]> git.proxmox.com Git - mirror_zfs-debian.git/blobdiff - module/zfs/zfs_fuid.c
Imported Upstream version 0.6.2+git20140204
[mirror_zfs-debian.git] / module / zfs / zfs_fuid.c
index e704b1ca9d01c70956bcf1985699126c46690e78..6ca61b87242f02d5524f95d80793886969408f22 100644 (file)
  * CDDL HEADER END
  */
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #include <sys/zfs_context.h>
-#include <sys/sunddi.h>
 #include <sys/dmu.h>
 #include <sys/avl.h>
 #include <sys/zap.h>
@@ -48,7 +46,7 @@
  * two AVL trees are created.  One tree is keyed by the index number
  * and the other by the domain string.  Nodes are never removed from
  * trees, but new entries may be added.  If a new entry is added then
- * the zfsvfs->z_fuid_dirty flag is set to true and the caller will then
+ * the zsb->z_fuid_dirty flag is set to true and the caller will then
  * be responsible for calling zfs_fuid_sync() to sync the changes to disk.
  *
  */
@@ -170,12 +168,12 @@ zfs_fuid_table_destroy(avl_tree_t *idx_tree, avl_tree_t *domain_tree)
        void *cookie;
 
        cookie = NULL;
-       while (domnode = avl_destroy_nodes(domain_tree, &cookie))
+       while ((domnode = avl_destroy_nodes(domain_tree, &cookie)))
                ksiddomain_rele(domnode->f_ksid);
 
        avl_destroy(domain_tree);
        cookie = NULL;
-       while (domnode = avl_destroy_nodes(idx_tree, &cookie))
+       while ((domnode = avl_destroy_nodes(idx_tree, &cookie)))
                kmem_free(domnode, sizeof (fuid_domain_t));
        avl_destroy(idx_tree);
 }
@@ -198,34 +196,34 @@ zfs_fuid_idx_domain(avl_tree_t *idx_tree, uint32_t idx)
  * Load the fuid table(s) into memory.
  */
 static void
