summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr/src/uts/common/fs/zfs/sys/zfs_acl.h6
-rw-r--r--usr/src/uts/common/fs/zfs/sys/zfs_fuid.h5
-rw-r--r--usr/src/uts/common/fs/zfs/sys/zfs_vfsops.h3
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_acl.c51
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_dir.c18
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_fuid.c24
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_vnops.c116
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) {