diff options
author | mav <mav@FreeBSD.org> | 2015-10-03 11:21:50 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2015-10-03 11:21:50 +0000 |
commit | b237c6cdd85588040bf87bd3f14becf76ba63d78 (patch) | |
tree | 0b461427b45aea26d66f6fab9537af061d356cc4 /sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c | |
parent | f2f72b8384bc06040b3de4dad8a54d4d8ac3c510 (diff) | |
download | FreeBSD-src-b237c6cdd85588040bf87bd3f14becf76ba63d78.zip FreeBSD-src-b237c6cdd85588040bf87bd3f14becf76ba63d78.tar.gz |
MFC r287103 (by avg): 5692 expose the number of hole blocks in a file
FreeBSD porting notes:
- only kernel-side changes are merged
- the new ioctl is not actually implemented yet
- thus, the goal is to synchronize DMU code
illumos/illumos-gate@2bcf0248e992f292c7b814458bcdce2f004925d6
https://www.illumos.org/issues/5692
we would like to expose the number of hole (sparse) blocks in a file.
this can be useful to for example if you want to fill in the holes with
some data; knowing the number of holes in advances allows you to report
progress on hole filling. We could use SEEK_HOLE to do that but it would
be O(n) where n is the number of holes present in the file.
Author: Max Grossman <max.grossman@delphix.com>
Reviewed by: Adam Leventhal <ahl@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: Boris Protopopov <bprotopopov@hotmail.com>
Approved by: Richard Lowe <richlowe@richlowe.net>
Diffstat (limited to 'sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c')
-rw-r--r-- | sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c | 51 |
1 files changed, 50 insertions, 1 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c index 00fcb7a..3a4f348 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c @@ -293,25 +293,32 @@ zfs_ioctl(vnode_t *vp, u_long com, intptr_t data, int flag, cred_t *cred, int *rvalp, caller_context_t *ct) { offset_t off; + offset_t ndata; + dmu_object_info_t doi; int error; zfsvfs_t *zfsvfs; znode_t *zp; switch (com) { case _FIOFFS: + { return (0); /* * The following two ioctls are used by bfu. Faking out, * necessary to avoid bfu errors. */ + } case _FIOGDIO: case _FIOSDIO: + { return (0); + } case _FIO_SEEK_DATA: case _FIO_SEEK_HOLE: -#ifdef sun + { +#ifdef illumos if (ddi_copyin((void *)data, &off, sizeof (off), flag)) return (SET_ERROR(EFAULT)); #else @@ -335,6 +342,48 @@ zfs_ioctl(vnode_t *vp, u_long com, intptr_t data, int flag, cred_t *cred, #endif return (0); } +#ifdef illumos + case _FIO_COUNT_FILLED: + { + /* + * _FIO_COUNT_FILLED adds a new ioctl command which + * exposes the number of filled blocks in a + * ZFS object. + */ + zp = VTOZ(vp); + zfsvfs = zp->z_zfsvfs; + ZFS_ENTER(zfsvfs); + ZFS_VERIFY_ZP(zp); + + /* + * Wait for all dirty blocks for this object + * to get synced out to disk, and the DMU info + * updated. + */ + error = dmu_object_wait_synced(zfsvfs->z_os, zp->z_id); + if (error) { + ZFS_EXIT(zfsvfs); + return (error); + } + + /* + * Retrieve fill count from DMU object. + */ + error = dmu_object_info(zfsvfs->z_os, zp->z_id, &doi); + if (error) { + ZFS_EXIT(zfsvfs); + return (error); + } + + ndata = doi.doi_fill_count; + + ZFS_EXIT(zfsvfs); + if (ddi_copyout(&ndata, (void *)data, sizeof (ndata), flag)) + return (SET_ERROR(EFAULT)); + return (0); + } +#endif + } return (SET_ERROR(ENOTTY)); } |