summaryrefslogtreecommitdiffstats
path: root/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c
diff options
context:
space:
mode:
authordelphij <delphij@FreeBSD.org>2014-09-25 21:28:19 +0000
committerdelphij <delphij@FreeBSD.org>2014-09-25 21:28:19 +0000
commit085d517a22c1dbea65c98e89da7876d7fefb0ded (patch)
treec1a95b8aa425da4d38384c90118d780e602353aa /sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c
parent93af829dad4816366c39e80c6f9f2a648215cd96 (diff)
downloadFreeBSD-src-085d517a22c1dbea65c98e89da7876d7fefb0ded.zip
FreeBSD-src-085d517a22c1dbea65c98e89da7876d7fefb0ded.tar.gz
MFC r271536: MFV r271518:
Correctly report hole at end of file. When asked to find a hole, the DMU sees that there are no holes in the object, and returns ESRCH. The ZPL interprets this as "no holes before the end of the file", and therefore inserts the "virtual hole" at the end of the file. Because DMU and ZPL have different ideas of where the end of an object/file is, we will end up returning the end of file, which is generally larger, instead of returning the end of object. The fix is to handle the "virtual hole" in the DMU. If no hole is found, the DMU will return a hole at the end of the file, rather than an error. Illumos issue: 5139 SEEK_HOLE failed to report a hole at end of file Approved by: re (gjb)
Diffstat (limited to 'sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c')
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c
index 55bf895..0b19e76 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c
@@ -1948,6 +1948,15 @@ dnode_next_offset(dnode_t *dn, int flags, uint64_t *offset,
flags, offset, lvl, blkfill, txg);
}
+ /*
+ * There's always a "virtual hole" at the end of the object, even
+ * if all BP's which physically exist are non-holes.
+ */
+ if ((flags & DNODE_FIND_HOLE) && error == ESRCH && txg == 0 &&
+ minlvl == 1 && blkfill == 1 && !(flags & DNODE_FIND_BACKWARDS)) {
+ error = 0;
+ }
+
if (error == 0 && (flags & DNODE_FIND_BACKWARDS ?
initial_offset < *offset : initial_offset > *offset))
error = SET_ERROR(ESRCH);
OpenPOWER on IntegriCloud