summaryrefslogtreecommitdiffstats
path: root/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2015-10-03 11:21:50 +0000
committermav <mav@FreeBSD.org>2015-10-03 11:21:50 +0000
commitb237c6cdd85588040bf87bd3f14becf76ba63d78 (patch)
tree0b461427b45aea26d66f6fab9537af061d356cc4 /sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c
parentf2f72b8384bc06040b3de4dad8a54d4d8ac3c510 (diff)
downloadFreeBSD-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/dmu.c')
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c51
1 files changed, 38 insertions, 13 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c
index 840bd7c..2b61311 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c
@@ -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 object, boolean_t hole, uint64_t *off)
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)
{
OpenPOWER on IntegriCloud