diff options
author | Matthew Ahrens <[email protected]> | 2013-07-01 09:24:43 -0700 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2013-07-02 09:24:18 -0700 |
commit | cf91b2b6b2baaca1e56f23c985e3261cd98bd3f0 (patch) | |
tree | 96cb43a75ad5252357a54acba48dfd0f158b0939 | |
parent | 0a6bef26ec80ee4db5f5340bbc007a45311e0415 (diff) |
Readd zfs_holey() from OpenSolaris
This patch restores the zfs_holey() function from OpenSolaris.
This was removed by commit 3558fd7 because it wasn't clear we
had a use for it in ZoL. However, this functionality is a
prerequisite for adding SEEK_DATA/SEEK_HOLE support to the ZPL.
Signed-off-by: Brian Behlendorf <[email protected]>
Signed-off-by: Richard Yao <[email protected]>
Issue #1384
-rw-r--r-- | module/zfs/zfs_vnops.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/module/zfs/zfs_vnops.c b/module/zfs/zfs_vnops.c index 3b671b4ac..5a9c96334 100644 --- a/module/zfs/zfs_vnops.c +++ b/module/zfs/zfs_vnops.c @@ -240,6 +240,51 @@ zfs_close(struct inode *ip, int flag, cred_t *cr) } EXPORT_SYMBOL(zfs_close); +#if 0 +/* + * Lseek support for finding holes (cmd == _FIO_SEEK_HOLE) and + * data (cmd == _FIO_SEEK_DATA). "off" is an in/out parameter. + */ +static int +zfs_holey(vnode_t *vp, int cmd, offset_t *off) +{ + znode_t *zp = VTOZ(vp); + uint64_t noff = (uint64_t)*off; /* new offset */ + uint64_t file_sz; + int error; + boolean_t hole; + + file_sz = zp->z_size; + if (noff >= file_sz) { + return (SET_ERROR(ENXIO)); + } + + if (cmd == _FIO_SEEK_HOLE) + hole = B_TRUE; + else + hole = B_FALSE; + + error = dmu_offset_next(zp->z_zfsvfs->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); + } + return (SET_ERROR(ENXIO)); + } + + if (noff < *off) + return (error); + *off = noff; + return (error); +} +#endif + #if defined(_KERNEL) /* * When a file is memory mapped, we must keep the IO data synchronized |