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/5e4745641bb4676f607fdb3f8750dbf...
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