diff options
Diffstat (limited to 'module/zfs/zfs_vnops.c')
-rw-r--r-- | module/zfs/zfs_vnops.c | 21 |
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) |