On 2/11/20 4:52 AM, Richard W.M. Jones wrote:
On Mon, Feb 10, 2020 at 03:43:58PM -0600, Eric Blake wrote:
> @@ -214,6 +217,52 @@ file_open (int readonly)
> h->can_fallocate = true;
> h->can_zeroout = h->is_block_device;
>
> + h->can_extents = false;
> + h->init_sparse = false;
> + h->init_zero = false;
> +#ifdef SEEK_HOLE
> + else if (r == statbuf.st_size) {
> + nbdkit_debug ("extents enabled, image currently all data");
> + }
> + else {
> + nbdkit_debug ("extents enabled, image includes data before
hole");
> + h->init_sparse = true;
> + }
> + }
> + }
> + }
In the non-block case, can't we stat(2) the file and look at statbuf.st_blocks?
True. In fact, we already did do fstat(), so the information is already
there.
Note that st_blocks == 0 proves a file is sparse. But POSIX says
st_block is not necessarily using the same units as st_blksize, so
checking st_block * st_blksize < st_size is NOT necessarily evidence
that a file is sparse. What's worse, there are some file systems where
first- and second-level indirect blocks are used for large files, and
where those indirects are counted towards st_block (but NOT towards
st_size), so it is possible to have a sparse file where st_block *
st_blksize > st_size but the file is still sparse. In short, proving
that a file has holes is easy with lseek(SEEK_HOLE), but only a
best-guess heuristic with stat() data. That said, you're right that it
is at least worth adding the heuristics in the !SEEK_HOLE case.
> +requires nbdsh -c 'exit (not hasattr (h, "get_init_flags"))'
Not wrong, but it's easier to do it like this:
https://github.com/libguestfs/nbdkit/blob/5e4745641bb4676f607fdb3f8750dbf...
Thanks, that is cleaner. I will update it (along with the updates
required by renaming it to two "is_init_*" functions) (affects several
patches in this series).
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3226
Virtualization:
qemu.org |
libvirt.org