]> granicus.if.org Git - zfs/commitdiff
OpenZFS 7003 - zap_lockdir() should tag hold
authorMatthew Ahrens <mahrens@delphix.com>
Wed, 20 Jul 2016 22:39:55 +0000 (15:39 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Fri, 19 Aug 2016 19:35:23 +0000 (12:35 -0700)
zap_lockdir() / zap_unlockdir() should take a "void *tag" argument which
tags the hold on the zap. This will help diagnose programming errors
which misuse the hold on the ZAP.

Sponsored by: Intel Corp.

Signed-off-by: Matthew Ahrens <mahrens@delphix.com>
Signed-off-by: Pavel Zakharov <pavel.zakha@gmail.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
OpenZFS-issue: https://www.illumos.org/issues/7003
OpenZFS-commit: https://github.com/openzfs/openzfs/pull/108
Closes #4972

include/sys/dmu.h
include/sys/zap_impl.h
module/zfs/dbuf.c
module/zfs/zap.c
module/zfs/zap_micro.c

index 87a8a40eb782182303e961ddbcfedab6d40cc642..98da928902263a438f23947e6e027e66eb7c3fd2 100644 (file)
@@ -619,6 +619,8 @@ void *dmu_buf_remove_user(dmu_buf_t *db, dmu_buf_user_t *user);
  */
 void *dmu_buf_get_user(dmu_buf_t *db);
 
+objset_t *dmu_buf_get_objset(dmu_buf_t *db);
+
 /* Block until any in-progress dmu buf user evictions complete. */
 void dmu_buf_user_evict_wait(void);
 
index bfd43e31da80043dfb93c0d23dc3da4117f22339..7b6d1b553b8052f67f1c1f1d3b991d152b334ee6 100644 (file)
@@ -21,6 +21,7 @@
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
+ * Copyright (c) 2013, 2016 by Delphix. All rights reserved.
  */
 
 #ifndef        _SYS_ZAP_IMPL_H
@@ -195,8 +196,8 @@ typedef struct zap_name {
 
 boolean_t zap_match(zap_name_t *zn, const char *matchname);
 int zap_lockdir(objset_t *os, uint64_t obj, dmu_tx_t *tx,
-    krw_t lti, boolean_t fatreader, boolean_t adding, zap_t **zapp);
-void zap_unlockdir(zap_t *zap);
+    krw_t lti, boolean_t fatreader, boolean_t adding, void *tag, zap_t **zapp);
+void zap_unlockdir(zap_t *zap, void *tag);
 void zap_evict(void *dbu);
 zap_name_t *zap_name_alloc(zap_t *zap, const char *key, matchtype_t mt);
 void zap_name_free(zap_name_t *zn);
@@ -215,9 +216,10 @@ void fzap_prefetch(zap_name_t *zn);
 int fzap_count_write(zap_name_t *zn, int add, uint64_t *towrite,
     uint64_t *tooverwrite);
 int fzap_add(zap_name_t *zn, uint64_t integer_size, uint64_t num_integers,
-    const void *val, dmu_tx_t *tx);
+    const void *val, void *tag, dmu_tx_t *tx);
 int fzap_update(zap_name_t *zn,
-    int integer_size, uint64_t num_integers, const void *val, dmu_tx_t *tx);
+    int integer_size, uint64_t num_integers, const void *val,
+    void *tag, dmu_tx_t *tx);
 int fzap_length(zap_name_t *zn,
     uint64_t *integer_size, uint64_t *num_integers);
 int fzap_remove(zap_name_t *zn, dmu_tx_t *tx);
@@ -227,7 +229,7 @@ void zap_put_leaf(struct zap_leaf *l);
 
 int fzap_add_cd(zap_name_t *zn,
     uint64_t integer_size, uint64_t num_integers,
-    const void *val, uint32_t cd, dmu_tx_t *tx);
+    const void *val, uint32_t cd, void *tag, dmu_tx_t *tx);
 void fzap_upgrade(zap_t *zap, dmu_tx_t *tx, zap_flags_t flags);
 
 #ifdef __cplusplus
