diff options
-rw-r--r-- | usr/src/uts/common/fs/zfs/sys/zfs_acl.h | 6 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/sys/zfs_fuid.h | 5 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/sys/zfs_vfsops.h | 3 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/zfs_acl.c | 51 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/zfs_dir.c | 18 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/zfs_fuid.c | 24 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/zfs_vnops.c | 116 |
7 files changed, 136 insertions, 87 deletions
diff --git a/usr/src/uts/common/fs/zfs/sys/zfs_acl.h b/usr/src/uts/common/fs/zfs/sys/zfs_acl.h index 1e6656612a..5d5ca56e95 100644 --- a/usr/src/uts/common/fs/zfs/sys/zfs_acl.h +++ b/usr/src/uts/common/fs/zfs/sys/zfs_acl.h @@ -165,6 +165,7 @@ typedef struct zfs_acl { zfs_acl_node_t *z_curr_node; /* current node iterator is handling */ list_t z_acl; /* chunks of ACE data */ acl_ops_t z_ops; /* ACL operations */ + boolean_t z_has_fuids; /* FUIDs present in ACL? */ } zfs_acl_t; #define ACL_DATA_ALLOCED 0x1 @@ -185,6 +186,7 @@ typedef struct zfs_acl { struct znode; struct zfsvfs; +struct zfs_fuid_info; #ifdef _KERNEL void zfs_perm_init(struct znode *, struct znode *, int, vattr_t *, @@ -198,12 +200,14 @@ extern int zfs_zaccess(struct znode *, int, int, boolean_t, cred_t *); extern int zfs_zaccess_rwx(struct znode *, mode_t, int, cred_t *); extern int zfs_zaccess_unix(struct znode *, mode_t, cred_t *); extern int zfs_acl_access(struct znode *, int, cred_t *); -int zfs_acl_chmod_setattr(struct znode *, uint64_t, dmu_tx_t *, cred_t *); +int zfs_acl_chmod_setattr(struct znode *, zfs_acl_t **, uint64_t); int zfs_zaccess_delete(struct znode *, struct znode *, cred_t *); int zfs_zaccess_rename(struct znode *, struct znode *, struct znode *, struct znode *, cred_t *cr); void zfs_acl_free(zfs_acl_t *); int zfs_vsec_2_aclp(struct zfsvfs *, vtype_t, vsecattr_t *, zfs_acl_t **); +int zfs_aclset_common(struct znode *, zfs_acl_t *, cred_t *, + struct zfs_fuid_info **, dmu_tx_t *); #endif diff --git a/usr/src/uts/common/fs/zfs/sys/zfs_fuid.h b/usr/src/uts/common/fs/zfs/sys/zfs_fuid.h index 56f1073607..ec8dea4e42 100644 --- a/usr/src/uts/common/fs/zfs/sys/zfs_fuid.h +++ b/usr/src/uts/common/fs/zfs/sys/zfs_fuid.h @@ -53,6 +53,11 @@ typedef enum { #endif +/* + * Estimate space needed for one more fuid table entry. + * for now assume its current size + 1K + */ +#define FUID_SIZE_ESTIMATE(z) (z->z_fuid_size + (SPA_MINBLOCKSIZE << 1)) #define FUID_INDEX(x) (x >> 32) #define FUID_RID(x) (x & 0xffffffff) diff --git a/usr/src/uts/common/fs/zfs/sys/zfs_vfsops.h b/usr/src/uts/common/fs/zfs/sys/zfs_vfsops.h index dc8e15fe77..502e4f218b 100644 --- a/usr/src/uts/common/fs/zfs/sys/zfs_vfsops.h +++ b/usr/src/uts/common/fs/zfs/sys/zfs_vfsops.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -51,6 +51,7 @@ struct zfsvfs { uint64_t z_max_blksz; /* maximum block size for files */ uint64_t z_assign; /* TXG_NOWAIT or set by zil_replay() */ uint64_t z_fuid_obj; /* fuid table object number */ + uint64_t z_fuid_size; /* fuid table size */ avl_tree_t z_fuid_idx; /* fuid tree keyed by index */ avl_tree_t z_fuid_domain; /* fuid tree keyed by domain */ krwlock_t z_fuid_lock; /* fuid lock */ diff --git a/usr/src/uts/common/fs/zfs/zfs_acl.c b/usr/src/uts/common/fs/zfs/zfs_acl.c index 482c53bd96..13d4d62ca9 100644 --- a/usr/src/uts/common/fs/zfs/zfs_acl.c +++ b/usr/src/uts/common/fs/zfs/zfs_acl.c @@ -543,8 +543,13 @@ zfs_copy_ace_2_fuid(vtype_t obj_type, zfs_acl_t *aclp, void *datap, aceptr->z_hdr.z_type = acep->a_type; entry_type = aceptr->z_hdr.z_flags & ACE_TYPE_FLAGS; if (entry_type != ACE_OWNER && entry_type != OWNING_GROUP && - entry_type != ACE_EVERYONE) + entry_type != ACE_EVERYONE) { + if (!aclp->z_has_fuids) + aclp->z_has_fuids = IS_EPHEMERAL(acep->a_who) ? + B_TRUE : B_FALSE; aceptr->z_fuid = (uint64_t)acep->a_who; + } + /* * Make sure ACE is valid */ @@ -1450,15 +1455,13 @@ zfs_fixup_group_entries(zfs_acl_t *aclp, void *acep, void *prevacep, * Apply the chmod algorithm as described * in PSARC/2002/240 */ -static int -zfs_acl_chmod(znode_t *zp, uint64_t mode, zfs_acl_t *aclp, - dmu_tx_t *tx, cred_t *cr) +static void +zfs_acl_chmod(znode_t *zp, uint64_t mode, zfs_acl_t *aclp) { zfsvfs_t *zfsvfs = zp->z_zfsvfs; void *acep = NULL, *prevacep = NULL; uint64_t who; int i; - int error; int entry_type; int reuse_deny; int need_canonical_six = 1; @@ -1592,25 +1595,21 @@ nextace: } zfs_acl_fixup_canonical_six(aclp, mode); - zp->z_phys->zp_mode = mode; - error = zfs_aclset_common(zp, aclp, cr, NULL, tx); - return (error); } int -zfs_acl_chmod_setattr(znode_t *zp, uint64_t mode, dmu_tx_t *tx, cred_t *cr) +zfs_acl_chmod_setattr(znode_t *zp, zfs_acl_t **aclp, uint64_t mode) { - zfs_acl_t *aclp = NULL; int error; - ASSERT(MUTEX_HELD(&zp->z_lock)); + mutex_enter(&zp->z_lock); mutex_enter(&zp->z_acl_lock); - error = zfs_acl_node_read(zp, &aclp, B_TRUE); + *aclp = NULL; + error = zfs_acl_node_read(zp, aclp, B_TRUE); if (error == 0) - error = zfs_acl_chmod(zp, mode, aclp, tx, cr); + zfs_acl_chmod(zp, mode, *aclp); mutex_exit(&zp->z_acl_lock); - if (aclp) - zfs_acl_free(aclp); + mutex_exit(&zp->z_lock); return (error); } @@ -1842,7 +1841,7 @@ zfs_perm_init(znode_t *zp, znode_t *parent, int flag, mutex_exit(&parent->z_lock); mutex_enter(&zp->z_lock); mutex_enter(&zp->z_acl_lock); - error = zfs_acl_chmod(zp, mode, aclp, tx, cr); + zfs_acl_chmod(zp, mode, aclp); } else { mutex_enter(&zp->z_lock); mutex_enter(&zp->z_acl_lock); @@ -2073,7 +2072,7 @@ top: zp->z_phys->zp_acl.z_acl_extern_obj, 0, DMU_OBJECT_END); dmu_tx_hold_write(tx, DMU_NEW_OBJECT, - 0, sizeof (zfs_object_ace_t) * 2048 + 6); + 0, aclp->z_acl_bytes); } else { dmu_tx_hold_write(tx, zp->z_phys->zp_acl.z_acl_extern_obj, @@ -2082,15 +2081,17 @@ top: } else if (aclp->z_acl_bytes > ZFS_ACE_SPACE) { dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, aclp->z_acl_bytes); } - if (zfsvfs->z_fuid_obj == 0) { - dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT); + if (aclp->z_has_fuids) { + if (zfsvfs->z_fuid_obj == 0) { + dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT); dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, - SPA_MAXBLOCKSIZE); - 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, - SPA_MAXBLOCKSIZE); + FUID_SIZE_ESTIMATE(zfsvfs)); + 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)); + } } error = dmu_tx_assign(tx, zfsvfs->z_assign); diff --git a/usr/src/uts/common/fs/zfs/zfs_dir.c b/usr/src/uts/common/fs/zfs/zfs_dir.c index 5488b25fd1..feae0826d3 100644 --- a/usr/src/uts/common/fs/zfs/zfs_dir.c +++ b/usr/src/uts/common/fs/zfs/zfs_dir.c @@ -817,13 +817,17 @@ zfs_make_xattrdir(znode_t *zp, vattr_t *vap, vnode_t **xvpp, cred_t *cr) tx = dmu_tx_create(zfsvfs->z_os); dmu_tx_hold_bonus(tx, zp->z_id); dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, FALSE, NULL); - if (zfsvfs->z_fuid_obj == 0) { - dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT); - dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, SPA_MAXBLOCKSIZE); - 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, SPA_MAXBLOCKSIZE); + if (IS_EPHEMERAL(crgetuid(cr)) || IS_EPHEMERAL(crgetgid(cr))) { + if (zfsvfs->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)); + 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)); + } } error = dmu_tx_assign(tx, zfsvfs->z_assign); if (error) { diff --git a/usr/src/uts/common/fs/zfs/zfs_fuid.c b/usr/src/uts/common/fs/zfs/zfs_fuid.c index 3ac3f8ee32..b763339908 100644 --- a/usr/src/uts/common/fs/zfs/zfs_fuid.c +++ b/usr/src/uts/common/fs/zfs/zfs_fuid.c @@ -111,7 +111,6 @@ zfs_fuid_init(zfsvfs_t *zfsvfs, dmu_tx_t *tx) { dmu_buf_t *db; char *packed; - size_t nvsize = 0; int error = 0; int i; @@ -146,21 +145,23 @@ zfs_fuid_init(zfsvfs_t *zfsvfs, dmu_tx_t *tx) if (zfsvfs->z_fuid_obj) { VERIFY(0 == dmu_bonus_hold(zfsvfs->z_os, zfsvfs->z_fuid_obj, FTAG, &db)); - nvsize = *(uint64_t *)db->db_data; + zfsvfs->z_fuid_size = *(uint64_t *)db->db_data; dmu_buf_rele(db, FTAG); } - if (nvsize == 0) + if (zfsvfs->z_fuid_size == 0) goto initialized; - packed = kmem_alloc(nvsize, KM_SLEEP); - error = dmu_read(zfsvfs->z_os, zfsvfs->z_fuid_obj, 0, nvsize, packed); + packed = kmem_alloc(zfsvfs->z_fuid_size, KM_SLEEP); + error = dmu_read(zfsvfs->z_os, zfsvfs->z_fuid_obj, 0, + zfsvfs->z_fuid_size, packed); if (error == 0) { nvlist_t **fuidnvp; nvlist_t *nvp = NULL; uint_t count; - VERIFY(nvlist_unpack(packed, nvsize, &nvp, 0) == 0); + VERIFY(nvlist_unpack(packed, zfsvfs->z_fuid_size, + &nvp, 0) == 0); VERIFY((error = nvlist_lookup_nvlist_array(nvp, FUID_NVP_ARRAY, &fuidnvp, &count)) == 0); @@ -197,7 +198,7 @@ zfs_fuid_init(zfsvfs_t *zfsvfs, dmu_tx_t *tx) } nvlist_free(nvp); } - kmem_free(packed, nvsize); + kmem_free(packed, zfsvfs->z_fuid_size); initialized: zfsvfs->z_fuid_loaded = B_TRUE; @@ -293,13 +294,14 @@ zfs_fuid_find_by_domain(zfsvfs_t *zfsvfs, const char *domain, char **retdomain, VERIFY(nvlist_pack(nvp, &packed, &nvsize, NV_ENCODE_XDR, KM_SLEEP) == 0); nvlist_free(nvp); - dmu_write(zfsvfs->z_os, zfsvfs->z_fuid_obj, 0, nvsize, - packed, tx); - kmem_free(packed, nvsize); + 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, FTAG, &db)); dmu_buf_will_dirty(db, tx); - *(uint64_t *)db->db_data = nvsize; + *(uint64_t *)db->db_data = zfsvfs->z_fuid_size; dmu_buf_rele(db, FTAG); rw_exit(&zfsvfs->z_fuid_lock); diff --git a/usr/src/uts/common/fs/zfs/zfs_vnops.c b/usr/src/uts/common/fs/zfs/zfs_vnops.c index edf2e85200..192d2e6f7c 100644 --- a/usr/src/uts/common/fs/zfs/zfs_vnops.c +++ b/usr/src/uts/common/fs/zfs/zfs_vnops.c @@ -1214,15 +1214,18 @@ top: tx = dmu_tx_create(os); dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT); - if (zfsvfs->z_fuid_obj == 0) { - dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT); - dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, - SPA_MAXBLOCKSIZE); - 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, - SPA_MAXBLOCKSIZE); + if (aclp && aclp->z_has_fuids) { + if (zfsvfs->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)); + 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, dzp->z_id); dmu_tx_hold_zap(tx, dzp->z_id, TRUE, name); @@ -1632,15 +1635,17 @@ top: tx = dmu_tx_create(zfsvfs->z_os); dmu_tx_hold_zap(tx, dzp->z_id, TRUE, dirname); dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, FALSE, NULL); - if (zfsvfs->z_fuid_obj == 0) { - dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT); - dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, - SPA_MAXBLOCKSIZE); - 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, - SPA_MAXBLOCKSIZE); + if (aclp && aclp->z_has_fuids) { + if (zfsvfs->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)); + 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)); + } } if ((dzp->z_phys->zp_flags & ZFS_INHERIT_ACE) || aclp) dmu_tx_hold_write(tx, DMU_NEW_OBJECT, @@ -2338,6 +2343,7 @@ zfs_setattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr, zfs_fuid_info_t *fuidp = NULL; xvattr_t *xvap = (xvattr_t *)vap; /* vap may be an xvattr_t * */ xoptattr_t *xoap; + zfs_acl_t *aclp = NULL; boolean_t skipaclchk = (flags & ATTR_NOACLCHECK) ? B_TRUE : B_FALSE; if (mask == 0) @@ -2565,15 +2571,18 @@ top: tx = dmu_tx_create(zfsvfs->z_os); dmu_tx_hold_bonus(tx, zp->z_id); - if (zfsvfs->z_fuid_obj == 0) { - dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT); - dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, - SPA_MAXBLOCKSIZE); - 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, - SPA_MAXBLOCKSIZE); + if (((mask & AT_UID) && IS_EPHEMERAL(vap->va_uid)) || + ((mask & AT_GID) && IS_EPHEMERAL(vap->va_gid))) { + if (zfsvfs->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)); + 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)); + } } if (mask & AT_MODE) { @@ -2581,6 +2590,11 @@ top: new_mode = (pmode & S_IFMT) | (vap->va_mode & ~S_IFMT); + if (err = zfs_acl_chmod_setattr(zp, &aclp, new_mode)) { + dmu_tx_abort(tx); + ZFS_EXIT(zfsvfs); + return (err); + } if (pzp->zp_acl.z_acl_extern_obj) { /* Are we upgrading ACL from old V0 format to new V1 */ if (zfsvfs->z_version <= ZPL_VERSION_FUID && @@ -2590,15 +2604,17 @@ top: pzp->zp_acl.z_acl_extern_obj, 0, DMU_OBJECT_END); dmu_tx_hold_write(tx, DMU_NEW_OBJECT, - 0, sizeof (zfs_object_ace_t) * 2048 + 6); + 0, aclp->z_acl_bytes); } else { dmu_tx_hold_write(tx, pzp->zp_acl.z_acl_extern_obj, 0, - SPA_MAXBLOCKSIZE); + aclp->z_acl_bytes); + } + } else if (!(pzp->zp_flags & ZFS_ACL_TRIVIAL)) { + if (aclp->z_acl_bytes > ZFS_ACE_SPACE) { + dmu_tx_hold_write(tx, DMU_NEW_OBJECT, + 0, aclp->z_acl_bytes); } - } else { - dmu_tx_hold_write(tx, DMU_NEW_OBJECT, - 0, sizeof (zfs_object_ace_t) * 2048 + 6); } } @@ -2607,6 +2623,8 @@ top: if (err) { dmu_tx_abort(tx); ZFS_EXIT(zfsvfs); + if (aclp) + zfs_acl_free(aclp); return (err); } dmu_tx_hold_bonus(tx, attrzp->z_id); @@ -2616,6 +2634,12 @@ top: if (err) { if (attrzp) VN_RELE(ZTOV(attrzp)); + + if (aclp) { + zfs_acl_free(aclp); + aclp = NULL; + } + if (err == ERESTART && zfsvfs->z_assign == TXG_NOWAIT) { dmu_tx_wait(tx); dmu_tx_abort(tx); @@ -2639,8 +2663,11 @@ top: mutex_enter(&zp->z_lock); if (mask & AT_MODE) { - err = zfs_acl_chmod_setattr(zp, new_mode, tx, cr); + mutex_enter(&zp->z_acl_lock); + zp->z_phys->zp_mode = new_mode; + err = zfs_aclset_common(zp, aclp, cr, &fuidp, tx); ASSERT3U(err, ==, 0); + mutex_exit(&zp->z_acl_lock); } if (attrzp) @@ -2663,6 +2690,9 @@ top: vap->va_gid, cr, ZFS_GROUP, tx, &fuidp); } + if (aclp) + zfs_acl_free(aclp); + if (attrzp) mutex_exit(&attrzp->z_lock); @@ -3177,15 +3207,17 @@ top: dmu_tx_hold_zap(tx, dzp->z_id, TRUE, name); if (dzp->z_phys->zp_flags & ZFS_INHERIT_ACE) dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, SPA_MAXBLOCKSIZE); - if (zfsvfs->z_fuid_obj == 0) { - dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT); - dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, - SPA_MAXBLOCKSIZE); - 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, - SPA_MAXBLOCKSIZE); + if (IS_EPHEMERAL(crgetuid(cr)) || IS_EPHEMERAL(crgetgid(cr))) { + if (zfsvfs->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)); + 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)); + } } error = dmu_tx_assign(tx, zfsvfs->z_assign); if (error) { |