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 + if (!h->is_block_device) { + off_t r; + + /* A simple test to see whether SEEK_DATA/SEEK_HOLE are likely to work on + * the current filesystem, and to see if the image is sparse or zero. + */ + ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&lseek_lock); + r = lseek (h->fd, 0, SEEK_DATA); + if (r == -1) { + if (errno == ENXIO) { + nbdkit_debug ("extents enabled, entire image is hole"); + h->can_extents = true; + h->init_sparse = true; + h->init_zero = true; + } else { + nbdkit_debug ("extents disabled: lseek(SEEK_DATA): %m"); + } + } + else { + h->can_extents = true; + if (r > 0) { + nbdkit_debug ("extents enabled, image includes hole before data"); + h->init_sparse = true; + } + else { + r = lseek (h->fd, 0, SEEK_HOLE); + if (r == -1) { + nbdkit_debug ("extents disabled: lseek(SEEK_HOLE): %m"); + h->can_extents = false; + } + 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?
+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/5e4745641bb4676f607fdb3f8750dbf6e9... Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-p2v converts physical machines to virtual machines. Boot with a live CD or over the network (PXE) and turn machines into KVM guests. http://libguestfs.org/virt-v2v