index 266f31250eebbb0c114ea4f80fb8d4e7fbdc93ac..d89d030d34dfd845a1383e69d2ea997cd4217c61 100644 (file)
@@ -2836,6 +2836,13 @@ dmu_buf_get_blkptr(dmu_buf_t *db)
        return (dbi->db_blkptr);
 }
 
+objset_t *
+dmu_buf_get_objset(dmu_buf_t *db)
+{
+       dmu_buf_impl_t *dbi = (dmu_buf_impl_t *)db;
+       return (dbi->db_objset);
+}
+
 static void
 dbuf_check_blkptr(dnode_t *dn, dmu_buf_impl_t *db)
 {
index 9e4f05049b2105c3161cf360417b8eca6973e699..d0d438fe39e47f699777f9cfc0d6474f9a49c0b9 100644 (file)
@@ -20,7 +20,7 @@
  */
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2015 by Delphix. All rights reserved.
+ * Copyright (c) 2012, 2016 by Delphix. All rights reserved.
  * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
  */
 
@@ -605,7 +605,8 @@ zap_deref_leaf(zap_t *zap, uint64_t h, dmu_tx_t *tx, krw_t lt, zap_leaf_t **lp)
 }
 
 static int
-zap_expand_leaf(zap_name_t *zn, zap_leaf_t *l, dmu_tx_t *tx, zap_leaf_t **lp)
+zap_expand_leaf(zap_name_t *zn, zap_leaf_t *l,
+    void *tag, dmu_tx_t *tx, zap_leaf_t **lp)
 {
        zap_t *zap = zn->zn_zap;
        uint64_t hash = zn->zn_hash;
@@ -627,9 +628,9 @@ zap_expand_leaf(zap_name_t *zn, zap_leaf_t *l, dmu_tx_t *tx, zap_leaf_t **lp)
                uint64_t object = zap->zap_object;
 
                zap_put_leaf(l);
-               zap_unlockdir(zap);
+               zap_unlockdir(zap, tag);
                err = zap_lockdir(os, object, tx, RW_WRITER,
-                   FALSE, FALSE, &zn->zn_zap);
+                   FALSE, FALSE, tag, &zn->zn_zap);
                zap = zn->zn_zap;
                if (err)
                        return (err);
@@ -692,7 +693,8 @@ zap_expand_leaf(zap_name_t *zn, zap_leaf_t *l, dmu_tx_t *tx, zap_leaf_t **lp)
 }
 
 static void
-zap_put_leaf_maybe_grow_ptrtbl(zap_name_t *zn, zap_leaf_t *l, dmu_tx_t *tx)
+zap_put_leaf_maybe_grow_ptrtbl(zap_name_t *zn, zap_leaf_t *l,
+    void *tag, dmu_tx_t *tx)
 {
        zap_t *zap = zn->zn_zap;
        int shift = zap_f_phys(zap)->zap_ptrtbl.zt_shift;
@@ -712,9 +714,9 @@ zap_put_leaf_maybe_grow_ptrtbl(zap_name_t *zn, zap_leaf_t *l, dmu_tx_t *tx)
                        objset_t *os = zap->zap_objset;
                        uint64_t zapobj = zap->zap_object;
 
-                       zap_unlockdir(zap);
+                       zap_unlockdir(zap, tag);
                        err = zap_lockdir(os, zapobj, tx,
-                           RW_WRITER, FALSE, FALSE, &zn->zn_zap);
+                           RW_WRITER, FALSE, FALSE, tag, &zn->zn_zap);
                        zap = zn->zn_zap;
                        if (err)
                                return;
