aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Ahrens <[email protected]>2013-07-01 09:24:43 -0700
committerBrian Behlendorf <[email protected]>2013-07-02 09:24:18 -0700
commitcf91b2b6b2baaca1e56f23c985e3261cd98bd3f0 (patch)
tree96cb43a75ad5252357a54acba48dfd0f158b0939
parent0a6bef26ec80ee4db5f5340bbc007a45311e0415 (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.c45
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