svn commit: r288590 - in stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs: . sys
Alexander Motin
mav at FreeBSD.org
Sat Oct 3 11:21:52 UTC 2015
Author: mav
Date: Sat Oct 3 11:21:50 2015
New Revision: 288590
URL: https://svnweb.freebsd.org/changeset/base/288590
Log:
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 at 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 at delphix.com>
Reviewed by: Adam Leventhal <ahl at delphix.com>
Reviewed by: Matthew Ahrens <mahrens at delphix.com>
Reviewed by: Boris Protopopov <bprotopopov at hotmail.com>
Approved by: Richard Lowe <richlowe at richlowe.net>
Modified:
stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c
stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h
stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
Directory Properties:
stable/10/ (props changed)
Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c
==============================================================================
--- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c Sat Oct 3 11:19:32 2015 (r288589)
+++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c Sat Oct 3 11:21:50 2015 (r288590)
@@ -1902,25 +1902,20 @@ int
dmu_offset_next(objset_t *os, uint64_t object, boolean_t hole, uint64_t *off)
{
dnode_t *dn;
- int i, err;
+ int err;
- err = dnode_hold(os, object, FTAG, &dn);
- if (err)
- return (err);
/*
* Sync any current changes before
* we go trundling through the block pointers.
*/
- for (i = 0; i < TXG_SIZE; i++) {
- if (list_link_active(&dn->dn_dirty_link[i]))
- break;
+ err = dmu_object_wait_synced(os, object);
+ if (err) {
+ return (err);
}
- if (i != TXG_SIZE) {
- dnode_rele(dn, FTAG);
- txg_wait_synced(dmu_objset_pool(os), 0);
- err = dnode_hold(os, object, FTAG, &dn);
- if (err)
- return (err);
+
+ err = dnode_hold(os, object, FTAG, &dn);
+ if (err) {
+ return (err);
}
err = dnode_next_offset(dn, (hole ? DNODE_FIND_HOLE : 0), off, 1, 1, 0);
@@ -1929,6 +1924,36 @@ dmu_offset_next(objset_t *os, uint64_t o
return (err);
}
+/*
+ * Given the ZFS object, if it contains any dirty nodes
+ * this function flushes all dirty blocks to disk. This
+ * ensures the DMU object info is updated. A more efficient
+ * future version might just find the TXG with the maximum
+ * ID and wait for that to be synced.
+ */
+int
+dmu_object_wait_synced(objset_t *os, uint64_t object) {
+ dnode_t *dn;
+ int error, i;
+
+ error = dnode_hold(os, object, FTAG, &dn);
+ if (error) {
+ return (error);
+ }
+
+ for (i = 0; i < TXG_SIZE; i++) {
+ if (list_link_active(&dn->dn_dirty_link[i])) {
+ break;
+ }
+ }
+ dnode_rele(dn, FTAG);
+ if (i != TXG_SIZE) {
+ txg_wait_synced(dmu_objset_pool(os), 0);
+ }
+
+ return (0);
+}
+
void
dmu_object_info_from_dnode(dnode_t *dn, dmu_object_info_t *doi)
{
Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h
==============================================================================
--- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h Sat Oct 3 11:19:32 2015 (r288589)
+++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h Sat Oct 3 11:21:50 2015 (r288590)
@@ -915,6 +915,15 @@ int dmu_offset_next(objset_t *os, uint64
uint64_t *off);
/*
+ * Check if a DMU object has any dirty blocks. If so, sync out
+ * all pending transaction groups. Otherwise, this function
+ * does not alter DMU state. This could be improved to only sync
+ * out the necessary transaction groups for this particular
+ * object.
+ */
+int dmu_object_wait_synced(objset_t *os, uint64_t object);
+
+/*
* Initial setup and final teardown.
*/
extern void dmu_init(void);
Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
==============================================================================
--- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c Sat Oct 3 11:19:32 2015 (r288589)
+++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c Sat Oct 3 11:21:50 2015 (r288590)
@@ -293,25 +293,32 @@ zfs_ioctl(vnode_t *vp, u_long com, intpt
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, intpt
#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));
}
More information about the svn-src-stable-10
mailing list