@@ -804,7 +806,7 @@ fzap_lookup(zap_name_t *zn,
 int
 fzap_add_cd(zap_name_t *zn,
     uint64_t integer_size, uint64_t num_integers,
-    const void *val, uint32_t cd, dmu_tx_t *tx)
+    const void *val, uint32_t cd, void *tag, dmu_tx_t *tx)
 {
        zap_leaf_t *l;
        int err;
@@ -833,7 +835,7 @@ retry:
        if (err == 0) {
                zap_increment_num_entries(zap, 1, tx);
        } else if (err == EAGAIN) {
-               err = zap_expand_leaf(zn, l, tx, &l);
+               err = zap_expand_leaf(zn, l, tag, tx, &l);
                zap = zn->zn_zap;       /* zap_expand_leaf() may change zap */
                if (err == 0)
                        goto retry;
@@ -841,26 +843,27 @@ retry:
 
 out:
        if (zap != NULL)
-               zap_put_leaf_maybe_grow_ptrtbl(zn, l, tx);
+               zap_put_leaf_maybe_grow_ptrtbl(zn, l, tag, tx);
        return (err);
 }
 
 int
 fzap_add(zap_name_t *zn,
     uint64_t integer_size, uint64_t num_integers,
-    const void *val, dmu_tx_t *tx)
+    const void *val, void *tag, dmu_tx_t *tx)
 {
        int err = fzap_check(zn, integer_size, num_integers);
        if (err != 0)
                return (err);
 
        return (fzap_add_cd(zn, integer_size, num_integers,
-           val, ZAP_NEED_CD, tx));
+           val, ZAP_NEED_CD, tag, tx));
 }
 
 int
 fzap_update(zap_name_t *zn,
-    int integer_size, uint64_t num_integers, const void *val, dmu_tx_t *tx)
+    int integer_size, uint64_t num_integers, const void *val,
+    void *tag, dmu_tx_t *tx)
 {
        zap_leaf_t *l;
        int err, create;
@@ -890,14 +893,14 @@ retry:
        }
 
        if (err == EAGAIN) {
-               err = zap_expand_leaf(zn, l, tx, &l);
+               err = zap_expand_leaf(zn, l, tag, tx, &l);
                zap = zn->zn_zap;       /* zap_expand_leaf() may change zap */
                if (err == 0)
                        goto retry;
        }
 
        if (zap != NULL)
-               zap_put_leaf_maybe_grow_ptrtbl(zn, l, tx);
+               zap_put_leaf_maybe_grow_ptrtbl(zn, l, tag, tx);
        return (err);
 }
 
index f3153cc18133db742c65c3111d45253a5875461d..de646287ece7a1f72fde5d78023edd10e57302f9 100644 (file)
@@ -20,7 +20,7 @@
  */
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2016 by Delphix. All rights reserved.
  * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
  */
 
@@ -42,7 +42,8 @@
 
 extern inline mzap_phys_t *zap_m_phys(zap_t *zap);
 
-static int mzap_upgrade(zap_t **zapp, dmu_tx_t *tx, zap_flags_t flags);
+static int mzap_upgrade(zap_t **zapp,
+    void *tag, dmu_tx_t *tx, zap_flags_t flags);
 
 uint64_t
 zap_getflags(zap_t *zap)
@@ -456,21 +457,19 @@ handle_winner:
        return (winner);
 }
 
