Subject: bug#9157: [PATCH] dd: sparse conv flag

From: Pádraig Brady <[email-masked]>
Date: Tue, 28 Feb 2012 11:02:31 +0000

On 02/28/2012 08:50 AM, Paul Eggert wrote:
> On 02/27/2012 05:09 PM, Pádraig Brady wrote:
>> how
>> to handle existing regular files with conv=trunc.
>> I.E. seeking over existing possible non NUL data.
>> It's too dangerous/inconsistent to do this for files I think.
> 
> Why?  This is *dd* we're talking about here.
> It's *supposed* to be used for tricky stuff like this.
> 
> If one interprets conv=sparse to mean "write sparsely",
> rather than "create a sparse file that exactly mimics
> the input's sparseness", then everything should be clear,
> no?

Well I wasn't considering reproducing sparseness.
I was thinking it would be more beneficial to be able to
update a file in place, but do so sparsely if possible.
I.E. support something like:

truncate -r src.img backup.img &&
dd if=src.img conv=notrunc,sparse of=backup.img

To do that, one could not simply skip over the output
for NUL input. Doing that would be "dangerous" as I said above,
or in other words, surprising to users to not update
possibly non NUL data in the output file.

As for the "inconsistent" point I mentioned. The last patch
currently just seeks the output for NUL input,
_except_ for the last byte of the file if part of a NUL write.
So that inconsistency means one couldn't use NUL input as
a write mask so to speak, if one ever did want such an
esoteric feature. I guess we could address the consistency aspect
by using ftruncate() rather than the write(outfd, "\0", 1) technique
(only doing that if we've extended the file).
However I'm not sure such functionality is useful for files,
and that we should try to align with the first operation?
Note ftruncate() might be good to do anyway to avoid
writes completely to a fully sparse file.

Also I'm just thought about oflag=append.
That will cause writes to ignore the seek beyond end of file.
I.E. with the last patch, this will create a file.test with just "ab"

  printf "a\000\000b" |
  src/dd conv=sparse bs=1 count=10 oflag=append > file.test

I guess an ftruncate() would cater for that too, except in the case
where another process is writing to the file, in which case
you would might want to disallow the conv=sparse oflag=append combo.
We can't really ftruncate as we go as that would be racy,
so I guess we should disallow the combo?

cheers,
Pádraig.