]> git.proxmox.com Git - mirror_zfs.git/blobdiff - module/zfs/zap_micro.c
OpenZFS 7004 - dmu_tx_hold_zap() does dnode_hold() 7x on same object
[mirror_zfs.git] / module / zfs / zap_micro.c
index de646287ece7a1f72fde5d78023edd10e57302f9..bc0a5e71d2bfa81309e2b21b6538fa23a0fb572e 100644 (file)
@@ -536,6 +536,24 @@ zap_lockdir_impl(dmu_buf_t *db, void *tag, dmu_tx_t *tx,
        return (0);
 }
 
+static int
+zap_lockdir_by_dnode(dnode_t *dn, dmu_tx_t *tx,
+    krw_t lti, boolean_t fatreader, boolean_t adding, void *tag, zap_t **zapp)
+{
+       dmu_buf_t *db;
+       int err;
+
+       err = dmu_buf_hold_by_dnode(dn, 0, tag, &db, DMU_READ_NO_PREFETCH);
+       if (err != 0) {
+               return (err);
+       }
+       err = zap_lockdir_impl(db, tag, tx, lti, fatreader, adding, zapp);
+       if (err != 0) {
+               dmu_buf_rele(db, tag);
+       }
+       return (err);
+}
+
 int
 zap_lockdir(objset_t *os, uint64_t obj, dmu_tx_t *tx,
     krw_t lti, boolean_t fatreader, boolean_t adding, void *tag, zap_t **zapp)
@@ -927,6 +945,33 @@ zap_prefetch(objset_t *os, uint64_t zapobj, const char *name)
        return (err);
 }
 
+int
+zap_lookup_by_dnode(dnode_t *dn, const char *name,
+    uint64_t integer_size, uint64_t num_integers, void *buf)
+{
+       return (zap_lookup_norm_by_dnode(dn, name, integer_size,
+           num_integers, buf, MT_EXACT, NULL, 0, NULL));
+}
+
+int
+zap_lookup_norm_by_dnode(dnode_t *dn, const char *name,
+    uint64_t integer_size, uint64_t num_integers, void *buf,
+    matchtype_t mt, char *realname, int rn_len,
+    boolean_t *ncp)
+{
+       zap_t *zap;
+       int err;
+
+       err = zap_lockdir_by_dnode(dn, NULL, RW_READER, TRUE, FALSE,
+           FTAG, &zap);
+       if (err != 0)
+               return (err);
+       err = zap_lookup_impl(zap, name, integer_size,
+           num_integers, buf, mt, realname, rn_len, ncp);
+       zap_unlockdir(zap, FTAG);
+       return (err);
+}
+
 int
 zap_prefetch_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
     int key_numints)
@@ -1460,7 +1505,7 @@ zap_get_stats(objset_t *os, uint64_t zapobj, zap_stats_t *zs)
 }
 
 int
-zap_count_write(objset_t *os, uint64_t zapobj, const char *name, int add,
+zap_count_write_by_dnode(dnode_t *dn, const char *name, int add,
     uint64_t *towrite, uint64_t *tooverwrite)
 {
        zap_t *zap;
@@ -1488,7 +1533,7 @@ zap_count_write(objset_t *os, uint64_t zapobj, const char *name, int add,
         * At present we are just evaluating the possibility of this operation
         * and hence we do not want to trigger an upgrade.
         */
-       err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE,
+       err = zap_lockdir_by_dnode(dn, NULL, RW_READER, TRUE, FALSE,
            FTAG, &zap);
        if (err != 0)
                return (err);
@@ -1552,7 +1597,7 @@ EXPORT_SYMBOL(zap_lookup_uint64);
 EXPORT_SYMBOL(zap_contains);
 EXPORT_SYMBOL(zap_prefetch);
 EXPORT_SYMBOL(zap_prefetch_uint64);
-EXPORT_SYMBOL(zap_count_write);
+EXPORT_SYMBOL(zap_count_write_by_dnode);
 EXPORT_SYMBOL(zap_add);
 EXPORT_SYMBOL(zap_add_uint64);
 EXPORT_SYMBOL(zap_update);