-int
-zap_lockdir(objset_t *os, uint64_t obj, dmu_tx_t *tx,
+static int
+zap_lockdir_impl(dmu_buf_t *db, void *tag, dmu_tx_t *tx,
     krw_t lti, boolean_t fatreader, boolean_t adding, zap_t **zapp)
 {
        dmu_object_info_t doi;
        zap_t *zap;
-       dmu_buf_t *db;
        krw_t lt;
-       int err;
 
-       *zapp = NULL;
+       objset_t *os = dmu_buf_get_objset(db);
+       uint64_t obj = db->db_object;
 
-       err = dmu_buf_hold(os, obj, 0, NULL, &db, DMU_READ_NO_PREFETCH);
-       if (err)
-               return (err);
+       ASSERT0(db->db_offset);
+       *zapp = NULL;
 
        dmu_object_info_from_db(db, &doi);
        if (DMU_OT_BYTESWAP(doi.doi_type) != DMU_BSWAP_ZAP)
@@ -484,7 +483,6 @@ zap_lockdir(objset_t *os, uint64_t obj, dmu_tx_t *tx,
                         * mzap_open() didn't like what it saw on-disk.
                         * Check for corruption!
                         */
-                       dmu_buf_rele(db, NULL);
                        return (SET_ERROR(EIO));
                }
        }
@@ -520,13 +518,16 @@ zap_lockdir(objset_t *os, uint64_t obj, dmu_tx_t *tx,
            zap->zap_m.zap_num_entries == zap->zap_m.zap_num_chunks) {
                uint64_t newsz = db->db_size + SPA_MINBLOCKSIZE;
                if (newsz > MZAP_MAX_BLKSZ) {
+                       int err;
                        dprintf("upgrading obj %llu: num_entries=%u\n",
                            obj, zap->zap_m.zap_num_entries);
                        *zapp = zap;
-                       return (mzap_upgrade(zapp, tx, 0));
+                       err = mzap_upgrade(zapp, tag, tx, 0);
+                       if (err != 0)
+                               rw_exit(&zap->zap_rwlock);
+                       return (err);
                }
-               err = dmu_object_set_blocksize(os, obj, newsz, 0, tx);
-               ASSERT0(err);
+               VERIFY0(dmu_object_set_blocksize(os, obj, newsz, 0, tx));
                zap->zap_m.zap_num_chunks =
                    db->db_size / MZAP_ENT_LEN - 1;
        }
@@ -535,15 +536,31 @@ zap_lockdir(objset_t *os, uint64_t obj, dmu_tx_t *tx,
        return (0);
 }
 
+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)
+{
+       dmu_buf_t *db;
+       int err;
+
+       err = dmu_buf_hold(os, obj, 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);
+}
+
 void
-zap_unlockdir(zap_t *zap)
+zap_unlockdir(zap_t *zap, void *tag)
 {
        rw_exit(&zap->zap_rwlock);
-       dmu_buf_rele(zap->zap_dbuf, NULL);
+       dmu_buf_rele(zap->zap_dbuf, tag);
 }
 
 static int
-mzap_upgrade(zap_t **zapp, dmu_tx_t *tx, zap_flags_t flags)
+mzap_upgrade(zap_t **zapp, void *tag, dmu_tx_t *tx, zap_flags_t flags)
 {
        mzap_phys_t *mzp;
        int i, sz, nchunks;
@@ -581,7 +598,8 @@ mzap_upgrade(zap_t **zapp, dmu_tx_t *tx, zap_flags_t flags)
                dprintf("adding %s=%llu\n",
                    mze->mze_name, mze->mze_value);
                zn = zap_name_alloc(zap, mze->mze_name, MT_EXACT);
-               err = fzap_add_cd(zn, 8, 1, &mze->mze_value, mze->mze_cd, tx);
+               err = fzap_add_cd(zn, 8, 1, &mze->mze_value, mze->mze_cd,
+                   tag, tx);
                zap = zn->zn_zap;       /* fzap_add_cd() may change zap */
                zap_name_free(zn);
                if (err)
@@ -620,9 +638,9 @@ mzap_create_impl(objset_t *os, uint64_t obj, int normflags, zap_flags_t flags,
                zap_t *zap;
                /* Only fat zap supports flags; upgrade immediately. */
                VERIFY(0 == zap_lockdir(os, obj, tx, RW_WRITER,
-                   B_FALSE, B_FALSE, &zap));
-               VERIFY3U(0, ==, mzap_upgrade(&zap, tx, flags));
-               zap_unlockdir(zap);
+                   B_FALSE, B_FALSE, FTAG, &zap));
+               VERIFY3U(0, ==, mzap_upgrade(&zap, FTAG, tx, flags));
+               zap_unlockdir(zap, FTAG);
        }
 }
 
