summaryrefslogtreecommitdiffstats
path: root/module/zfs/zfs_vnops.c
diff options
context:
space:
mode:
authorMatthew Ahrens <[email protected]>2014-09-17 17:25:10 +0200
committerBrian Behlendorf <[email protected]>2014-09-23 10:38:45 -0700
commitd97aa48f7c53e851675ad5d250daecee1bac81c1 (patch)
tree81472793ebbb63c12c5bc26d18a4699216742a5d /module/zfs/zfs_vnops.c
parent843b4aad504b791eb1e8dfe6772a55d4da090b65 (diff)
Illumos 5139 - SEEK_HOLE failed to report a hole at end of file
5139 SEEK_HOLE failed to report a hole at end of file Reviewed by: Adam Leventhal <[email protected]> Reviewed by: Alex Reece <[email protected]> Reviewed by: Christopher Siden <[email protected]> Reviewed by: George Wilson <[email protected]> Reviewed by: Max Grossman <[email protected]> Reviewed by: Peng Dai <[email protected]> Reviewed by: Richard Elling <[email protected]> Approved by: Dan McDonald <[email protected]> References: https://www.illumos.org/issues/5139 https://github.com/illumos/illumos-gate/commit/0fbc0cd Ported by: Turbo Fredriksson <[email protected]> Signed-off-by: Brian Behlendorf <[email protected]> Closes #2714
Diffstat (limited to 'module/zfs/zfs_vnops.c')
-rw-r--r--module/zfs/zfs_vnops.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/module/zfs/zfs_vnops.c b/module/zfs/zfs_vnops.c
index ddd997fae..33f9e0ec9 100644
--- a/module/zfs/zfs_vnops.c
+++ b/module/zfs/zfs_vnops.c
@@ -274,16 +274,19 @@ zfs_holey_common(struct inode *ip, int cmd, loff_t *off)
error = dmu_offset_next(ZTOZSB(zp)->z_os, zp->z_id, hole, &noff);
- /* end of file? */
- if ((error == ESRCH) || (noff > file_sz)) {
- /*
- * Handle the virtual hole at the end of file.
- */
- if (hole) {
- *off = file_sz;
- return (0);
- }
+ if (error == ESRCH)
return (SET_ERROR(ENXIO));
+
+ /*
+ * We could find a hole that begins after the logical end-of-file,
+ * because dmu_offset_next() only works on whole blocks. If the
+ * EOF falls mid-block, then indicate that the "virtual hole"
+ * at the end of the file begins at the logical EOF, rather than
+ * at the end of the last block.
+ */
+ if (noff > file_sz) {
+ ASSERT(hole);
+ noff = file_sz;
}
if (noff < *off)