-zfs_fuid_init(zfsvfs_t *zfsvfs)
+zfs_fuid_init(zfs_sb_t *zsb)
 {
-       rw_enter(&zfsvfs->z_fuid_lock, RW_WRITER);
+       rw_enter(&zsb->z_fuid_lock, RW_WRITER);
 
-       if (zfsvfs->z_fuid_loaded) {
-               rw_exit(&zfsvfs->z_fuid_lock);
+       if (zsb->z_fuid_loaded) {
+               rw_exit(&zsb->z_fuid_lock);
                return;
        }
 
-       zfs_fuid_avl_tree_create(&zfsvfs->z_fuid_idx, &zfsvfs->z_fuid_domain);
+       zfs_fuid_avl_tree_create(&zsb->z_fuid_idx, &zsb->z_fuid_domain);
 
-       (void) zap_lookup(zfsvfs->z_os, MASTER_NODE_OBJ,
-           ZFS_FUID_TABLES, 8, 1, &zfsvfs->z_fuid_obj);
-       if (zfsvfs->z_fuid_obj != 0) {
-               zfsvfs->z_fuid_size = zfs_fuid_table_load(zfsvfs->z_os,
-                   zfsvfs->z_fuid_obj, &zfsvfs->z_fuid_idx,
-                   &zfsvfs->z_fuid_domain);
+       (void) zap_lookup(zsb->z_os, MASTER_NODE_OBJ,
+           ZFS_FUID_TABLES, 8, 1, &zsb->z_fuid_obj);
+       if (zsb->z_fuid_obj != 0) {
+               zsb->z_fuid_size = zfs_fuid_table_load(zsb->z_os,
+                   zsb->z_fuid_obj, &zsb->z_fuid_idx,
+                   &zsb->z_fuid_domain);
        }
 
-       zfsvfs->z_fuid_loaded = B_TRUE;
-       rw_exit(&zfsvfs->z_fuid_lock);
+       zsb->z_fuid_loaded = B_TRUE;
+       rw_exit(&zsb->z_fuid_lock);
 }
 
 /*
  * sync out AVL trees to persistent storage.
  */
 void
-zfs_fuid_sync(zfsvfs_t *zfsvfs, dmu_tx_t *tx)
+zfs_fuid_sync(zfs_sb_t *zsb, dmu_tx_t *tx)
 {
        nvlist_t *nvp;
        nvlist_t **fuids;
@@ -236,30 +234,30 @@ zfs_fuid_sync(zfsvfs_t *zfsvfs, dmu_tx_t *tx)
        int numnodes;
        int i;
 
-       if (!zfsvfs->z_fuid_dirty) {
+       if (!zsb->z_fuid_dirty) {
                return;
        }
 
-       rw_enter(&zfsvfs->z_fuid_lock, RW_WRITER);
+       rw_enter(&zsb->z_fuid_lock, RW_WRITER);
 
        /*
         * First see if table needs to be created?
         */
-       if (zfsvfs->z_fuid_obj == 0) {
-               zfsvfs->z_fuid_obj = dmu_object_alloc(zfsvfs->z_os,
+       if (zsb->z_fuid_obj == 0) {
+               zsb->z_fuid_obj = dmu_object_alloc(zsb->z_os,
                    DMU_OT_FUID, 1 << 14, DMU_OT_FUID_SIZE,
                    sizeof (uint64_t), tx);
-               VERIFY(zap_add(zfsvfs->z_os, MASTER_NODE_OBJ,
+               VERIFY(zap_add(zsb->z_os, MASTER_NODE_OBJ,
                    ZFS_FUID_TABLES, sizeof (uint64_t), 1,
-                   &zfsvfs->z_fuid_obj, tx) == 0);
+                   &zsb->z_fuid_obj, tx) == 0);
        }
 
        VERIFY(nvlist_alloc(&nvp, NV_UNIQUE_NAME, KM_SLEEP) == 0);
 
-       numnodes = avl_numnodes(&zfsvfs->z_fuid_idx);
+       numnodes = avl_numnodes(&zsb->z_fuid_idx);
        fuids = kmem_alloc(numnodes * sizeof (void *), KM_SLEEP);
-       for (i = 0, domnode = avl_first(&zfsvfs->z_fuid_domain); domnode; i++,
-           domnode = AVL_NEXT(&zfsvfs->z_fuid_domain, domnode)) {
+       for (i = 0, domnode = avl_first(&zsb->z_fuid_domain); domnode; i++,
+           domnode = AVL_NEXT(&zsb->z_fuid_domain, domnode)) {
                VERIFY(nvlist_alloc(&fuids[i], NV_UNIQUE_NAME, KM_SLEEP) == 0);
                VERIFY(nvlist_add_uint64(fuids[i], FUID_IDX,
                    domnode->f_idx) == 0);
@@ -277,30 +275,29 @@ zfs_fuid_sync(zfsvfs_t *zfsvfs, dmu_tx_t *tx)
        VERIFY(nvlist_pack(nvp, &packed, &nvsize,
            NV_ENCODE_XDR, KM_SLEEP) == 0);
        nvlist_free(nvp);
-       zfsvfs->z_fuid_size = nvsize;
-       dmu_write(zfsvfs->z_os, zfsvfs->z_fuid_obj, 0,
-           zfsvfs->z_fuid_size, packed, tx);
-       kmem_free(packed, zfsvfs->z_fuid_size);
-       VERIFY(0 == dmu_bonus_hold(zfsvfs->z_os, zfsvfs->z_fuid_obj,
+       zsb->z_fuid_size = nvsize;
+       dmu_write(zsb->z_os, zsb->z_fuid_obj, 0, zsb->z_fuid_size, packed, tx);
+       kmem_free(packed, zsb->z_fuid_size);
+       VERIFY(0 == dmu_bonus_hold(zsb->z_os, zsb->z_fuid_obj,
            FTAG, &db));
        dmu_buf_will_dirty(db, tx);
-       *(uint64_t *)db->db_data = zfsvfs->z_fuid_size;
+       *(uint64_t *)db->db_data = zsb->z_fuid_size;
        dmu_buf_rele(db, FTAG);
 
-       zfsvfs->z_fuid_dirty = B_FALSE;
-       rw_exit(&zfsvfs->z_fuid_lock);
+       zsb->z_fuid_dirty = B_FALSE;
+       rw_exit(&zsb->z_fuid_lock);
 }
 
 /*
  * Query domain table for a given domain.
  *
  * If domain isn't found and addok is set, it is added to AVL trees and
- * the zfsvfs->z_fuid_dirty flag will be set to TRUE.  It will then be
+ * the zsb->z_fuid_dirty flag will be set to TRUE.  It will then be
  * necessary for the caller or another thread to detect the dirty table
  * and sync out the changes.
  */
 int
-zfs_fuid_find_by_domain(zfsvfs_t *zfsvfs, const char *domain,
+zfs_fuid_find_by_domain(zfs_sb_t *zsb, const char *domain,
     char **retdomain, boolean_t addok)
 {
        fuid_domain_t searchnode, *findnode;
@@ -321,23 +318,23 @@ zfs_fuid_find_by_domain(zfsvfs_t *zfsvfs, const char *domain,
        searchnode.f_ksid = ksid_lookupdomain(domain);
        if (retdomain)
                *retdomain = searchnode.f_ksid->kd_name;
-       if (!zfsvfs->z_fuid_loaded)
-               zfs_fuid_init(zfsvfs);
+       if (!zsb->z_fuid_loaded)
+               zfs_fuid_init(zsb);
 
 retry:
-       rw_enter(&zfsvfs->z_fuid_lock, rw);
-       findnode = avl_find(&zfsvfs->z_fuid_domain, &searchnode, &loc);
+       rw_enter(&zsb->z_fuid_lock, rw);
+       findnode = avl_find(&zsb->z_fuid_domain, &searchnode, &loc);
 
        if (findnode) {
-               rw_exit(&zfsvfs->z_fuid_lock);
+               rw_exit(&zsb->z_fuid_lock);
                ksiddomain_rele(searchnode.f_ksid);
                return (findnode->f_idx);
        } else if (addok) {
                fuid_domain_t *domnode;
                uint64_t retidx;
 
-               if (rw == RW_READER && !rw_tryupgrade(&zfsvfs->z_fuid_lock)) {
-                       rw_exit(&zfsvfs->z_fuid_lock);
+               if (rw == RW_READER && !rw_tryupgrade(&zsb->z_fuid_lock)) {
+                       rw_exit(&zsb->z_fuid_lock);
                        rw = RW_WRITER;
                        goto retry;
                }
@@ -345,15 +342,15 @@ retry:
                domnode = kmem_alloc(sizeof (fuid_domain_t), KM_SLEEP);
                domnode->f_ksid = searchnode.f_ksid;
 
-               retidx = domnode->f_idx = avl_numnodes(&zfsvfs->z_fuid_idx) + 1;
+               retidx = domnode->f_idx = avl_numnodes(&zsb->z_fuid_idx) + 1;
 
-               avl_add(&zfsvfs->z_fuid_domain, domnode);
-               avl_add(&zfsvfs->z_fuid_idx, domnode);
-               zfsvfs->z_fuid_dirty = B_TRUE;
-               rw_exit(&zfsvfs->z_fuid_lock);
+               avl_add(&zsb->z_fuid_domain, domnode);
+               avl_add(&zsb->z_fuid_idx, domnode);
+               zsb->z_fuid_dirty = B_TRUE;
+               rw_exit(&zsb->z_fuid_lock);
                return (retidx);
        } else {
-               rw_exit(&zfsvfs->z_fuid_lock);
+               rw_exit(&zsb->z_fuid_lock);
                return (-1);
        }
 }
@@ -365,23 +362,23 @@ retry:
  *
  */
 const char *
-zfs_fuid_find_by_idx(zfsvfs_t *zfsvfs, uint32_t idx)
+zfs_fuid_find_by_idx(zfs_sb_t *zsb, uint32_t idx)
 {
        char *domain;
 
-       if (idx == 0 || !zfsvfs->z_use_fuids)
+       if (idx == 0 || !zsb->z_use_fuids)
                return (NULL);
 
-       if (!zfsvfs->z_fuid_loaded)
-               zfs_fuid_init(zfsvfs);
+       if (!zsb->z_fuid_loaded)
+               zfs_fuid_init(zsb);
 
-       rw_enter(&zfsvfs->z_fuid_lock, RW_READER);
+       rw_enter(&zsb->z_fuid_lock, RW_READER);
 
-       if (zfsvfs->z_fuid_obj)
-               domain = zfs_fuid_idx_domain(&zfsvfs->z_fuid_idx, idx);
+       if (zsb->z_fuid_obj || zsb->z_fuid_dirty)
+               domain = zfs_fuid_idx_domain(&zsb->z_fuid_idx, idx);
        else
                domain = nulldomain;
-       rw_exit(&zfsvfs->z_fuid_lock);
+       rw_exit(&zsb->z_fuid_lock);
 
        ASSERT(domain);
        return (domain);
@@ -390,16 +387,15 @@ zfs_fuid_find_by_idx(zfsvfs_t *zfsvfs, uint32_t idx)
 void
 zfs_fuid_map_ids(znode_t *zp, cred_t *cr, uid_t *uidp, uid_t *gidp)
 {
-       *uidp = zfs_fuid_map_id(zp->z_zfsvfs, zp->z_phys->zp_uid,
-           cr, ZFS_OWNER);
-       *gidp = zfs_fuid_map_id(zp->z_zfsvfs, zp->z_phys->zp_gid,
-           cr, ZFS_GROUP);
+       *uidp = zfs_fuid_map_id(ZTOZSB(zp), zp->z_uid, cr, ZFS_OWNER);
+       *gidp = zfs_fuid_map_id(ZTOZSB(zp), zp->z_gid, cr, ZFS_GROUP);
 }
 
 uid_t
-zfs_fuid_map_id(zfsvfs_t *zfsvfs, uint64_t fuid,
+zfs_fuid_map_id(zfs_sb_t *zsb, uint64_t fuid,
     cred_t *cr, zfs_fuid_type_t type)
 {
+#ifdef HAVE_KSID
        uint32_t index = FUID_INDEX(fuid);
        const char *domain;
        uid_t id;
@@ -407,7 +403,7 @@ zfs_fuid_map_id(zfsvfs_t *zfsvfs, uint64_t fuid,
        if (index == 0)
                return (fuid);
 
-       domain = zfs_fuid_find_by_idx(zfsvfs, index);
+       domain = zfs_fuid_find_by_idx(zsb, index);
        ASSERT(domain != NULL);
 
        if (type == ZFS_OWNER || type == ZFS_ACE_USER) {
@@ -418,6 +414,12 @@ zfs_fuid_map_id(zfsvfs_t *zfsvfs, uint64_t fuid,
                    FUID_RID(fuid), &id);
        }
        return (id);
+#else
+       /*
+        * The Linux port only supports POSIX IDs, use the passed id.
+        */
+       return (fuid);
+#endif /* HAVE_KSID */
 }
 
 /*
@@ -427,7 +429,7 @@ zfs_fuid_map_id(zfsvfs_t *zfsvfs, uint64_t fuid,
  * If ACL has multiple domains, then keep only one copy of each unique
  * domain.
  */
-static void
+void
 zfs_fuid_node_add(zfs_fuid_info_t **fuidpp, const char *domain, uint32_t rid,
     uint64_t idx, uint64_t id, zfs_fuid_type_t type)
 {
@@ -486,44 +488,60 @@ zfs_fuid_node_add(zfs_fuid_info_t **fuidpp, const char *domain, uint32_t rid,
        }
 }
 
+#ifdef HAVE_KSID
 /*
  * Create a file system FUID, based on information in the users cred
+ *
+ * If cred contains KSID_OWNER then it should be used to determine
+ * the uid otherwise cred's uid will be used. By default cred's gid
+ * is used unless it's an ephemeral ID in which case KSID_GROUP will
+ * be used if it exists.
  */
 uint64_t
-zfs_fuid_create_cred(zfsvfs_t *zfsvfs, zfs_fuid_type_t type,
+zfs_fuid_create_cred(zfs_sb_t *zsb, zfs_fuid_type_t type,
     cred_t *cr, zfs_fuid_info_t **fuidp)
 {
        uint64_t        idx;
        ksid_t          *ksid;
        uint32_t        rid;
-       char            *kdomain;
+       char            *kdomain;
        const char      *domain;
        uid_t           id;
 
        VERIFY(type == ZFS_OWNER || type == ZFS_GROUP);
 
        ksid = crgetsid(cr, (type == ZFS_OWNER) ? KSID_OWNER : KSID_GROUP);
-       if (ksid) {
-               id = ksid_getid(ksid);
-       } else {
-               if (type == ZFS_OWNER)
-                       id = crgetuid(cr);
-               else
-                       id = crgetgid(cr);
+
+       if (!zsb->z_use_fuids || (ksid == NULL)) {
+               id = (type == ZFS_OWNER) ? crgetuid(cr) : crgetgid(cr);
+
+               if (IS_EPHEMERAL(id))
+                       return ((type == ZFS_OWNER) ? UID_NOBODY : GID_NOBODY);
+
+               return ((uint64_t)id);
        }
 
-       if (!zfsvfs->z_use_fuids || (!IS_EPHEMERAL(id)))
+       /*
+        * ksid is present and FUID is supported
+        */
+       id = (type == ZFS_OWNER) ? ksid_getid(ksid) : crgetgid(cr);
+
+       if (!IS_EPHEMERAL(id))
                return ((uint64_t)id);
 
+       if (type == ZFS_GROUP)
+               id = ksid_getid(ksid);
+
        rid = ksid_getrid(ksid);
        domain = ksid_getdomain(ksid);
 
-       idx = zfs_fuid_find_by_domain(zfsvfs, domain, &kdomain, B_TRUE);
+       idx = zfs_fuid_find_by_domain(zsb, domain, &kdomain, B_TRUE);
 
        zfs_fuid_node_add(fuidp, kdomain, rid, idx, id, type);
 
        return (FUID_ENCODE(idx, rid));
 }
+#endif /* HAVE_KSID */
 
 /*
  * Create a file system FUID for an ACL ace
@@ -535,20 +553,21 @@ zfs_fuid_create_cred(zfsvfs_t *zfsvfs, zfs_fuid_type_t type,
  *
  * During replay operations the domain+rid information is
  * found in the zfs_fuid_info_t that the replay code has
- * attached to the zfsvfs of the file system.
+ * attached to the zsb of the file system.
  */
 uint64_t
-zfs_fuid_create(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr,
+zfs_fuid_create(zfs_sb_t *zsb, uint64_t id, cred_t *cr,
     zfs_fuid_type_t type, zfs_fuid_info_t **fuidpp)
 {
+#ifdef HAVE_KSID
        const char *domain;
        char *kdomain;
        uint32_t fuid_idx = FUID_INDEX(id);
        uint32_t rid;
        idmap_stat status;
-       uint64_t idx;
+       uint64_t idx = 0;
        zfs_fuid_t *zfuid = NULL;
-       zfs_fuid_info_t *fuidp;
+       zfs_fuid_info_t *fuidp = NULL;
 
        /*
         * If POSIX ID, or entry is already a FUID then
@@ -558,11 +577,11 @@ zfs_fuid_create(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr,
         * chmod.
         */
 
-       if (!zfsvfs->z_use_fuids || !IS_EPHEMERAL(id) || fuid_idx != 0)
+       if (!zsb->z_use_fuids || !IS_EPHEMERAL(id) || fuid_idx != 0)
                return (id);
 
-       if (zfsvfs->z_replay) {
-               fuidp = zfsvfs->z_fuid_replay;
+       if (zsb->z_replay) {
+               fuidp = zsb->z_fuid_replay;
 
                /*
                 * If we are passed an ephemeral id, but no
@@ -573,6 +592,9 @@ zfs_fuid_create(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr,
                if (fuidp == NULL)
                        return (UID_NOBODY);
 
+               VERIFY3U(type, >=, ZFS_OWNER);
+               VERIFY3U(type, <=, ZFS_ACE_GROUP);
+
                switch (type) {
                case ZFS_ACE_USER:
                case ZFS_ACE_GROUP:
@@ -589,7 +611,7 @@ zfs_fuid_create(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr,
                        idx = FUID_INDEX(fuidp->z_fuid_group);
                        break;
                };
-               domain = fuidp->z_domain_table[idx -1];
+               domain = fuidp->z_domain_table[idx - 1];
        } else {
                if (type == ZFS_OWNER || type == ZFS_ACE_USER)
                        status = kidmap_getsidbyuid(crgetzone(cr), id,
@@ -609,9 +631,9 @@ zfs_fuid_create(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr,
                }
        }
 
-       idx = zfs_fuid_find_by_domain(zfsvfs, domain, &kdomain, B_TRUE);
+       idx = zfs_fuid_find_by_domain(zsb, domain, &kdomain, B_TRUE);
 
-       if (!zfsvfs->z_replay)
+       if (!zsb->z_replay)
                zfs_fuid_node_add(fuidpp, kdomain,
                    rid, idx, id, type);
        else if (zfuid != NULL) {
@@ -619,18 +641,24 @@ zfs_fuid_create(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr,
                kmem_free(zfuid, sizeof (zfs_fuid_t));
        }
        return (FUID_ENCODE(idx, rid));
+#else
+       /*
+        * The Linux port only supports POSIX IDs, use the passed id.
+        */
+       return (id);
+#endif
 }
 
 void
-zfs_fuid_destroy(zfsvfs_t *zfsvfs)
+zfs_fuid_destroy(zfs_sb_t *zsb)
 {
-       rw_enter(&zfsvfs->z_fuid_lock, RW_WRITER);
-       if (!zfsvfs->z_fuid_loaded) {
-               rw_exit(&zfsvfs->z_fuid_lock);
+       rw_enter(&zsb->z_fuid_lock, RW_WRITER);
+       if (!zsb->z_fuid_loaded) {
+               rw_exit(&zsb->z_fuid_lock);
                return;
        }
-       zfs_fuid_table_destroy(&zfsvfs->z_fuid_idx, &zfsvfs->z_fuid_domain);
-       rw_exit(&zfsvfs->z_fuid_lock);
+       zfs_fuid_table_destroy(&zsb->z_fuid_idx, &zsb->z_fuid_domain);
+       rw_exit(&zsb->z_fuid_lock);
 }
 
 /*
@@ -684,14 +712,15 @@ zfs_fuid_info_free(zfs_fuid_info_t *fuidp)
  * Will use a straight FUID compare when possible.
  */
 boolean_t
-zfs_groupmember(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr)
+zfs_groupmember(zfs_sb_t *zsb, uint64_t id, cred_t *cr)
 {
+#ifdef HAVE_KSID
        ksid_t          *ksid = crgetsid(cr, KSID_GROUP);
        ksidlist_t      *ksidlist = crgetsidlist(cr);
        uid_t           gid;
 
        if (ksid && ksidlist) {
-               int             i;
+               int             i;
                ksid_t          *ksid_groups;
                uint32_t        idx = FUID_INDEX(id);
                uint32_t        rid = FUID_RID(id);
@@ -707,7 +736,7 @@ zfs_groupmember(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr)
                        } else {
                                const char *domain;
 
-                               domain = zfs_fuid_find_by_idx(zfsvfs, idx);
+                               domain = zfs_fuid_find_by_idx(zsb, idx);
                                ASSERT(domain != NULL);
 
                                if (strcmp(domain,
@@ -725,22 +754,25 @@ zfs_groupmember(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr)
        /*
         * Not found in ksidlist, check posix groups
         */
-       gid = zfs_fuid_map_id(zfsvfs, id, cr, ZFS_GROUP);
+       gid = zfs_fuid_map_id(zsb, id, cr, ZFS_GROUP);
        return (groupmember(gid, cr));
+#else
+       return (B_TRUE);
+#endif
 }
 
 void
-zfs_fuid_txhold(zfsvfs_t *zfsvfs, dmu_tx_t *tx)
+zfs_fuid_txhold(zfs_sb_t *zsb, dmu_tx_t *tx)
 {
-       if (zfsvfs->z_fuid_obj == 0) {
+       if (zsb->z_fuid_obj == 0) {
                dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT);
                dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0,
-                   FUID_SIZE_ESTIMATE(zfsvfs));
+                   FUID_SIZE_ESTIMATE(zsb));
                dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, FALSE, NULL);
        } else {
-               dmu_tx_hold_bonus(tx, zfsvfs->z_fuid_obj);
-               dmu_tx_hold_write(tx, zfsvfs->z_fuid_obj, 0,
-                   FUID_SIZE_ESTIMATE(zfsvfs));
+               dmu_tx_hold_bonus(tx, zsb->z_fuid_obj);
+               dmu_tx_hold_write(tx, zsb->z_fuid_obj, 0,
+                   FUID_SIZE_ESTIMATE(zsb));
        }
 }
 #endif