@@ -762,7 +780,7 @@ zap_count(objset_t *os, uint64_t zapobj, uint64_t *count)
        zap_t *zap;
        int err;
 
-       err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap);
+       err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, FTAG, &zap);
        if (err)
                return (err);
        if (!zap->zap_ismicro) {
@@ -770,7 +788,7 @@ zap_count(objset_t *os, uint64_t zapobj, uint64_t *count)
        } else {
                *count = zap->zap_m.zap_num_entries;
        }
-       zap_unlockdir(zap);
+       zap_unlockdir(zap, FTAG);
        return (err);
 }
 
@@ -827,25 +845,19 @@ zap_lookup(objset_t *os, uint64_t zapobj, const char *name,
            num_integers, buf, MT_EXACT, NULL, 0, NULL));
 }
 
-int
-zap_lookup_norm(objset_t *os, uint64_t zapobj, const char *name,
+static int
+zap_lookup_impl(zap_t *zap, 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;
+       int err = 0;
        mzap_ent_t *mze;
        zap_name_t *zn;
 
-       err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap);
-       if (err)
-               return (err);
        zn = zap_name_alloc(zap, name, mt);
-       if (zn == NULL) {
-               zap_unlockdir(zap);
+       if (zn == NULL)
                return (SET_ERROR(ENOTSUP));
-       }
 
        if (!zap->zap_ismicro) {
                err = fzap_lookup(zn, integer_size, num_integers, buf,
@@ -872,7 +884,24 @@ zap_lookup_norm(objset_t *os, uint64_t zapobj, const char *name,
                }
        }
        zap_name_free(zn);
-       zap_unlockdir(zap);
+       return (err);
+}
+
+int
+zap_lookup_norm(objset_t *os, uint64_t zapobj, 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(os, zapobj, 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);
 }
 
@@ -883,18 +912,18 @@ zap_prefetch(objset_t *os, uint64_t zapobj, const char *name)
        int err;
        zap_name_t *zn;
 
-       err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap);
+       err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, FTAG, &zap);
        if (err)
                return (err);
        zn = zap_name_alloc(zap, name, MT_EXACT);
        if (zn == NULL) {
-               zap_unlockdir(zap);
+               zap_unlockdir(zap, FTAG);
                return (SET_ERROR(ENOTSUP));
        }
 
        fzap_prefetch(zn);
        zap_name_free(zn);
-       zap_unlockdir(zap);
+       zap_unlockdir(zap, FTAG);
        return (err);
 }
 
@@ -906,18 +935,18 @@ zap_prefetch_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
        int err;
        zap_name_t *zn;
 
-       err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap);
+       err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, FTAG, &zap);
        if (err)
                return (err);
        zn = zap_name_alloc_uint64(zap, key, key_numints);
        if (zn == NULL) {
-               zap_unlockdir(zap);
+               zap_unlockdir(zap, FTAG);
                return (SET_ERROR(ENOTSUP));
        }
 
        fzap_prefetch(zn);
        zap_name_free(zn);
-       zap_unlockdir(zap);
+       zap_unlockdir(zap, FTAG);
        return (err);
 }
 
@@ -929,19 +958,19 @@ zap_lookup_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
        int err;
        zap_name_t *zn;
 
-       err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap);
+       err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, FTAG, &zap);
        if (err)
                return (err);
        zn = zap_name_alloc_uint64(zap, key, key_numints);
        if (zn == NULL) {
-               zap_unlockdir(zap);
+               zap_unlockdir(zap, FTAG);
                return (SET_ERROR(ENOTSUP));
        }
 
        err = fzap_lookup(zn, integer_size, num_integers, buf,
            NULL, 0, NULL);
        zap_name_free(zn);
