mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-25 18:59:33 +03:00
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 <adam.leventhal@delphix.com> Reviewed by: Alex Reece <alex.reece@delphix.com> Reviewed by: Christopher Siden <christopher.siden@delphix.com> Reviewed by: George Wilson <george.wilson@delphix.com> Reviewed by: Max Grossman <max.grossman@delphix.com> Reviewed by: Peng Dai <peng.dai@delphix.com> Reviewed by: Richard Elling <richard.elling@gmail.com> Approved by: Dan McDonald <danmcd@omniti.com> References: https://www.illumos.org/issues/5139 https://github.com/illumos/illumos-gate/commit/0fbc0cd Ported by: Turbo Fredriksson <turbo@bayour.com> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #2714
This commit is contained in:
parent
843b4aad50
commit
d97aa48f7c
@ -1902,6 +1902,15 @@ dnode_next_offset(dnode_t *dn, int flags, uint64_t *offset,
|
|||||||
flags, offset, lvl, blkfill, txg);
|
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 ?
|
if (error == 0 && (flags & DNODE_FIND_BACKWARDS ?
|
||||||
initial_offset < *offset : initial_offset > *offset))
|
initial_offset < *offset : initial_offset > *offset))
|
||||||
error = SET_ERROR(ESRCH);
|
error = SET_ERROR(ESRCH);
|
||||||
|
@ -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);
|
error = dmu_offset_next(ZTOZSB(zp)->z_os, zp->z_id, hole, &noff);
|
||||||
|
|
||||||
/* end of file? */
|
if (error == ESRCH)
|
||||||
if ((error == ESRCH) || (noff > file_sz)) {
|
|
||||||
/*
|
|
||||||
* Handle the virtual hole at the end of file.
|
|
||||||
*/
|
|
||||||
if (hole) {
|
|
||||||
*off = file_sz;
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
return (SET_ERROR(ENXIO));
|
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)
|
if (noff < *off)
|
||||||
|
Loading…
Reference in New Issue
Block a user