-       zap_unlockdir(zap);
+       zap_unlockdir(zap, FTAG);
        return (err);
 }
 
@@ -964,12 +993,12 @@ zap_length(objset_t *os, uint64_t zapobj, const char *name,
        mzap_ent_t *mze;
        zap_name_t *zn;
 
-       err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap);
+       err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, FTAG, &zap);
        if (err)
                return (err);
        zn = zap_name_alloc(zap, name, MT_EXACT);
        if (zn == NULL) {
-               zap_unlockdir(zap);
+               zap_unlockdir(zap, FTAG);
                return (SET_ERROR(ENOTSUP));
        }
        if (!zap->zap_ismicro) {
@@ -986,7 +1015,7 @@ zap_length(objset_t *os, uint64_t zapobj, const char *name,
                }
        }
        zap_name_free(zn);
-       zap_unlockdir(zap);
+       zap_unlockdir(zap, FTAG);
        return (err);
 }
 
@@ -998,17 +1027,17 @@ zap_length_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
        int err;
        zap_name_t *zn;
 
-       err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap);
+       err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, FTAG, &zap);
        if (err)
                return (err);
        zn = zap_name_alloc_uint64(zap, key, key_numints);
        if (zn == NULL) {
-               zap_unlockdir(zap);
+               zap_unlockdir(zap, FTAG);
                return (SET_ERROR(ENOTSUP));
        }
        err = fzap_length(zn, integer_size, num_integers);
        zap_name_free(zn);
-       zap_unlockdir(zap);
+       zap_unlockdir(zap, FTAG);
        return (err);
 }
 
@@ -1068,22 +1097,24 @@ zap_add(objset_t *os, uint64_t zapobj, const char *key,
        const uint64_t *intval = val;
        zap_name_t *zn;
 
-       err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, &zap);
+       err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, FTAG, &zap);
        if (err)
                return (err);
        zn = zap_name_alloc(zap, key, MT_EXACT);
        if (zn == NULL) {
-               zap_unlockdir(zap);
+               zap_unlockdir(zap, FTAG);
                return (SET_ERROR(ENOTSUP));
        }
        if (!zap->zap_ismicro) {
-               err = fzap_add(zn, integer_size, num_integers, val, tx);
+               err = fzap_add(zn, integer_size, num_integers, val, FTAG, tx);
                zap = zn->zn_zap;       /* fzap_add() may change zap */
        } else if (integer_size != 8 || num_integers != 1 ||
            strlen(key) >= MZAP_NAME_LEN) {
-               err = mzap_upgrade(&zn->zn_zap, tx, 0);
-               if (err == 0)
-                       err = fzap_add(zn, integer_size, num_integers, val, tx);
+               err = mzap_upgrade(&zn->zn_zap, FTAG, tx, 0);
+               if (err == 0) {
+                       err = fzap_add(zn, integer_size, num_integers, val,
+                           FTAG, tx);
+               }
                zap = zn->zn_zap;       /* fzap_add() may change zap */
        } else {
                mze = mze_find(zn);
@@ -1096,7 +1127,7 @@ zap_add(objset_t *os, uint64_t zapobj, const char *key,
        ASSERT(zap == zn->zn_zap);
        zap_name_free(zn);
        if (zap != NULL)        /* may be NULL if fzap_add() failed */
-               zap_unlockdir(zap);
+               zap_unlockdir(zap, FTAG);
        return (err);
 }
 
@@ -1109,19 +1140,19 @@ zap_add_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
        int err;
        zap_name_t *zn;
 
-       err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, &zap);
+       err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, FTAG, &zap);
        if (err)
                return (err);
        zn = zap_name_alloc_uint64(zap, key, key_numints);
        if (zn == NULL) {
-               zap_unlockdir(zap);
+               zap_unlockdir(zap, FTAG);
                return (SET_ERROR(ENOTSUP));
        }
-       err = fzap_add(zn, integer_size, num_integers, val, tx);
+       err = fzap_add(zn, integer_size, num_integers, val, FTAG, tx);
        zap = zn->zn_zap;       /* fzap_add() may change zap */
        zap_name_free(zn);
        if (zap != NULL)        /* may be NULL if fzap_add() failed */
-               zap_unlockdir(zap);
+               zap_unlockdir(zap, FTAG);
        return (err);
 }
 
@@ -1146,25 +1177,27 @@ zap_update(objset_t *os, uint64_t zapobj, const char *name,
                (void) zap_lookup(os, zapobj, name, 8, 1, &oldval);
 #endif
 
-       err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, &zap);
+       err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, FTAG, &zap);
        if (err)
                return (err);
        zn = zap_name_alloc(zap, name, MT_EXACT);
        if (zn == NULL) {
-               zap_unlockdir(zap);
+               zap_unlockdir(zap, FTAG);
                return (SET_ERROR(ENOTSUP));
        }
        if (!zap->zap_ismicro) {
-               err = fzap_update(zn, integer_size, num_integers, val, tx);
+               err = fzap_update(zn, integer_size, num_integers, val,
+                   FTAG, tx);
                zap = zn->zn_zap;       /* fzap_update() may change zap */
        } else if (integer_size != 8 || num_integers != 1 ||
            strlen(name) >= MZAP_NAME_LEN) {
                dprintf("upgrading obj %llu: intsz=%u numint=%llu name=%s\n",
                    zapobj, integer_size, num_integers, name);
-               err = mzap_upgrade(&zn->zn_zap, tx, 0);
-               if (err == 0)
+               err = mzap_upgrade(&zn->zn_zap, FTAG, tx, 0);
+               if (err == 0) {
                        err = fzap_update(zn, integer_size, num_integers,
-                           val, tx);
+                           val, FTAG, tx);
+               }
                zap = zn->zn_zap;       /* fzap_update() may change zap */
        } else {
                mze = mze_find(zn);
@@ -1178,7 +1211,7 @@ zap_update(objset_t *os, uint64_t zapobj, const char *name,
        ASSERT(zap == zn->zn_zap);
        zap_name_free(zn);
        if (zap != NULL)        /* may be NULL if fzap_upgrade() failed */
-               zap_unlockdir(zap);
+               zap_unlockdir(zap, FTAG);
        return (err);
 }
 
@@ -1191,19 +1224,19 @@ zap_update_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
        zap_name_t *zn;
        int err;
 
-       err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, &zap);
+       err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, FTAG, &zap);
        if (err)
                return (err);
        zn = zap_name_alloc_uint64(zap, key, key_numints);
        if (zn == NULL) {
-               zap_unlockdir(zap);
+               zap_unlockdir(zap, FTAG);
                return (SET_ERROR(ENOTSUP));
        }
-       err = fzap_update(zn, integer_size, num_integers, val, tx);
+       err = fzap_update(zn, integer_size, num_integers, val, FTAG, tx);
        zap = zn->zn_zap;       /* fzap_update() may change zap */
        zap_name_free(zn);
        if (zap != NULL)        /* may be NULL if fzap_upgrade() failed */
-               zap_unlockdir(zap);
+               zap_unlockdir(zap, FTAG);
        return (err);
 }
 
@@ -1222,12 +1255,12 @@ zap_remove_norm(objset_t *os, uint64_t zapobj, const char *name,
        mzap_ent_t *mze;
        zap_name_t *zn;
 
-       err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, FALSE, &zap);
+       err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, FALSE, FTAG, &zap);
        if (err)
                return (err);
        zn = zap_name_alloc(zap, name, mt);
        if (zn == NULL) {
-               zap_unlockdir(zap);
+               zap_unlockdir(zap, FTAG);
                return (SET_ERROR(ENOTSUP));
        }
        if (!zap->zap_ismicro) {
@@ -1244,7 +1277,7 @@ zap_remove_norm(objset_t *os, uint64_t zapobj, const char *name,
                }
        }
        zap_name_free(zn);
-       zap_unlockdir(zap);
+       zap_unlockdir(zap, FTAG);
        return (err);
 }
 
@@ -1256,17 +1289,17 @@ zap_remove_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
        int err;
        zap_name_t *zn;
 
-       err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, FALSE, &zap);
+       err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, FALSE, FTAG, &zap);
        if (err)
                return (err);
        zn = zap_name_alloc_uint64(zap, key, key_numints);
        if (zn == NULL) {
-               zap_unlockdir(zap);
+               zap_unlockdir(zap, FTAG);
                return (SET_ERROR(ENOTSUP));
        }
        err = fzap_remove(zn, tx);
        zap_name_free(zn);
-       zap_unlockdir(zap);
+       zap_unlockdir(zap, FTAG);
        return (err);
 }
 
@@ -1298,7 +1331,7 @@ zap_cursor_fini(zap_cursor_t *zc)
 {
        if (zc->zc_zap) {
                rw_enter(&zc->zc_zap->zap_rwlock, RW_READER);
-               zap_unlockdir(zc->zc_zap);
+               zap_unlockdir(zc->zc_zap, NULL);
                zc->zc_zap = NULL;
        }
        if (zc->zc_leaf) {
@@ -1345,7 +1378,7 @@ zap_cursor_retrieve(zap_cursor_t *zc, zap_attribute_t *za)
        if (zc->zc_zap == NULL) {
                int hb;
                err = zap_lockdir(zc->zc_objset, zc->zc_zapobj, NULL,
-                   RW_READER, TRUE, FALSE, &zc->zc_zap);
+                   RW_READER, TRUE, FALSE, NULL, &zc->zc_zap);
                if (err)
                        return (err);
 
@@ -1409,7 +1442,7 @@ zap_get_stats(objset_t *os, uint64_t zapobj, zap_stats_t *zs)
        int err;
        zap_t *zap;
 
-       err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap);
+       err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, FTAG, &zap);
        if (err)
                return (err);
 
@@ -1422,7 +1455,7 @@ zap_get_stats(objset_t *os, uint64_t zapobj, zap_stats_t *zs)
        } else {
                fzap_get_stats(zap, zs);
        }
-       zap_unlockdir(zap);
+       zap_unlockdir(zap, FTAG);
        return (0);
 }
 
@@ -1441,7 +1474,7 @@ zap_count_write(objset_t *os, uint64_t zapobj, const char *name, int add,
         *      - 2 blocks for possibly split leaves,
         *      - 2 grown ptrtbl blocks
         *
-        * This also accomodates the case where an add operation to a fairly
+        * This also accommodates the case where an add operation to a fairly
         * large microzap results in a promotion to fatzap.
         */
        if (name == NULL) {
@@ -1453,10 +1486,11 @@ zap_count_write(objset_t *os, uint64_t zapobj, const char *name, int add,
         * We lock the zap with adding == FALSE. Because, if we pass
         * the actual value of add, it could trigger a mzap_upgrade().
         * At present we are just evaluating the possibility of this operation
-        * and hence we donot want to trigger an upgrade.
+        * and hence we do not want to trigger an upgrade.
         */
-       err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap);
-       if (err)
+       err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE,
+           FTAG, &zap);
+       if (err != 0)
                return (err);
 
        if (!zap->zap_ismicro) {
@@ -1497,7 +1531,7 @@ zap_count_write(objset_t *os, uint64_t zapobj, const char *name, int add,
                }
        }
 
-       zap_unlockdir(zap);
+       zap_unlockdir(zap, FTAG);
        return (err);
 }