mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-23 02:44:41 +03:00
Prototype/structure update for Linux
I appologize in advance why to many things ended up in this commit. When it could be seperated in to a whole series of commits teasing that all apart now would take considerable time and I'm not sure there's much merrit in it. As such I'll just summerize the intent of the changes which are all (or partly) in this commit. Broadly the intent is to remove as much Solaris specific code as possible and replace it with native Linux equivilants. More specifically: 1) Replace all instances of zfsvfs_t with zfs_sb_t. While the type is largely the same calling it private super block data rather than a zfsvfs is more consistent with how Linux names this. While non critical it makes the code easier to read when your thinking in Linux friendly VFS terms. 2) Replace vnode_t with struct inode. The Linux VFS doesn't have the notion of a vnode and there's absolutely no good reason to create one. There are in fact several good reasons to remove it. It just adds overhead on Linux if we were to manage one, it conplicates the code, and it likely will lead to bugs so there's a good change it will be out of date. The code has been updated to remove all need for this type. 3) Replace all vtype_t's with umode types. Along with this shift all uses of types to mode bits. The Solaris code would pass a vtype which is redundant with the Linux mode. Just update all the code to use the Linux mode macros and remove this redundancy. 4) Remove using of vn_* helpers and replace where needed with inode helpers. The big example here is creating iput_aync to replace vn_rele_async. Other vn helpers will be addressed as needed but they should be be emulated. They are a Solaris VFS'ism and should simply be replaced with Linux equivilants. 5) Update znode alloc/free code. Under Linux it's common to embed the inode specific data with the inode itself. This removes the need for an extra memory allocation. In zfs this information is called a znode and it now embeds the inode with it. Allocators have been updated accordingly. 6) Minimal integration with the vfs flags for setting up the super block and handling mount options has been added this code will need to be refined but functionally it's all there. This will be the first and last of these to large to review commits.
This commit is contained in:
@@ -910,10 +910,8 @@ dmu_objset_snapshot_one(const char *name, void *arg)
|
||||
* permission checks for the starting dataset have already been
|
||||
* performed in zfs_secpolicy_snapshot()
|
||||
*/
|
||||
#ifdef HAVE_ZPL
|
||||
if (sn->recursive && (err = zfs_secpolicy_snapshot_perms(name, CRED())))
|
||||
return (err);
|
||||
#endif
|
||||
|
||||
err = dmu_objset_hold(name, sn, &os);
|
||||
if (err != 0)
|
||||
|
||||
@@ -2364,13 +2364,11 @@ dsl_snapshot_rename_one(const char *name, void *arg)
|
||||
* For recursive snapshot renames the parent won't be changing
|
||||
* so we just pass name for both the to/from argument.
|
||||
*/
|
||||
#ifdef HAVE_ZPL
|
||||
err = zfs_secpolicy_rename_perms(snapname, snapname, CRED());
|
||||
if (err != 0) {
|
||||
strfree(snapname);
|
||||
return (err == ENOENT ? 0 : err);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* XXX: Ignore for SPL version until mounting the FS is supported */
|
||||
#if defined(_KERNEL) && !defined(HAVE_SPL)
|
||||
|
||||
@@ -92,7 +92,7 @@ dsl_pool_open_impl(spa_t *spa, uint64_t txg)
|
||||
|
||||
mutex_init(&dp->dp_lock, NULL, MUTEX_DEFAULT, NULL);
|
||||
|
||||
dp->dp_vnrele_taskq = taskq_create("zfs_vn_rele_taskq", 1, minclsyspri,
|
||||
dp->dp_iput_taskq = taskq_create("zfs_iput_taskq", 1, minclsyspri,
|
||||
1, 4, 0);
|
||||
|
||||
return (dp);
|
||||
@@ -214,7 +214,7 @@ dsl_pool_close(dsl_pool_t *dp)
|
||||
dsl_scan_fini(dp);
|
||||
rw_destroy(&dp->dp_config_rwlock);
|
||||
mutex_destroy(&dp->dp_lock);
|
||||
taskq_destroy(dp->dp_vnrele_taskq);
|
||||
taskq_destroy(dp->dp_iput_taskq);
|
||||
if (dp->dp_blkstats)
|
||||
kmem_free(dp->dp_blkstats, sizeof (zfs_all_blkstats_t));
|
||||
kmem_free(dp, sizeof (dsl_pool_t));
|
||||
@@ -738,9 +738,9 @@ dsl_pool_create_origin(dsl_pool_t *dp, dmu_tx_t *tx)
|
||||
}
|
||||
|
||||
taskq_t *
|
||||
dsl_pool_vnrele_taskq(dsl_pool_t *dp)
|
||||
dsl_pool_iput_taskq(dsl_pool_t *dp)
|
||||
{
|
||||
return (dp->dp_vnrele_taskq);
|
||||
return (dp->dp_iput_taskq);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -179,7 +179,6 @@ spa_config_write(spa_config_dirent_t *dp, nvlist_t *nvl)
|
||||
(void) vn_rename(temp, dp->scd_path, UIO_SYSSPACE);
|
||||
}
|
||||
(void) VOP_CLOSE(vp, oflags, 1, 0, kcred, NULL);
|
||||
VN_RELE(vp);
|
||||
}
|
||||
|
||||
(void) vn_remove(temp, UIO_SYSSPACE, RMFILE);
|
||||
|
||||
@@ -130,7 +130,6 @@ vdev_file_close(vdev_t *vd)
|
||||
(void) VOP_PUTPAGE(vf->vf_vnode, 0, 0, B_INVAL, kcred, NULL);
|
||||
(void) VOP_CLOSE(vf->vf_vnode, spa_mode(vd->vdev_spa), 1, 0,
|
||||
kcred, NULL);
|
||||
VN_RELE(vf->vf_vnode);
|
||||
}
|
||||
|
||||
vd->vdev_delayed_close = B_FALSE;
|
||||
|
||||
+140
-141
@@ -345,7 +345,7 @@ zfs_external_acl(znode_t *zp)
|
||||
* changed.
|
||||
*/
|
||||
|
||||
if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_ZNODE_ACL(zp->z_zfsvfs),
|
||||
if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_ZNODE_ACL(ZTOZSB(zp)),
|
||||
&acl_phys, sizeof (acl_phys))) == 0)
|
||||
return (acl_phys.z_acl_extern_obj);
|
||||
else {
|
||||
@@ -368,23 +368,23 @@ static int
|
||||
zfs_acl_znode_info(znode_t *zp, int *aclsize, int *aclcount,
|
||||
zfs_acl_phys_t *aclphys)
|
||||
{
|
||||
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
|
||||
zfs_sb_t *zsb = ZTOZSB(zp);
|
||||
uint64_t acl_count;
|
||||
int size;
|
||||
int error;
|
||||
|
||||
ASSERT(MUTEX_HELD(&zp->z_acl_lock));
|
||||
if (zp->z_is_sa) {
|
||||
if ((error = sa_size(zp->z_sa_hdl, SA_ZPL_DACL_ACES(zfsvfs),
|
||||
if ((error = sa_size(zp->z_sa_hdl, SA_ZPL_DACL_ACES(zsb),
|
||||
&size)) != 0)
|
||||
return (error);
|
||||
*aclsize = size;
|
||||
if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_DACL_COUNT(zfsvfs),
|
||||
if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_DACL_COUNT(zsb),
|
||||
&acl_count, sizeof (acl_count))) != 0)
|
||||
return (error);
|
||||
*aclcount = acl_count;
|
||||
} else {
|
||||
if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_ZNODE_ACL(zfsvfs),
|
||||
if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_ZNODE_ACL(zsb),
|
||||
aclphys, sizeof (*aclphys))) != 0)
|
||||
return (error);
|
||||
|
||||
@@ -418,7 +418,7 @@ zfs_znode_acl_version(znode_t *zp)
|
||||
* changed.
|
||||
*/
|
||||
if ((error = sa_lookup(zp->z_sa_hdl,
|
||||
SA_ZPL_ZNODE_ACL(zp->z_zfsvfs),
|
||||
SA_ZPL_ZNODE_ACL(ZTOZSB(zp)),
|
||||
&acl_phys, sizeof (acl_phys))) == 0)
|
||||
return (acl_phys.z_acl_version);
|
||||
else {
|
||||
@@ -444,7 +444,7 @@ zfs_acl_version(int version)
|
||||
static int
|
||||
zfs_acl_version_zp(znode_t *zp)
|
||||
{
|
||||
return (zfs_acl_version(zp->z_zfsvfs->z_version));
|
||||
return (zfs_acl_version(ZTOZSB(zp)->z_version));
|
||||
}
|
||||
|
||||
zfs_acl_t *
|
||||
@@ -531,7 +531,7 @@ zfs_acl_valid_ace_type(uint_t type, uint_t flags)
|
||||
}
|
||||
|
||||
static boolean_t
|
||||
zfs_ace_valid(vtype_t obj_type, zfs_acl_t *aclp, uint16_t type, uint16_t iflags)
|
||||
zfs_ace_valid(umode_t obj_mode, zfs_acl_t *aclp, uint16_t type, uint16_t iflags)
|
||||
{
|
||||
/*
|
||||
* first check type of entry
|
||||
@@ -554,7 +554,7 @@ zfs_ace_valid(vtype_t obj_type, zfs_acl_t *aclp, uint16_t type, uint16_t iflags)
|
||||
* next check inheritance level flags
|
||||
*/
|
||||
|
||||
if (obj_type == VDIR &&
|
||||
if (S_ISDIR(obj_mode) &&
|
||||
(iflags & (ACE_FILE_INHERIT_ACE|ACE_DIRECTORY_INHERIT_ACE)))
|
||||
aclp->z_hints |= ZFS_INHERIT_ACE;
|
||||
|
||||
@@ -648,7 +648,7 @@ zfs_ace_walk(void *datap, uint64_t cookie, int aclcnt,
|
||||
* ACE FUIDs will be created later.
|
||||
*/
|
||||
int
|
||||
zfs_copy_ace_2_fuid(zfsvfs_t *zfsvfs, vtype_t obj_type, zfs_acl_t *aclp,
|
||||
zfs_copy_ace_2_fuid(zfs_sb_t *zsb, umode_t obj_mode, zfs_acl_t *aclp,
|
||||
void *datap, zfs_ace_t *z_acl, uint64_t aclcnt, size_t *size,
|
||||
zfs_fuid_info_t **fuidp, cred_t *cr)
|
||||
{
|
||||
@@ -666,7 +666,7 @@ zfs_copy_ace_2_fuid(zfsvfs_t *zfsvfs, vtype_t obj_type, zfs_acl_t *aclp,
|
||||
entry_type = aceptr->z_hdr.z_flags & ACE_TYPE_FLAGS;
|
||||
if (entry_type != ACE_OWNER && entry_type != OWNING_GROUP &&
|
||||
entry_type != ACE_EVERYONE) {
|
||||
aceptr->z_fuid = zfs_fuid_create(zfsvfs, acep->a_who,
|
||||
aceptr->z_fuid = zfs_fuid_create(zsb, acep->a_who,
|
||||
cr, (entry_type == 0) ?
|
||||
ZFS_ACE_USER : ZFS_ACE_GROUP, fuidp);
|
||||
}
|
||||
@@ -674,7 +674,7 @@ zfs_copy_ace_2_fuid(zfsvfs_t *zfsvfs, vtype_t obj_type, zfs_acl_t *aclp,
|
||||
/*
|
||||
* Make sure ACE is valid
|
||||
*/
|
||||
if (zfs_ace_valid(obj_type, aclp, aceptr->z_hdr.z_type,
|
||||
if (zfs_ace_valid(obj_mode, aclp, aceptr->z_hdr.z_type,
|
||||
aceptr->z_hdr.z_flags) != B_TRUE)
|
||||
return (EINVAL);
|
||||
|
||||
@@ -710,7 +710,7 @@ zfs_copy_ace_2_fuid(zfsvfs_t *zfsvfs, vtype_t obj_type, zfs_acl_t *aclp,
|
||||
* Copy ZFS ACEs to fixed size ace_t layout
|
||||
*/
|
||||
static void
|
||||
zfs_copy_fuid_2_ace(zfsvfs_t *zfsvfs, zfs_acl_t *aclp, cred_t *cr,
|
||||
zfs_copy_fuid_2_ace(zfs_sb_t *zsb, zfs_acl_t *aclp, cred_t *cr,
|
||||
void *datap, int filter)
|
||||
{
|
||||
uint64_t who;
|
||||
@@ -753,7 +753,7 @@ zfs_copy_fuid_2_ace(zfsvfs_t *zfsvfs, zfs_acl_t *aclp, cred_t *cr,
|
||||
if ((entry_type != ACE_OWNER &&
|
||||
entry_type != OWNING_GROUP &&
|
||||
entry_type != ACE_EVERYONE)) {
|
||||
acep->a_who = zfs_fuid_map_id(zfsvfs, who,
|
||||
acep->a_who = zfs_fuid_map_id(zsb, who,
|
||||
cr, (entry_type & ACE_IDENTIFIER_GROUP) ?
|
||||
ZFS_ACE_GROUP : ZFS_ACE_USER);
|
||||
} else {
|
||||
@@ -767,7 +767,7 @@ zfs_copy_fuid_2_ace(zfsvfs_t *zfsvfs, zfs_acl_t *aclp, cred_t *cr,
|
||||
}
|
||||
|
||||
static int
|
||||
zfs_copy_ace_2_oldace(vtype_t obj_type, zfs_acl_t *aclp, ace_t *acep,
|
||||
zfs_copy_ace_2_oldace(umode_t obj_mode, zfs_acl_t *aclp, ace_t *acep,
|
||||
zfs_oldace_t *z_acl, int aclcnt, size_t *size)
|
||||
{
|
||||
int i;
|
||||
@@ -781,7 +781,7 @@ zfs_copy_ace_2_oldace(vtype_t obj_type, zfs_acl_t *aclp, ace_t *acep,
|
||||
/*
|
||||
* Make sure ACE is valid
|
||||
*/
|
||||
if (zfs_ace_valid(obj_type, aclp, aceptr->z_type,
|
||||
if (zfs_ace_valid(obj_mode, aclp, aceptr->z_type,
|
||||
aceptr->z_flags) != B_TRUE)
|
||||
return (EINVAL);
|
||||
}
|
||||
@@ -825,8 +825,8 @@ zfs_acl_xform(znode_t *zp, zfs_acl_t *aclp, cred_t *cr)
|
||||
newaclnode = zfs_acl_node_alloc(aclp->z_acl_count *
|
||||
sizeof (zfs_object_ace_t));
|
||||
aclp->z_ops = zfs_acl_fuid_ops;
|
||||
VERIFY(zfs_copy_ace_2_fuid(zp->z_zfsvfs, ZTOV(zp)->v_type, aclp,
|
||||
oldaclp, newaclnode->z_acldata, aclp->z_acl_count,
|
||||
VERIFY(zfs_copy_ace_2_fuid(ZTOZSB(zp), ZTOI(zp)->i_mode,
|
||||
aclp, oldaclp, newaclnode->z_acldata, aclp->z_acl_count,
|
||||
&newaclnode->z_size, NULL, cr) == 0);
|
||||
newaclnode->z_ace_count = aclp->z_acl_count;
|
||||
aclp->z_version = ZFS_ACL_VERSION;
|
||||
@@ -1100,7 +1100,7 @@ zfs_acl_node_read(znode_t *zp, boolean_t have_lock, zfs_acl_t **aclpp,
|
||||
|
||||
if (!zp->z_is_sa) {
|
||||
if (znode_acl.z_acl_extern_obj) {
|
||||
error = dmu_read(zp->z_zfsvfs->z_os,
|
||||
error = dmu_read(ZTOZSB(zp)->z_os,
|
||||
znode_acl.z_acl_extern_obj, 0, aclnode->z_size,
|
||||
aclnode->z_acldata, DMU_READ_PREFETCH);
|
||||
} else {
|
||||
@@ -1108,7 +1108,7 @@ zfs_acl_node_read(znode_t *zp, boolean_t have_lock, zfs_acl_t **aclpp,
|
||||
aclnode->z_size);
|
||||
}
|
||||
} else {
|
||||
error = sa_lookup(zp->z_sa_hdl, SA_ZPL_DACL_ACES(zp->z_zfsvfs),
|
||||
error = sa_lookup(zp->z_sa_hdl, SA_ZPL_DACL_ACES(ZTOZSB(zp)),
|
||||
aclnode->z_acldata, aclnode->z_size);
|
||||
}
|
||||
|
||||
@@ -1295,7 +1295,7 @@ int
|
||||
zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx)
|
||||
{
|
||||
int error;
|
||||
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
|
||||
zfs_sb_t *zsb = ZTOZSB(zp);
|
||||
dmu_object_type_t otype;
|
||||
zfs_acl_locator_cb_t locate = { 0 };
|
||||
uint64_t mode;
|
||||
@@ -1309,11 +1309,11 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx)
|
||||
zp->z_uid, zp->z_gid);
|
||||
|
||||
zp->z_mode = mode;
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zfsvfs), NULL,
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zsb), NULL,
|
||||
&mode, sizeof (mode));
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs), NULL,
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb), NULL,
|
||||
&zp->z_pflags, sizeof (zp->z_pflags));
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL,
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb), NULL,
|
||||
&ctime, sizeof (ctime));
|
||||
|
||||
if (zp->z_acl_cached) {
|
||||
@@ -1324,11 +1324,11 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx)
|
||||
/*
|
||||
* Upgrade needed?
|
||||
*/
|
||||
if (!zfsvfs->z_use_fuids) {
|
||||
if (!zsb->z_use_fuids) {
|
||||
otype = DMU_OT_OLDACL;
|
||||
} else {
|
||||
if ((aclp->z_version == ZFS_ACL_VERSION_INITIAL) &&
|
||||
(zfsvfs->z_version >= ZPL_VERSION_FUID))
|
||||
(zsb->z_version >= ZPL_VERSION_FUID))
|
||||
zfs_acl_xform(zp, aclp, cr);
|
||||
ASSERT(aclp->z_version >= ZFS_ACL_VERSION_FUID);
|
||||
otype = DMU_OT_ACL;
|
||||
@@ -1341,9 +1341,9 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx)
|
||||
|
||||
if (zp->z_is_sa) { /* the easy case, just update the ACL attribute */
|
||||
locate.cb_aclp = aclp;
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_DACL_ACES(zfsvfs),
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_DACL_ACES(zsb),
|
||||
zfs_acl_data_locator, &locate, aclp->z_acl_bytes);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_DACL_COUNT(zfsvfs),
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_DACL_COUNT(zsb),
|
||||
NULL, &aclp->z_acl_count, sizeof (uint64_t));
|
||||
} else { /* Painful legacy way */
|
||||
zfs_acl_node_t *aclnode;
|
||||
@@ -1351,7 +1351,7 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx)
|
||||
zfs_acl_phys_t acl_phys;
|
||||
uint64_t aoid;
|
||||
|
||||
if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_ZNODE_ACL(zfsvfs),
|
||||
if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_ZNODE_ACL(zsb),
|
||||
&acl_phys, sizeof (acl_phys))) != 0)
|
||||
return (error);
|
||||
|
||||
@@ -1365,20 +1365,20 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx)
|
||||
*/
|
||||
if (aoid &&
|
||||
aclp->z_version != acl_phys.z_acl_version) {
|
||||
error = dmu_object_free(zfsvfs->z_os, aoid, tx);
|
||||
error = dmu_object_free(zsb->z_os, aoid, tx);
|
||||
if (error)
|
||||
return (error);
|
||||
aoid = 0;
|
||||
}
|
||||
if (aoid == 0) {
|
||||
aoid = dmu_object_alloc(zfsvfs->z_os,
|
||||
aoid = dmu_object_alloc(zsb->z_os,
|
||||
otype, aclp->z_acl_bytes,
|
||||
otype == DMU_OT_ACL ?
|
||||
DMU_OT_SYSACL : DMU_OT_NONE,
|
||||
otype == DMU_OT_ACL ?
|
||||
DN_MAX_BONUSLEN : 0, tx);
|
||||
} else {
|
||||
(void) dmu_object_set_blocksize(zfsvfs->z_os,
|
||||
(void) dmu_object_set_blocksize(zsb->z_os,
|
||||
aoid, aclp->z_acl_bytes, 0, tx);
|
||||
}
|
||||
acl_phys.z_acl_extern_obj = aoid;
|
||||
@@ -1386,7 +1386,7 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx)
|
||||
aclnode = list_next(&aclp->z_acl, aclnode)) {
|
||||
if (aclnode->z_ace_count == 0)
|
||||
continue;
|
||||
dmu_write(zfsvfs->z_os, aoid, off,
|
||||
dmu_write(zsb->z_os, aoid, off,
|
||||
aclnode->z_size, aclnode->z_acldata, tx);
|
||||
off += aclnode->z_size;
|
||||
}
|
||||
@@ -1396,7 +1396,7 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx)
|
||||
* Migrating back embedded?
|
||||
*/
|
||||
if (acl_phys.z_acl_extern_obj) {
|
||||
error = dmu_object_free(zfsvfs->z_os,
|
||||
error = dmu_object_free(zsb->z_os,
|
||||
acl_phys.z_acl_extern_obj, tx);
|
||||
if (error)
|
||||
return (error);
|
||||
@@ -1425,7 +1425,7 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx)
|
||||
}
|
||||
acl_phys.z_acl_version = aclp->z_version;
|
||||
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ZNODE_ACL(zfsvfs), NULL,
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ZNODE_ACL(zsb), NULL,
|
||||
&acl_phys, sizeof (acl_phys));
|
||||
}
|
||||
|
||||
@@ -1444,19 +1444,19 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx)
|
||||
}
|
||||
|
||||
static void
|
||||
zfs_acl_chmod(zfsvfs_t *zfsvfs, uint64_t mode, zfs_acl_t *aclp)
|
||||
zfs_acl_chmod(zfs_sb_t *zsb, uint64_t mode, zfs_acl_t *aclp)
|
||||
{
|
||||
void *acep = NULL;
|
||||
uint64_t who;
|
||||
int new_count, new_bytes;
|
||||
int ace_size;
|
||||
int entry_type;
|
||||
int entry_type;
|
||||
uint16_t iflags, type;
|
||||
uint32_t access_mask;
|
||||
zfs_acl_node_t *newnode;
|
||||
size_t abstract_size = aclp->z_ops.ace_abstract_size();
|
||||
void *zacep;
|
||||
uint32_t owner, group, everyone;
|
||||
size_t abstract_size = aclp->z_ops.ace_abstract_size();
|
||||
void *zacep;
|
||||
uint32_t owner, group, everyone;
|
||||
uint32_t deny1, deny2, allow0;
|
||||
|
||||
new_count = new_bytes = 0;
|
||||
@@ -1516,7 +1516,7 @@ zfs_acl_chmod(zfsvfs_t *zfsvfs, uint64_t mode, zfs_acl_t *aclp)
|
||||
* Limit permissions to be no greater than
|
||||
* group permissions
|
||||
*/
|
||||
if (zfsvfs->z_acl_inherit == ZFS_ACL_RESTRICTED) {
|
||||
if (zsb->z_acl_inherit == ZFS_ACL_RESTRICTED) {
|
||||
if (!(mode & S_IRGRP))
|
||||
access_mask &= ~ACE_READ_DATA;
|
||||
if (!(mode & S_IWGRP))
|
||||
@@ -1558,7 +1558,7 @@ zfs_acl_chmod_setattr(znode_t *zp, zfs_acl_t **aclp, uint64_t mode)
|
||||
mutex_enter(&zp->z_lock);
|
||||
*aclp = zfs_acl_alloc(zfs_acl_version_zp(zp));
|
||||
(*aclp)->z_hints = zp->z_pflags & V4_ACL_WIDE_FLAGS;
|
||||
zfs_acl_chmod(zp->z_zfsvfs, mode, *aclp);
|
||||
zfs_acl_chmod(ZTOZSB(zp), mode, *aclp);
|
||||
mutex_exit(&zp->z_lock);
|
||||
mutex_exit(&zp->z_acl_lock);
|
||||
ASSERT(*aclp);
|
||||
@@ -1568,11 +1568,11 @@ zfs_acl_chmod_setattr(znode_t *zp, zfs_acl_t **aclp, uint64_t mode)
|
||||
* strip off write_owner and write_acl
|
||||
*/
|
||||
static void
|
||||
zfs_restricted_update(zfsvfs_t *zfsvfs, zfs_acl_t *aclp, void *acep)
|
||||
zfs_restricted_update(zfs_sb_t *zsb, zfs_acl_t *aclp, void *acep)
|
||||
{
|
||||
uint32_t mask = aclp->z_ops.ace_mask_get(acep);
|
||||
|
||||
if ((zfsvfs->z_acl_inherit == ZFS_ACL_RESTRICTED) &&
|
||||
if ((zsb->z_acl_inherit == ZFS_ACL_RESTRICTED) &&
|
||||
(aclp->z_ops.ace_type_get(acep) == ALLOW)) {
|
||||
mask &= ~RESTRICTED_CLEAR;
|
||||
aclp->z_ops.ace_mask_set(acep, mask);
|
||||
@@ -1583,14 +1583,14 @@ zfs_restricted_update(zfsvfs_t *zfsvfs, zfs_acl_t *aclp, void *acep)
|
||||
* Should ACE be inherited?
|
||||
*/
|
||||
static int
|
||||
zfs_ace_can_use(vtype_t vtype, uint16_t acep_flags)
|
||||
zfs_ace_can_use(umode_t obj_mode, uint16_t acep_flags)
|
||||
{
|
||||
int iflags = (acep_flags & 0xf);
|
||||
|
||||
if ((vtype == VDIR) && (iflags & ACE_DIRECTORY_INHERIT_ACE))
|
||||
if (S_ISDIR(obj_mode) && (iflags & ACE_DIRECTORY_INHERIT_ACE))
|
||||
return (1);
|
||||
else if (iflags & ACE_FILE_INHERIT_ACE)
|
||||
return (!((vtype == VDIR) &&
|
||||
return (!(S_ISDIR(obj_mode) &&
|
||||
(iflags & ACE_NO_PROPAGATE_INHERIT_ACE)));
|
||||
return (0);
|
||||
}
|
||||
@@ -1599,7 +1599,7 @@ zfs_ace_can_use(vtype_t vtype, uint16_t acep_flags)
|
||||
* inherit inheritable ACEs from parent
|
||||
*/
|
||||
static zfs_acl_t *
|
||||
zfs_acl_inherit(zfsvfs_t *zfsvfs, vtype_t vtype, zfs_acl_t *paclp,
|
||||
zfs_acl_inherit(zfs_sb_t *zsb, umode_t obj_mode, zfs_acl_t *paclp,
|
||||
uint64_t mode, boolean_t *need_chmod)
|
||||
{
|
||||
void *pacep;
|
||||
@@ -1612,21 +1612,21 @@ zfs_acl_inherit(zfsvfs_t *zfsvfs, vtype_t vtype, zfs_acl_t *paclp,
|
||||
size_t ace_size;
|
||||
void *data1, *data2;
|
||||
size_t data1sz, data2sz;
|
||||
boolean_t vdir = vtype == VDIR;
|
||||
boolean_t vreg = vtype == VREG;
|
||||
boolean_t vdir = S_ISDIR(obj_mode);
|
||||
boolean_t vreg = S_ISREG(obj_mode);
|
||||
boolean_t passthrough, passthrough_x, noallow;
|
||||
|
||||
passthrough_x =
|
||||
zfsvfs->z_acl_inherit == ZFS_ACL_PASSTHROUGH_X;
|
||||
zsb->z_acl_inherit == ZFS_ACL_PASSTHROUGH_X;
|
||||
passthrough = passthrough_x ||
|
||||
zfsvfs->z_acl_inherit == ZFS_ACL_PASSTHROUGH;
|
||||
zsb->z_acl_inherit == ZFS_ACL_PASSTHROUGH;
|
||||
noallow =
|
||||
zfsvfs->z_acl_inherit == ZFS_ACL_NOALLOW;
|
||||
zsb->z_acl_inherit == ZFS_ACL_NOALLOW;
|
||||
|
||||
*need_chmod = B_TRUE;
|
||||
pacep = NULL;
|
||||
aclp = zfs_acl_alloc(paclp->z_version);
|
||||
if (zfsvfs->z_acl_inherit == ZFS_ACL_DISCARD || vtype == VLNK)
|
||||
if (zsb->z_acl_inherit == ZFS_ACL_DISCARD || S_ISLNK(obj_mode))
|
||||
return (aclp);
|
||||
while ((pacep = zfs_acl_next_ace(paclp, pacep, &who,
|
||||
&access_mask, &iflags, &type))) {
|
||||
@@ -1642,7 +1642,7 @@ zfs_acl_inherit(zfsvfs_t *zfsvfs, vtype_t vtype, zfs_acl_t *paclp,
|
||||
|
||||
ace_size = aclp->z_ops.ace_size(pacep);
|
||||
|
||||
if (!zfs_ace_can_use(vtype, iflags))
|
||||
if (!zfs_ace_can_use(obj_mode, iflags))
|
||||
continue;
|
||||
|
||||
/*
|
||||
@@ -1690,7 +1690,7 @@ zfs_acl_inherit(zfsvfs_t *zfsvfs, vtype_t vtype, zfs_acl_t *paclp,
|
||||
newflags &= ~ALL_INHERIT;
|
||||
aclp->z_ops.ace_flags_set(acep,
|
||||
newflags|ACE_INHERITED_ACE);
|
||||
zfs_restricted_update(zfsvfs, aclp, acep);
|
||||
zfs_restricted_update(zsb, aclp, acep);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1723,7 +1723,7 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr,
|
||||
vsecattr_t *vsecp, zfs_acl_ids_t *acl_ids)
|
||||
{
|
||||
int error;
|
||||
zfsvfs_t *zfsvfs = dzp->z_zfsvfs;
|
||||
zfs_sb_t *zsb = ZTOZSB(dzp);
|
||||
zfs_acl_t *paclp;
|
||||
#ifdef HAVE_KSID
|
||||
gid_t gid;
|
||||
@@ -1732,11 +1732,11 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr,
|
||||
boolean_t inherited = B_FALSE;
|
||||
|
||||
bzero(acl_ids, sizeof (zfs_acl_ids_t));
|
||||
acl_ids->z_mode = MAKEIMODE(vap->va_type, vap->va_mode);
|
||||
acl_ids->z_mode = vap->va_mode;
|
||||
|
||||
if (vsecp)
|
||||
if ((error = zfs_vsec_2_aclp(zfsvfs, vap->va_type, vsecp, cr,
|
||||
&acl_ids->z_fuidp, &acl_ids->z_aclp)) != 0)
|
||||
if ((error = zfs_vsec_2_aclp(zsb, vap->va_mode, vsecp,
|
||||
cr, &acl_ids->z_fuidp, &acl_ids->z_aclp)) != 0)
|
||||
return (error);
|
||||
|
||||
acl_ids->z_fuid = vap->va_uid;
|
||||
@@ -1745,21 +1745,19 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr,
|
||||
/*
|
||||
* Determine uid and gid.
|
||||
*/
|
||||
if ((flag & IS_ROOT_NODE) || zfsvfs->z_replay ||
|
||||
((flag & IS_XATTR) && (vap->va_type == VDIR))) {
|
||||
acl_ids->z_fuid = zfs_fuid_create(zfsvfs,
|
||||
(uint64_t)vap->va_uid, cr,
|
||||
ZFS_OWNER, &acl_ids->z_fuidp);
|
||||
acl_ids->z_fgid = zfs_fuid_create(zfsvfs,
|
||||
(uint64_t)vap->va_gid, cr,
|
||||
ZFS_GROUP, &acl_ids->z_fuidp);
|
||||
if ((flag & IS_ROOT_NODE) || zsb->z_replay ||
|
||||
((flag & IS_XATTR) && (S_ISDIR(vap->va_mode)))) {
|
||||
acl_ids->z_fuid = zfs_fuid_create(zsb, (uint64_t)vap->va_uid,
|
||||
cr, ZFS_OWNER, &acl_ids->z_fuidp);
|
||||
acl_ids->z_fgid = zfs_fuid_create(zsb, (uint64_t)vap->va_gid,
|
||||
cr, ZFS_GROUP, &acl_ids->z_fuidp);
|
||||
gid = vap->va_gid;
|
||||
} else {
|
||||
acl_ids->z_fuid = zfs_fuid_create_cred(zfsvfs, ZFS_OWNER,
|
||||
acl_ids->z_fuid = zfs_fuid_create_cred(zsb, ZFS_OWNER,
|
||||
cr, &acl_ids->z_fuidp);
|
||||
acl_ids->z_fgid = 0;
|
||||
if (vap->va_mask & AT_GID) {
|
||||
acl_ids->z_fgid = zfs_fuid_create(zfsvfs,
|
||||
acl_ids->z_fgid = zfs_fuid_create(zsb,
|
||||
(uint64_t)vap->va_gid,
|
||||
cr, ZFS_GROUP, &acl_ids->z_fuidp);
|
||||
gid = vap->va_gid;
|
||||
@@ -1774,13 +1772,13 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr,
|
||||
uint32_t rid;
|
||||
|
||||
acl_ids->z_fgid = dzp->z_gid;
|
||||
gid = zfs_fuid_map_id(zfsvfs, acl_ids->z_fgid,
|
||||
gid = zfs_fuid_map_id(zsb, acl_ids->z_fgid,
|
||||
cr, ZFS_GROUP);
|
||||
|
||||
if (zfsvfs->z_use_fuids &&
|
||||
if (zsb->z_use_fuids &&
|
||||
IS_EPHEMERAL(acl_ids->z_fgid)) {
|
||||
domain = zfs_fuid_idx_domain(
|
||||
&zfsvfs->z_fuid_idx,
|
||||
&zsb->z_fuid_idx,
|
||||
FUID_INDEX(acl_ids->z_fgid));
|
||||
rid = FUID_RID(acl_ids->z_fgid);
|
||||
zfs_fuid_node_add(&acl_ids->z_fuidp,
|
||||
@@ -1789,7 +1787,7 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr,
|
||||
acl_ids->z_fgid, ZFS_GROUP);
|
||||
}
|
||||
} else {
|
||||
acl_ids->z_fgid = zfs_fuid_create_cred(zfsvfs,
|
||||
acl_ids->z_fgid = zfs_fuid_create_cred(zsb,
|
||||
ZFS_GROUP, cr, &acl_ids->z_fuidp);
|
||||
gid = crgetgid(cr);
|
||||
}
|
||||
@@ -1805,7 +1803,7 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr,
|
||||
*/
|
||||
|
||||
if (!(flag & IS_ROOT_NODE) && (dzp->z_mode & S_ISGID) &&
|
||||
(vap->va_type == VDIR)) {
|
||||
(S_ISDIR(vap->va_mode))) {
|
||||
acl_ids->z_mode |= S_ISGID;
|
||||
} else {
|
||||
if ((acl_ids->z_mode & S_ISGID) &&
|
||||
@@ -1816,13 +1814,13 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr,
|
||||
if (acl_ids->z_aclp == NULL) {
|
||||
mutex_enter(&dzp->z_acl_lock);
|
||||
mutex_enter(&dzp->z_lock);
|
||||
if (!(flag & IS_ROOT_NODE) && (ZTOV(dzp)->v_type == VDIR &&
|
||||
if (!(flag & IS_ROOT_NODE) && (S_ISDIR(ZTOI(dzp)->i_mode) &&
|
||||
(dzp->z_pflags & ZFS_INHERIT_ACE)) &&
|
||||
!(dzp->z_pflags & ZFS_XATTR)) {
|
||||
VERIFY(0 == zfs_acl_node_read(dzp, B_TRUE,
|
||||
&paclp, B_FALSE));
|
||||
acl_ids->z_aclp = zfs_acl_inherit(zfsvfs,
|
||||
vap->va_type, paclp, acl_ids->z_mode, &need_chmod);
|
||||
acl_ids->z_aclp = zfs_acl_inherit(zsb,
|
||||
vap->va_mode, paclp, acl_ids->z_mode, &need_chmod);
|
||||
inherited = B_TRUE;
|
||||
} else {
|
||||
acl_ids->z_aclp =
|
||||
@@ -1832,9 +1830,9 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr,
|
||||
mutex_exit(&dzp->z_lock);
|
||||
mutex_exit(&dzp->z_acl_lock);
|
||||
if (need_chmod) {
|
||||
acl_ids->z_aclp->z_hints |= (vap->va_type == VDIR) ?
|
||||
acl_ids->z_aclp->z_hints |= S_ISDIR(vap->va_mode) ?
|
||||
ZFS_ACL_AUTO_INHERIT : 0;
|
||||
zfs_acl_chmod(zfsvfs, acl_ids->z_mode, acl_ids->z_aclp);
|
||||
zfs_acl_chmod(zsb, acl_ids->z_mode, acl_ids->z_aclp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1864,10 +1862,10 @@ zfs_acl_ids_free(zfs_acl_ids_t *acl_ids)
|
||||
}
|
||||
|
||||
boolean_t
|
||||
zfs_acl_ids_overquota(zfsvfs_t *zfsvfs, zfs_acl_ids_t *acl_ids)
|
||||
zfs_acl_ids_overquota(zfs_sb_t *zsb, zfs_acl_ids_t *acl_ids)
|
||||
{
|
||||
return (zfs_fuid_overquota(zfsvfs, B_FALSE, acl_ids->z_fuid) ||
|
||||
zfs_fuid_overquota(zfsvfs, B_TRUE, acl_ids->z_fgid));
|
||||
return (zfs_fuid_overquota(zsb, B_FALSE, acl_ids->z_fuid) ||
|
||||
zfs_fuid_overquota(zsb, B_TRUE, acl_ids->z_fgid));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1939,7 +1937,7 @@ zfs_getacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr)
|
||||
vsecp->vsa_aclentsz = aclsz;
|
||||
|
||||
if (aclp->z_version == ZFS_ACL_VERSION_FUID)
|
||||
zfs_copy_fuid_2_ace(zp->z_zfsvfs, aclp, cr,
|
||||
zfs_copy_fuid_2_ace(ZTOZSB(zp), aclp, cr,
|
||||
vsecp->vsa_aclentp, !(mask & VSA_ACE_ALLTYPES));
|
||||
else {
|
||||
zfs_acl_node_t *aclnode;
|
||||
@@ -1971,7 +1969,7 @@ zfs_getacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr)
|
||||
}
|
||||
|
||||
int
|
||||
zfs_vsec_2_aclp(zfsvfs_t *zfsvfs, vtype_t obj_type,
|
||||
zfs_vsec_2_aclp(zfs_sb_t *zsb, umode_t obj_mode,
|
||||
vsecattr_t *vsecp, cred_t *cr, zfs_fuid_info_t **fuidp, zfs_acl_t **zaclp)
|
||||
{
|
||||
zfs_acl_t *aclp;
|
||||
@@ -1982,12 +1980,12 @@ zfs_vsec_2_aclp(zfsvfs_t *zfsvfs, vtype_t obj_type,
|
||||
if (vsecp->vsa_aclcnt > MAX_ACL_ENTRIES || vsecp->vsa_aclcnt <= 0)
|
||||
return (EINVAL);
|
||||
|
||||
aclp = zfs_acl_alloc(zfs_acl_version(zfsvfs->z_version));
|
||||
aclp = zfs_acl_alloc(zfs_acl_version(zsb->z_version));
|
||||
|
||||
aclp->z_hints = 0;
|
||||
aclnode = zfs_acl_node_alloc(aclcnt * sizeof (zfs_object_ace_t));
|
||||
if (aclp->z_version == ZFS_ACL_VERSION_INITIAL) {
|
||||
if ((error = zfs_copy_ace_2_oldace(obj_type, aclp,
|
||||
if ((error = zfs_copy_ace_2_oldace(obj_mode, aclp,
|
||||
(ace_t *)vsecp->vsa_aclentp, aclnode->z_acldata,
|
||||
aclcnt, &aclnode->z_size)) != 0) {
|
||||
zfs_acl_free(aclp);
|
||||
@@ -1995,7 +1993,7 @@ zfs_vsec_2_aclp(zfsvfs_t *zfsvfs, vtype_t obj_type,
|
||||
return (error);
|
||||
}
|
||||
} else {
|
||||
if ((error = zfs_copy_ace_2_fuid(zfsvfs, obj_type, aclp,
|
||||
if ((error = zfs_copy_ace_2_fuid(zsb, obj_mode, aclp,
|
||||
vsecp->vsa_aclentp, aclnode->z_acldata, aclcnt,
|
||||
&aclnode->z_size, fuidp, cr)) != 0) {
|
||||
zfs_acl_free(aclp);
|
||||
@@ -2031,8 +2029,8 @@ zfs_vsec_2_aclp(zfsvfs_t *zfsvfs, vtype_t obj_type,
|
||||
int
|
||||
zfs_setacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr)
|
||||
{
|
||||
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
|
||||
zilog_t *zilog = zfsvfs->z_log;
|
||||
zfs_sb_t *zsb = ZTOZSB(zp);
|
||||
zilog_t *zilog = zsb->z_log;
|
||||
ulong_t mask = vsecp->vsa_mask & (VSA_ACE | VSA_ACECNT);
|
||||
dmu_tx_t *tx;
|
||||
int error;
|
||||
@@ -2050,7 +2048,7 @@ zfs_setacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr)
|
||||
if ((error = zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr)))
|
||||
return (error);
|
||||
|
||||
error = zfs_vsec_2_aclp(zfsvfs, ZTOV(zp)->v_type, vsecp, cr, &fuidp,
|
||||
error = zfs_vsec_2_aclp(zsb, ZTOI(zp)->i_mode, vsecp, cr, &fuidp,
|
||||
&aclp);
|
||||
if (error)
|
||||
return (error);
|
||||
@@ -2067,13 +2065,13 @@ top:
|
||||
mutex_enter(&zp->z_acl_lock);
|
||||
mutex_enter(&zp->z_lock);
|
||||
|
||||
tx = dmu_tx_create(zfsvfs->z_os);
|
||||
tx = dmu_tx_create(zsb->z_os);
|
||||
|
||||
dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_TRUE);
|
||||
|
||||
fuid_dirtied = zfsvfs->z_fuid_dirty;
|
||||
fuid_dirtied = zsb->z_fuid_dirty;
|
||||
if (fuid_dirtied)
|
||||
zfs_fuid_txhold(zfsvfs, tx);
|
||||
zfs_fuid_txhold(zsb, tx);
|
||||
|
||||
/*
|
||||
* If old version and ACL won't fit in bonus and we aren't
|
||||
@@ -2081,7 +2079,7 @@ top:
|
||||
*/
|
||||
|
||||
if ((acl_obj = zfs_external_acl(zp)) != 0) {
|
||||
if (zfsvfs->z_version >= ZPL_VERSION_FUID &&
|
||||
if (zsb->z_version >= ZPL_VERSION_FUID &&
|
||||
zfs_znode_acl_version(zp) <= ZFS_ACL_VERSION_INITIAL) {
|
||||
dmu_tx_hold_free(tx, acl_obj, 0,
|
||||
DMU_OBJECT_END);
|
||||
@@ -2116,7 +2114,7 @@ top:
|
||||
zp->z_acl_cached = aclp;
|
||||
|
||||
if (fuid_dirtied)
|
||||
zfs_fuid_sync(zfsvfs, tx);
|
||||
zfs_fuid_sync(zsb, tx);
|
||||
|
||||
zfs_log_acl(zilog, tx, zp, vsecp, fuidp);
|
||||
|
||||
@@ -2139,9 +2137,9 @@ static int
|
||||
zfs_zaccess_dataset_check(znode_t *zp, uint32_t v4_mode)
|
||||
{
|
||||
if ((v4_mode & WRITE_MASK) &&
|
||||
(zp->z_zfsvfs->z_vfs->vfs_flag & VFS_RDONLY) &&
|
||||
(!IS_DEVVP(ZTOV(zp)) ||
|
||||
(IS_DEVVP(ZTOV(zp)) && (v4_mode & WRITE_MASK_ATTRS)))) {
|
||||
(ZTOZSB(zp)->z_vfs->mnt_flags & MNT_READONLY) &&
|
||||
(!S_ISDEV(ZTOI(zp)->i_mode) ||
|
||||
(S_ISDEV(ZTOI(zp)->i_mode) && (v4_mode & WRITE_MASK_ATTRS)))) {
|
||||
return (EROFS);
|
||||
}
|
||||
|
||||
@@ -2149,9 +2147,9 @@ zfs_zaccess_dataset_check(znode_t *zp, uint32_t v4_mode)
|
||||
* Only check for READONLY on non-directories.
|
||||
*/
|
||||
if ((v4_mode & WRITE_MASK_DATA) &&
|
||||
(((ZTOV(zp)->v_type != VDIR) &&
|
||||
((!S_ISDIR(ZTOI(zp)->i_mode) &&
|
||||
(zp->z_pflags & (ZFS_READONLY | ZFS_IMMUTABLE))) ||
|
||||
(ZTOV(zp)->v_type == VDIR &&
|
||||
(S_ISDIR(ZTOI(zp)->i_mode) &&
|
||||
(zp->z_pflags & ZFS_IMMUTABLE)))) {
|
||||
return (EPERM);
|
||||
}
|
||||
@@ -2198,11 +2196,11 @@ static int
|
||||
zfs_zaccess_aces_check(znode_t *zp, uint32_t *working_mode,
|
||||
boolean_t anyaccess, cred_t *cr)
|
||||
{
|
||||
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
|
||||
zfs_sb_t *zsb = ZTOZSB(zp);
|
||||
zfs_acl_t *aclp;
|
||||
int error;
|
||||
uid_t uid = crgetuid(cr);
|
||||
uint64_t who;
|
||||
uint64_t who;
|
||||
uint16_t type, iflags;
|
||||
uint16_t entry_type;
|
||||
uint32_t access_mask;
|
||||
@@ -2231,7 +2229,8 @@ zfs_zaccess_aces_check(znode_t *zp, uint32_t *working_mode,
|
||||
if (!zfs_acl_valid_ace_type(type, iflags))
|
||||
continue;
|
||||
|
||||
if (ZTOV(zp)->v_type == VDIR && (iflags & ACE_INHERIT_ONLY_ACE))
|
||||
if (S_ISDIR(ZTOI(zp)->i_mode) &&
|
||||
(iflags & ACE_INHERIT_ONLY_ACE))
|
||||
continue;
|
||||
|
||||
/* Skip ACE if it does not affect any AoI */
|
||||
@@ -2252,7 +2251,7 @@ zfs_zaccess_aces_check(znode_t *zp, uint32_t *working_mode,
|
||||
who = gowner;
|
||||
/*FALLTHROUGH*/
|
||||
case ACE_IDENTIFIER_GROUP:
|
||||
checkit = zfs_groupmember(zfsvfs, who, cr);
|
||||
checkit = zfs_groupmember(zsb, who, cr);
|
||||
break;
|
||||
case ACE_EVERYONE:
|
||||
checkit = B_TRUE;
|
||||
@@ -2263,7 +2262,7 @@ zfs_zaccess_aces_check(znode_t *zp, uint32_t *working_mode,
|
||||
if (entry_type == 0) {
|
||||
uid_t newid;
|
||||
|
||||
newid = zfs_fuid_map_id(zfsvfs, who, cr,
|
||||
newid = zfs_fuid_map_id(zsb, who, cr,
|
||||
ZFS_ACE_USER);
|
||||
if (newid != IDMAP_WK_CREATOR_OWNER_UID &&
|
||||
uid == newid)
|
||||
@@ -2325,8 +2324,8 @@ zfs_has_access(znode_t *zp, cred_t *cr)
|
||||
if (zfs_zaccess_aces_check(zp, &have, B_TRUE, cr) != 0) {
|
||||
uid_t owner;
|
||||
|
||||
owner = zfs_fuid_map_id(zp->z_zfsvfs, zp->z_uid, cr, ZFS_OWNER);
|
||||
return (secpolicy_vnode_any_access(cr, ZTOV(zp), owner) == 0);
|
||||
owner = zfs_fuid_map_id(ZTOZSB(zp), zp->z_uid, cr, ZFS_OWNER);
|
||||
return (secpolicy_vnode_any_access(cr, ZTOI(zp), owner) == 0);
|
||||
}
|
||||
return (B_TRUE);
|
||||
}
|
||||
@@ -2335,7 +2334,7 @@ static int
|
||||
zfs_zaccess_common(znode_t *zp, uint32_t v4_mode, uint32_t *working_mode,
|
||||
boolean_t *check_privs, boolean_t skipaclchk, cred_t *cr)
|
||||
{
|
||||
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
|
||||
zfs_sb_t *zsb = ZTOZSB(zp);
|
||||
int err;
|
||||
|
||||
*working_mode = v4_mode;
|
||||
@@ -2344,7 +2343,7 @@ zfs_zaccess_common(znode_t *zp, uint32_t v4_mode, uint32_t *working_mode,
|
||||
/*
|
||||
* Short circuit empty requests
|
||||
*/
|
||||
if (v4_mode == 0 || zfsvfs->z_replay) {
|
||||
if (v4_mode == 0 || zsb->z_replay) {
|
||||
*working_mode = 0;
|
||||
return (0);
|
||||
}
|
||||
@@ -2391,7 +2390,7 @@ zfs_fastaccesschk_execute(znode_t *zdp, cred_t *cr)
|
||||
return (EACCES);
|
||||
|
||||
is_attr = ((zdp->z_pflags & ZFS_XATTR) &&
|
||||
(ZTOV(zdp)->v_type == VDIR));
|
||||
(S_ISDIR(ZTOI(zdp)->i_mode)));
|
||||
if (is_attr)
|
||||
goto slow;
|
||||
|
||||
@@ -2439,9 +2438,9 @@ zfs_fastaccesschk_execute(znode_t *zdp, cred_t *cr)
|
||||
|
||||
slow:
|
||||
DTRACE_PROBE(zfs__fastpath__execute__access__miss);
|
||||
ZFS_ENTER(zdp->z_zfsvfs);
|
||||
ZFS_ENTER(ZTOZSB(zdp));
|
||||
error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr);
|
||||
ZFS_EXIT(zdp->z_zfsvfs);
|
||||
ZFS_EXIT(ZTOZSB(zdp));
|
||||
return (error);
|
||||
}
|
||||
|
||||
@@ -2456,13 +2455,13 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
|
||||
uint32_t working_mode;
|
||||
int error;
|
||||
int is_attr;
|
||||
boolean_t check_privs;
|
||||
boolean_t check_privs;
|
||||
znode_t *xzp;
|
||||
znode_t *check_zp = zp;
|
||||
znode_t *check_zp = zp;
|
||||
mode_t needed_bits;
|
||||
uid_t owner;
|
||||
|
||||
is_attr = ((zp->z_pflags & ZFS_XATTR) && (ZTOV(zp)->v_type == VDIR));
|
||||
is_attr = ((zp->z_pflags & ZFS_XATTR) && S_ISDIR(ZTOI(zp)->i_mode));
|
||||
|
||||
/*
|
||||
* If attribute then validate against base file
|
||||
@@ -2471,11 +2470,11 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
|
||||
uint64_t parent;
|
||||
|
||||
if ((error = sa_lookup(zp->z_sa_hdl,
|
||||
SA_ZPL_PARENT(zp->z_zfsvfs), &parent,
|
||||
SA_ZPL_PARENT(ZTOZSB(zp)), &parent,
|
||||
sizeof (parent))) != 0)
|
||||
return (error);
|
||||
|
||||
if ((error = zfs_zget(zp->z_zfsvfs,
|
||||
if ((error = zfs_zget(ZTOZSB(zp),
|
||||
parent, &xzp)) != 0) {
|
||||
return (error);
|
||||
}
|
||||
@@ -2497,11 +2496,11 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
|
||||
}
|
||||
}
|
||||
|
||||
owner = zfs_fuid_map_id(zp->z_zfsvfs, zp->z_uid, cr, ZFS_OWNER);
|
||||
owner = zfs_fuid_map_id(ZTOZSB(zp), zp->z_uid, cr, ZFS_OWNER);
|
||||
/*
|
||||
* Map the bits required to the standard vnode flags VREAD|VWRITE|VEXEC
|
||||
* in needed_bits. Map the bits mapped by working_mode (currently
|
||||
* missing) in missing_bits.
|
||||
* Map the bits required to the standard inode flags
|
||||
* S_IRUSR|S_IWUSR|S_IXUSR in the needed_bits. Map the bits
|
||||
* mapped by working_mode (currently missing) in missing_bits.
|
||||
* Call secpolicy_vnode_access2() with (needed_bits & ~checkmode),
|
||||
* needed_bits.
|
||||
*/
|
||||
@@ -2514,24 +2513,24 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
|
||||
|
||||
if (working_mode & (ACE_READ_DATA|ACE_READ_NAMED_ATTRS|
|
||||
ACE_READ_ACL|ACE_READ_ATTRIBUTES|ACE_SYNCHRONIZE))
|
||||
needed_bits |= VREAD;
|
||||
needed_bits |= S_IRUSR;
|
||||
if (working_mode & (ACE_WRITE_DATA|ACE_WRITE_NAMED_ATTRS|
|
||||
ACE_APPEND_DATA|ACE_WRITE_ATTRIBUTES|ACE_SYNCHRONIZE))
|
||||
needed_bits |= VWRITE;
|
||||
needed_bits |= S_IWUSR;
|
||||
if (working_mode & ACE_EXECUTE)
|
||||
needed_bits |= VEXEC;
|
||||
needed_bits |= S_IXUSR;
|
||||
|
||||
if ((error = zfs_zaccess_common(check_zp, mode, &working_mode,
|
||||
&check_privs, skipaclchk, cr)) == 0) {
|
||||
if (is_attr)
|
||||
VN_RELE(ZTOV(xzp));
|
||||
return (secpolicy_vnode_access2(cr, ZTOV(zp), owner,
|
||||
iput(ZTOI(xzp));
|
||||
return (secpolicy_vnode_access2(cr, ZTOI(zp), owner,
|
||||
needed_bits, needed_bits));
|
||||
}
|
||||
|
||||
if (error && !check_privs) {
|
||||
if (is_attr)
|
||||
VN_RELE(ZTOV(xzp));
|
||||
iput(ZTOI(xzp));
|
||||
return (error);
|
||||
}
|
||||
|
||||
@@ -2556,14 +2555,14 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
|
||||
|
||||
if (working_mode & (ACE_READ_DATA|ACE_READ_NAMED_ATTRS|
|
||||
ACE_READ_ACL|ACE_READ_ATTRIBUTES|ACE_SYNCHRONIZE))
|
||||
checkmode |= VREAD;
|
||||
checkmode |= S_IRUSR;
|
||||
if (working_mode & (ACE_WRITE_DATA|ACE_WRITE_NAMED_ATTRS|
|
||||
ACE_APPEND_DATA|ACE_WRITE_ATTRIBUTES|ACE_SYNCHRONIZE))
|
||||
checkmode |= VWRITE;
|
||||
checkmode |= S_IWUSR;
|
||||
if (working_mode & ACE_EXECUTE)
|
||||
checkmode |= VEXEC;
|
||||
checkmode |= S_IXUSR;
|
||||
|
||||
error = secpolicy_vnode_access2(cr, ZTOV(check_zp), owner,
|
||||
error = secpolicy_vnode_access2(cr, ZTOI(check_zp), owner,
|
||||
needed_bits & ~checkmode, needed_bits);
|
||||
|
||||
if (error == 0 && (working_mode & ACE_WRITE_OWNER))
|
||||
@@ -2588,19 +2587,19 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
|
||||
}
|
||||
}
|
||||
} else if (error == 0) {
|
||||
error = secpolicy_vnode_access2(cr, ZTOV(zp), owner,
|
||||
error = secpolicy_vnode_access2(cr, ZTOI(zp), owner,
|
||||
needed_bits, needed_bits);
|
||||
}
|
||||
|
||||
|
||||
if (is_attr)
|
||||
VN_RELE(ZTOV(xzp));
|
||||
iput(ZTOI(xzp));
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Translate traditional unix VREAD/VWRITE/VEXEC mode into
|
||||
* Translate traditional unix S_IRUSR/S_IWUSR/S_IXUSR mode into
|
||||
* native ACL format and call zfs_zaccess()
|
||||
*/
|
||||
int
|
||||
@@ -2627,10 +2626,10 @@ zfs_delete_final_check(znode_t *zp, znode_t *dzp,
|
||||
int error;
|
||||
uid_t downer;
|
||||
|
||||
downer = zfs_fuid_map_id(dzp->z_zfsvfs, dzp->z_uid, cr, ZFS_OWNER);
|
||||
downer = zfs_fuid_map_id(ZTOZSB(dzp), dzp->z_uid, cr, ZFS_OWNER);
|
||||
|
||||
error = secpolicy_vnode_access2(cr, ZTOV(dzp),
|
||||
downer, available_perms, VWRITE|VEXEC);
|
||||
error = secpolicy_vnode_access2(cr, ZTOI(dzp),
|
||||
downer, available_perms, S_IWUSR|S_IXUSR);
|
||||
|
||||
if (error == 0)
|
||||
error = zfs_sticky_remove_access(dzp, zp, cr);
|
||||
@@ -2750,8 +2749,8 @@ zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr)
|
||||
* Fourth row
|
||||
*/
|
||||
|
||||
available_perms = (dzp_working_mode & ACE_WRITE_DATA) ? 0 : VWRITE;
|
||||
available_perms |= (dzp_working_mode & ACE_EXECUTE) ? 0 : VEXEC;
|
||||
available_perms = (dzp_working_mode & ACE_WRITE_DATA) ? 0 : S_IWUSR;
|
||||
available_perms |= (dzp_working_mode & ACE_EXECUTE) ? 0 : S_IXUSR;
|
||||
|
||||
return (zfs_delete_final_check(zp, dzp, available_perms, cr));
|
||||
|
||||
@@ -2767,7 +2766,7 @@ zfs_zaccess_rename(znode_t *sdzp, znode_t *szp, znode_t *tdzp,
|
||||
if (szp->z_pflags & ZFS_AV_QUARANTINED)
|
||||
return (EACCES);
|
||||
|
||||
add_perm = (ZTOV(szp)->v_type == VDIR) ?
|
||||
add_perm = S_ISDIR(ZTOI(szp)->i_mode) ?
|
||||
ACE_ADD_SUBDIRECTORY : ACE_ADD_FILE;
|
||||
|
||||
/*
|
||||
|
||||
+143
-142
@@ -22,7 +22,6 @@
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_ZPL
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
@@ -62,12 +61,12 @@
|
||||
* of names after deciding which is the appropriate lookup interface.
|
||||
*/
|
||||
static int
|
||||
zfs_match_find(zfsvfs_t *zfsvfs, znode_t *dzp, char *name, boolean_t exact,
|
||||
zfs_match_find(zfs_sb_t *zsb, znode_t *dzp, char *name, boolean_t exact,
|
||||
boolean_t update, int *deflags, pathname_t *rpnp, uint64_t *zoid)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (zfsvfs->z_norm) {
|
||||
if (zsb->z_norm) {
|
||||
matchtype_t mt = MT_FIRST;
|
||||
boolean_t conflict = B_FALSE;
|
||||
size_t bufsz = 0;
|
||||
@@ -83,17 +82,19 @@ zfs_match_find(zfsvfs_t *zfsvfs, znode_t *dzp, char *name, boolean_t exact,
|
||||
* In the non-mixed case we only expect there would ever
|
||||
* be one match, but we need to use the normalizing lookup.
|
||||
*/
|
||||
error = zap_lookup_norm(zfsvfs->z_os, dzp->z_id, name, 8, 1,
|
||||
error = zap_lookup_norm(zsb->z_os, dzp->z_id, name, 8, 1,
|
||||
zoid, mt, buf, bufsz, &conflict);
|
||||
if (!error && deflags)
|
||||
*deflags = conflict ? ED_CASE_CONFLICT : 0;
|
||||
} else {
|
||||
error = zap_lookup(zfsvfs->z_os, dzp->z_id, name, 8, 1, zoid);
|
||||
error = zap_lookup(zsb->z_os, dzp->z_id, name, 8, 1, zoid);
|
||||
}
|
||||
*zoid = ZFS_DIRENT_OBJ(*zoid);
|
||||
|
||||
#ifdef HAVE_DNLC
|
||||
if (error == ENOENT && update)
|
||||
dnlc_update(ZTOV(dzp), name, DNLC_NO_VNODE);
|
||||
dnlc_update(ZTOI(dzp), name, DNLC_NO_VNODE);
|
||||
#endif /* HAVE_DNLC */
|
||||
|
||||
return (error);
|
||||
}
|
||||
@@ -137,12 +138,14 @@ int
|
||||
zfs_dirent_lock(zfs_dirlock_t **dlpp, znode_t *dzp, char *name, znode_t **zpp,
|
||||
int flag, int *direntflags, pathname_t *realpnp)
|
||||
{
|
||||
zfsvfs_t *zfsvfs = dzp->z_zfsvfs;
|
||||
zfs_sb_t *zsb = ZTOZSB(dzp);
|
||||
zfs_dirlock_t *dl;
|
||||
boolean_t update;
|
||||
boolean_t exact;
|
||||
uint64_t zoid;
|
||||
#ifdef HAVE_DNLC
|
||||
vnode_t *vp = NULL;
|
||||
#endif /* HAVE_DNLC */
|
||||
int error = 0;
|
||||
int cmpflags;
|
||||
|
||||
@@ -160,7 +163,7 @@ zfs_dirent_lock(zfs_dirlock_t **dlpp, znode_t *dzp, char *name, znode_t **zpp,
|
||||
/*
|
||||
* Case sensitivity and normalization preferences are set when
|
||||
* the file system is created. These are stored in the
|
||||
* zfsvfs->z_case and zfsvfs->z_norm fields. These choices
|
||||
* zsb->z_case and zsb->z_norm fields. These choices
|
||||
* affect what vnodes can be cached in the DNLC, how we
|
||||
* perform zap lookups, and the "width" of our dirlocks.
|
||||
*
|
||||
@@ -180,8 +183,8 @@ zfs_dirent_lock(zfs_dirlock_t **dlpp, znode_t *dzp, char *name, znode_t **zpp,
|
||||
* access.
|
||||
*/
|
||||
exact =
|
||||
((zfsvfs->z_case == ZFS_CASE_INSENSITIVE) && (flag & ZCIEXACT)) ||
|
||||
((zfsvfs->z_case == ZFS_CASE_MIXED) && !(flag & ZCILOOK));
|
||||
((zsb->z_case == ZFS_CASE_INSENSITIVE) && (flag & ZCIEXACT)) ||
|
||||
((zsb->z_case == ZFS_CASE_MIXED) && !(flag & ZCILOOK));
|
||||
|
||||
/*
|
||||
* Only look in or update the DNLC if we are looking for the
|
||||
@@ -193,9 +196,9 @@ zfs_dirent_lock(zfs_dirlock_t **dlpp, znode_t *dzp, char *name, znode_t **zpp,
|
||||
* Maybe can add TO-UPPERed version of name to dnlc in ci-only
|
||||
* case for performance improvement?
|
||||
*/
|
||||
update = !zfsvfs->z_norm ||
|
||||
((zfsvfs->z_case == ZFS_CASE_MIXED) &&
|
||||
!(zfsvfs->z_norm & ~U8_TEXTPREP_TOUPPER) && !(flag & ZCILOOK));
|
||||
update = !zsb->z_norm ||
|
||||
((zsb->z_case == ZFS_CASE_MIXED) &&
|
||||
!(zsb->z_norm & ~U8_TEXTPREP_TOUPPER) && !(flag & ZCILOOK));
|
||||
|
||||
/*
|
||||
* ZRENAMING indicates we are in a situation where we should
|
||||
@@ -208,7 +211,7 @@ zfs_dirent_lock(zfs_dirlock_t **dlpp, znode_t *dzp, char *name, znode_t **zpp,
|
||||
if (flag & ZRENAMING)
|
||||
cmpflags = 0;
|
||||
else
|
||||
cmpflags = zfsvfs->z_norm;
|
||||
cmpflags = zsb->z_norm;
|
||||
|
||||
/*
|
||||
* Wait until there are no locks on this name.
|
||||
@@ -288,29 +291,34 @@ zfs_dirent_lock(zfs_dirlock_t **dlpp, znode_t *dzp, char *name, znode_t **zpp,
|
||||
* See if there's an object by this name; if so, put a hold on it.
|
||||
*/
|
||||
if (flag & ZXATTR) {
|
||||
error = sa_lookup(dzp->z_sa_hdl, SA_ZPL_XATTR(zfsvfs), &zoid,
|
||||
error = sa_lookup(dzp->z_sa_hdl, SA_ZPL_XATTR(zsb), &zoid,
|
||||
sizeof (zoid));
|
||||
if (error == 0)
|
||||
error = (zoid == 0 ? ENOENT : 0);
|
||||
} else {
|
||||
#ifdef HAVE_DNLC
|
||||
if (update)
|
||||
vp = dnlc_lookup(ZTOV(dzp), name);
|
||||
vp = dnlc_lookup(ZTOI(dzp), name);
|
||||
if (vp == DNLC_NO_VNODE) {
|
||||
VN_RELE(vp);
|
||||
iput(vp);
|
||||
error = ENOENT;
|
||||
} else if (vp) {
|
||||
if (flag & ZNEW) {
|
||||
zfs_dirent_unlock(dl);
|
||||
VN_RELE(vp);
|
||||
iput(vp);
|
||||
return (EEXIST);
|
||||
}
|
||||
*dlpp = dl;
|
||||
*zpp = VTOZ(vp);
|
||||
return (0);
|
||||
} else {
|
||||
error = zfs_match_find(zfsvfs, dzp, name, exact,
|
||||
error = zfs_match_find(zsb, dzp, name, exact,
|
||||
update, direntflags, realpnp, &zoid);
|
||||
}
|
||||
#else
|
||||
error = zfs_match_find(zsb, dzp, name, exact,
|
||||
update, direntflags, realpnp, &zoid);
|
||||
#endif /* HAVE_DNLC */
|
||||
}
|
||||
if (error) {
|
||||
if (error != ENOENT || (flag & ZEXISTS)) {
|
||||
@@ -322,13 +330,15 @@ zfs_dirent_lock(zfs_dirlock_t **dlpp, znode_t *dzp, char *name, znode_t **zpp,
|
||||
zfs_dirent_unlock(dl);
|
||||
return (EEXIST);
|
||||
}
|
||||
error = zfs_zget(zfsvfs, zoid, zpp);
|
||||
error = zfs_zget(zsb, zoid, zpp);
|
||||
if (error) {
|
||||
zfs_dirent_unlock(dl);
|
||||
return (error);
|
||||
}
|
||||
#ifdef HAVE_DNLC
|
||||
if (!(flag & ZXATTR) && update)
|
||||
dnlc_update(ZTOV(dzp), name, ZTOV(*zpp));
|
||||
dnlc_update(ZTOI(dzp), name, ZTOI(*zpp));
|
||||
#endif /* HAVE_DNLC */
|
||||
}
|
||||
|
||||
*dlpp = dl;
|
||||
@@ -377,7 +387,7 @@ zfs_dirent_unlock(zfs_dirlock_t *dl)
|
||||
* special pseudo-directory.
|
||||
*/
|
||||
int
|
||||
zfs_dirlook(znode_t *dzp, char *name, vnode_t **vpp, int flags,
|
||||
zfs_dirlook(znode_t *dzp, char *name, struct inode **ipp, int flags,
|
||||
int *deflg, pathname_t *rpnp)
|
||||
{
|
||||
zfs_dirlock_t *dl;
|
||||
@@ -386,31 +396,35 @@ zfs_dirlook(znode_t *dzp, char *name, vnode_t **vpp, int flags,
|
||||
uint64_t parent;
|
||||
|
||||
if (name[0] == 0 || (name[0] == '.' && name[1] == 0)) {
|
||||
*vpp = ZTOV(dzp);
|
||||
VN_HOLD(*vpp);
|
||||
*ipp = ZTOI(dzp);
|
||||
igrab(*ipp);
|
||||
} else if (name[0] == '.' && name[1] == '.' && name[2] == 0) {
|
||||
zfsvfs_t *zfsvfs = dzp->z_zfsvfs;
|
||||
zfs_sb_t *zsb = ZTOZSB(dzp);
|
||||
|
||||
/*
|
||||
* If we are a snapshot mounted under .zfs, return
|
||||
* the vp for the snapshot directory.
|
||||
*/
|
||||
if ((error = sa_lookup(dzp->z_sa_hdl,
|
||||
SA_ZPL_PARENT(zfsvfs), &parent, sizeof (parent))) != 0)
|
||||
SA_ZPL_PARENT(zsb), &parent, sizeof (parent))) != 0)
|
||||
return (error);
|
||||
if (parent == dzp->z_id && zfsvfs->z_parent != zfsvfs) {
|
||||
error = zfsctl_root_lookup(zfsvfs->z_parent->z_ctldir,
|
||||
"snapshot", vpp, NULL, 0, NULL, kcred,
|
||||
#ifdef HAVE_SNAPSHOT
|
||||
if (parent == dzp->z_id && zsb->z_parent != zsb) {
|
||||
error = zfsctl_root_lookup(zsb->z_parent->z_ctldir,
|
||||
"snapshot", ipp, NULL, 0, NULL, kcred,
|
||||
NULL, NULL, NULL);
|
||||
return (error);
|
||||
}
|
||||
#endif /* HAVE_SNAPSHOT */
|
||||
rw_enter(&dzp->z_parent_lock, RW_READER);
|
||||
error = zfs_zget(zfsvfs, parent, &zp);
|
||||
error = zfs_zget(zsb, parent, &zp);
|
||||
if (error == 0)
|
||||
*vpp = ZTOV(zp);
|
||||
*ipp = ZTOI(zp);
|
||||
rw_exit(&dzp->z_parent_lock);
|
||||
#ifdef HAVE_SNAPSHOT
|
||||
} else if (zfs_has_ctldir(dzp) && strcmp(name, ZFS_CTLDIR_NAME) == 0) {
|
||||
*vpp = zfsctl_root(dzp);
|
||||
*ipp = zfsctl_root(dzp);
|
||||
#endif /* HAVE_SNAPSHOT */
|
||||
} else {
|
||||
int zf;
|
||||
|
||||
@@ -420,7 +434,7 @@ zfs_dirlook(znode_t *dzp, char *name, vnode_t **vpp, int flags,
|
||||
|
||||
error = zfs_dirent_lock(&dl, dzp, name, &zp, zf, deflg, rpnp);
|
||||
if (error == 0) {
|
||||
*vpp = ZTOV(zp);
|
||||
*ipp = ZTOI(zp);
|
||||
zfs_dirent_unlock(dl);
|
||||
dzp->z_zn_prefetch = B_TRUE; /* enable prefetching */
|
||||
}
|
||||
@@ -450,13 +464,13 @@ zfs_dirlook(znode_t *dzp, char *name, vnode_t **vpp, int flags,
|
||||
void
|
||||
zfs_unlinked_add(znode_t *zp, dmu_tx_t *tx)
|
||||
{
|
||||
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
|
||||
zfs_sb_t *zsb = ZTOZSB(zp);
|
||||
|
||||
ASSERT(zp->z_unlinked);
|
||||
ASSERT(zp->z_links == 0);
|
||||
|
||||
VERIFY3U(0, ==,
|
||||
zap_add_int(zfsvfs->z_os, zfsvfs->z_unlinkedobj, zp->z_id, tx));
|
||||
zap_add_int(zsb->z_os, zsb->z_unlinkedobj, zp->z_id, tx));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -464,7 +478,7 @@ zfs_unlinked_add(znode_t *zp, dmu_tx_t *tx)
|
||||
* (force) umounted the file system.
|
||||
*/
|
||||
void
|
||||
zfs_unlinked_drain(zfsvfs_t *zfsvfs)
|
||||
zfs_unlinked_drain(zfs_sb_t *zsb)
|
||||
{
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t zap;
|
||||
@@ -475,7 +489,7 @@ zfs_unlinked_drain(zfsvfs_t *zfsvfs)
|
||||
/*
|
||||
* Interate over the contents of the unlinked set.
|
||||
*/
|
||||
for (zap_cursor_init(&zc, zfsvfs->z_os, zfsvfs->z_unlinkedobj);
|
||||
for (zap_cursor_init(&zc, zsb->z_os, zsb->z_unlinkedobj);
|
||||
zap_cursor_retrieve(&zc, &zap) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
|
||||
@@ -483,8 +497,7 @@ zfs_unlinked_drain(zfsvfs_t *zfsvfs)
|
||||
* See what kind of object we have in list
|
||||
*/
|
||||
|
||||
error = dmu_object_info(zfsvfs->z_os,
|
||||
zap.za_first_integer, &doi);
|
||||
error = dmu_object_info(zsb->z_os, zap.za_first_integer, &doi);
|
||||
if (error != 0)
|
||||
continue;
|
||||
|
||||
@@ -494,7 +507,7 @@ zfs_unlinked_drain(zfsvfs_t *zfsvfs)
|
||||
* We need to re-mark these list entries for deletion,
|
||||
* so we pull them back into core and set zp->z_unlinked.
|
||||
*/
|
||||
error = zfs_zget(zfsvfs, zap.za_first_integer, &zp);
|
||||
error = zfs_zget(zsb, zap.za_first_integer, &zp);
|
||||
|
||||
/*
|
||||
* We may pick up znodes that are already marked for deletion.
|
||||
@@ -506,7 +519,7 @@ zfs_unlinked_drain(zfsvfs_t *zfsvfs)
|
||||
continue;
|
||||
|
||||
zp->z_unlinked = B_TRUE;
|
||||
VN_RELE(ZTOV(zp));
|
||||
iput(ZTOI(zp));
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
}
|
||||
@@ -529,35 +542,34 @@ zfs_purgedir(znode_t *dzp)
|
||||
zap_attribute_t zap;
|
||||
znode_t *xzp;
|
||||
dmu_tx_t *tx;
|
||||
zfsvfs_t *zfsvfs = dzp->z_zfsvfs;
|
||||
zfs_sb_t *zsb = ZTOZSB(dzp);
|
||||
zfs_dirlock_t dl;
|
||||
int skipped = 0;
|
||||
int error;
|
||||
|
||||
for (zap_cursor_init(&zc, zfsvfs->z_os, dzp->z_id);
|
||||
for (zap_cursor_init(&zc, zsb->z_os, dzp->z_id);
|
||||
(error = zap_cursor_retrieve(&zc, &zap)) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
error = zfs_zget(zfsvfs,
|
||||
error = zfs_zget(zsb,
|
||||
ZFS_DIRENT_OBJ(zap.za_first_integer), &xzp);
|
||||
if (error) {
|
||||
skipped += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
ASSERT((ZTOV(xzp)->v_type == VREG) ||
|
||||
(ZTOV(xzp)->v_type == VLNK));
|
||||
ASSERT(S_ISREG(ZTOI(xzp)->i_mode)||S_ISLNK(ZTOI(xzp)->i_mode));
|
||||
|
||||
tx = dmu_tx_create(zfsvfs->z_os);
|
||||
tx = dmu_tx_create(zsb->z_os);
|
||||
dmu_tx_hold_sa(tx, dzp->z_sa_hdl, B_FALSE);
|
||||
dmu_tx_hold_zap(tx, dzp->z_id, FALSE, zap.za_name);
|
||||
dmu_tx_hold_sa(tx, xzp->z_sa_hdl, B_FALSE);
|
||||
dmu_tx_hold_zap(tx, zfsvfs->z_unlinkedobj, FALSE, NULL);
|
||||
dmu_tx_hold_zap(tx, zsb->z_unlinkedobj, FALSE, NULL);
|
||||
/* Is this really needed ? */
|
||||
zfs_sa_upgrade_txholds(tx, xzp);
|
||||
error = dmu_tx_assign(tx, TXG_WAIT);
|
||||
if (error) {
|
||||
dmu_tx_abort(tx);
|
||||
VN_RELE(ZTOV(xzp));
|
||||
iput(ZTOI(xzp));
|
||||
skipped += 1;
|
||||
continue;
|
||||
}
|
||||
@@ -570,7 +582,7 @@ zfs_purgedir(znode_t *dzp)
|
||||
skipped += 1;
|
||||
dmu_tx_commit(tx);
|
||||
|
||||
VN_RELE(ZTOV(xzp));
|
||||
iput(ZTOI(xzp));
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
if (error != ENOENT)
|
||||
@@ -581,8 +593,8 @@ zfs_purgedir(znode_t *dzp)
|
||||
void
|
||||
zfs_rmnode(znode_t *zp)
|
||||
{
|
||||
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
|
||||
objset_t *os = zfsvfs->z_os;
|
||||
zfs_sb_t *zsb = ZTOZSB(zp);
|
||||
objset_t *os = zsb->z_os;
|
||||
znode_t *xzp = NULL;
|
||||
dmu_tx_t *tx;
|
||||
uint64_t acl_obj;
|
||||
@@ -590,19 +602,20 @@ zfs_rmnode(znode_t *zp)
|
||||
int error;
|
||||
|
||||
ASSERT(zp->z_links == 0);
|
||||
ASSERT(ZTOV(zp)->v_count == 0);
|
||||
ASSERT(atomic_read(&ZTOI(zp)->i_count) == 0);
|
||||
|
||||
/*
|
||||
* If this is an attribute directory, purge its contents.
|
||||
*/
|
||||
if (ZTOV(zp)->v_type == VDIR && (zp->z_pflags & ZFS_XATTR)) {
|
||||
if (S_ISDIR(ZTOI(zp)->i_mode) && (zp->z_pflags & ZFS_XATTR)) {
|
||||
if (zfs_purgedir(zp) != 0) {
|
||||
/*
|
||||
* Not enough space to delete some xattrs.
|
||||
* Leave it in the unlinked set.
|
||||
*/
|
||||
zfs_znode_dmu_fini(zp);
|
||||
zfs_znode_free(zp);
|
||||
zfs_inode_destroy(ZTOI(zp));
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -616,7 +629,7 @@ zfs_rmnode(znode_t *zp)
|
||||
* Not enough space. Leave the file in the unlinked set.
|
||||
*/
|
||||
zfs_znode_dmu_fini(zp);
|
||||
zfs_znode_free(zp);
|
||||
zfs_inode_destroy(ZTOI(zp));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -624,10 +637,10 @@ zfs_rmnode(znode_t *zp)
|
||||
* If the file has extended attributes, we're going to unlink
|
||||
* the xattr dir.
|
||||
*/
|
||||
error = sa_lookup(zp->z_sa_hdl, SA_ZPL_XATTR(zfsvfs),
|
||||
error = sa_lookup(zp->z_sa_hdl, SA_ZPL_XATTR(zsb),
|
||||
&xattr_obj, sizeof (xattr_obj));
|
||||
if (error == 0 && xattr_obj) {
|
||||
error = zfs_zget(zfsvfs, xattr_obj, &xzp);
|
||||
error = zfs_zget(zsb, xattr_obj, &xzp);
|
||||
ASSERT(error == 0);
|
||||
}
|
||||
|
||||
@@ -638,9 +651,9 @@ zfs_rmnode(znode_t *zp)
|
||||
*/
|
||||
tx = dmu_tx_create(os);
|
||||
dmu_tx_hold_free(tx, zp->z_id, 0, DMU_OBJECT_END);
|
||||
dmu_tx_hold_zap(tx, zfsvfs->z_unlinkedobj, FALSE, NULL);
|
||||
dmu_tx_hold_zap(tx, zsb->z_unlinkedobj, FALSE, NULL);
|
||||
if (xzp) {
|
||||
dmu_tx_hold_zap(tx, zfsvfs->z_unlinkedobj, TRUE, NULL);
|
||||
dmu_tx_hold_zap(tx, zsb->z_unlinkedobj, TRUE, NULL);
|
||||
dmu_tx_hold_sa(tx, xzp->z_sa_hdl, B_FALSE);
|
||||
}
|
||||
if (acl_obj)
|
||||
@@ -656,7 +669,7 @@ zfs_rmnode(znode_t *zp)
|
||||
*/
|
||||
dmu_tx_abort(tx);
|
||||
zfs_znode_dmu_fini(zp);
|
||||
zfs_znode_free(zp);
|
||||
zfs_inode_destroy(ZTOI(zp));
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -665,7 +678,7 @@ zfs_rmnode(znode_t *zp)
|
||||
mutex_enter(&xzp->z_lock);
|
||||
xzp->z_unlinked = B_TRUE; /* mark xzp for deletion */
|
||||
xzp->z_links = 0; /* no more links to it */
|
||||
VERIFY(0 == sa_update(xzp->z_sa_hdl, SA_ZPL_LINKS(zfsvfs),
|
||||
VERIFY(0 == sa_update(xzp->z_sa_hdl, SA_ZPL_LINKS(zsb),
|
||||
&xzp->z_links, sizeof (xzp->z_links), tx));
|
||||
mutex_exit(&xzp->z_lock);
|
||||
zfs_unlinked_add(xzp, tx);
|
||||
@@ -673,14 +686,14 @@ zfs_rmnode(znode_t *zp)
|
||||
|
||||
/* Remove this znode from the unlinked set */
|
||||
VERIFY3U(0, ==,
|
||||
zap_remove_int(zfsvfs->z_os, zfsvfs->z_unlinkedobj, zp->z_id, tx));
|
||||
zap_remove_int(zsb->z_os, zsb->z_unlinkedobj, zp->z_id, tx));
|
||||
|
||||
zfs_znode_delete(zp, tx);
|
||||
|
||||
dmu_tx_commit(tx);
|
||||
out:
|
||||
if (xzp)
|
||||
VN_RELE(ZTOV(xzp));
|
||||
iput(ZTOI(xzp));
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
@@ -688,7 +701,7 @@ zfs_dirent(znode_t *zp, uint64_t mode)
|
||||
{
|
||||
uint64_t de = zp->z_id;
|
||||
|
||||
if (zp->z_zfsvfs->z_version >= ZPL_VERSION_DIRENT_TYPE)
|
||||
if (ZTOZSB(zp)->z_version >= ZPL_VERSION_DIRENT_TYPE)
|
||||
de |= IFTODT(mode) << 60;
|
||||
return (de);
|
||||
}
|
||||
@@ -700,10 +713,9 @@ int
|
||||
zfs_link_create(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag)
|
||||
{
|
||||
znode_t *dzp = dl->dl_dzp;
|
||||
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
|
||||
vnode_t *vp = ZTOV(zp);
|
||||
zfs_sb_t *zsb = ZTOZSB(zp);
|
||||
uint64_t value;
|
||||
int zp_is_dir = (vp->v_type == VDIR);
|
||||
int zp_is_dir = S_ISDIR(ZTOI(zp)->i_mode);
|
||||
sa_bulk_attr_t bulk[5];
|
||||
uint64_t mtime[2], ctime[2];
|
||||
int count = 0;
|
||||
@@ -718,17 +730,17 @@ zfs_link_create(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag)
|
||||
return (ENOENT);
|
||||
}
|
||||
zp->z_links++;
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zfsvfs), NULL,
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zsb), NULL,
|
||||
&zp->z_links, sizeof (zp->z_links));
|
||||
|
||||
}
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_PARENT(zfsvfs), NULL,
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_PARENT(zsb), NULL,
|
||||
&dzp->z_id, sizeof (dzp->z_id));
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs), NULL,
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb), NULL,
|
||||
&zp->z_pflags, sizeof (zp->z_pflags));
|
||||
|
||||
if (!(flag & ZNEW)) {
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL,
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb), NULL,
|
||||
ctime, sizeof (ctime));
|
||||
zfs_tstamp_update_setup(zp, STATE_CHANGED, mtime,
|
||||
ctime, B_TRUE);
|
||||
@@ -742,15 +754,15 @@ zfs_link_create(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag)
|
||||
dzp->z_size++;
|
||||
dzp->z_links += zp_is_dir;
|
||||
count = 0;
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zfsvfs), NULL,
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zsb), NULL,
|
||||
&dzp->z_size, sizeof (dzp->z_size));
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zfsvfs), NULL,
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zsb), NULL,
|
||||
&dzp->z_links, sizeof (dzp->z_links));
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zfsvfs), NULL,
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zsb), NULL,
|
||||
mtime, sizeof (mtime));
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL,
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb), NULL,
|
||||
ctime, sizeof (ctime));
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs), NULL,
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb), NULL,
|
||||
&dzp->z_pflags, sizeof (dzp->z_pflags));
|
||||
zfs_tstamp_update_setup(dzp, CONTENT_MODIFIED, mtime, ctime, B_TRUE);
|
||||
error = sa_bulk_update(dzp->z_sa_hdl, bulk, count, tx);
|
||||
@@ -758,11 +770,13 @@ zfs_link_create(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag)
|
||||
mutex_exit(&dzp->z_lock);
|
||||
|
||||
value = zfs_dirent(zp, zp->z_mode);
|
||||
error = zap_add(zp->z_zfsvfs->z_os, dzp->z_id, dl->dl_name,
|
||||
error = zap_add(ZTOZSB(zp)->z_os, dzp->z_id, dl->dl_name,
|
||||
8, 1, &value, tx);
|
||||
ASSERT(error == 0);
|
||||
|
||||
dnlc_update(ZTOV(dzp), dl->dl_name, vp);
|
||||
#ifdef HAVE_DNLC
|
||||
dnlc_update(ZTOI(dzp), dl->dl_name, vp);
|
||||
#endif /* HAVE_DNLC */
|
||||
|
||||
return (0);
|
||||
}
|
||||
@@ -773,18 +787,18 @@ zfs_dropname(zfs_dirlock_t *dl, znode_t *zp, znode_t *dzp, dmu_tx_t *tx,
|
||||
{
|
||||
int error;
|
||||
|
||||
if (zp->z_zfsvfs->z_norm) {
|
||||
if (((zp->z_zfsvfs->z_case == ZFS_CASE_INSENSITIVE) &&
|
||||
if (ZTOZSB(zp)->z_norm) {
|
||||
if (((ZTOZSB(zp)->z_case == ZFS_CASE_INSENSITIVE) &&
|
||||
(flag & ZCIEXACT)) ||
|
||||
((zp->z_zfsvfs->z_case == ZFS_CASE_MIXED) &&
|
||||
((ZTOZSB(zp)->z_case == ZFS_CASE_MIXED) &&
|
||||
!(flag & ZCILOOK)))
|
||||
error = zap_remove_norm(zp->z_zfsvfs->z_os,
|
||||
error = zap_remove_norm(ZTOZSB(zp)->z_os,
|
||||
dzp->z_id, dl->dl_name, MT_EXACT, tx);
|
||||
else
|
||||
error = zap_remove_norm(zp->z_zfsvfs->z_os,
|
||||
error = zap_remove_norm(ZTOZSB(zp)->z_os,
|
||||
dzp->z_id, dl->dl_name, MT_FIRST, tx);
|
||||
} else {
|
||||
error = zap_remove(zp->z_zfsvfs->z_os,
|
||||
error = zap_remove(ZTOZSB(zp)->z_os,
|
||||
dzp->z_id, dl->dl_name, tx);
|
||||
}
|
||||
|
||||
@@ -803,31 +817,23 @@ zfs_link_destroy(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag,
|
||||
boolean_t *unlinkedp)
|
||||
{
|
||||
znode_t *dzp = dl->dl_dzp;
|
||||
zfsvfs_t *zfsvfs = dzp->z_zfsvfs;
|
||||
vnode_t *vp = ZTOV(zp);
|
||||
int zp_is_dir = (vp->v_type == VDIR);
|
||||
zfs_sb_t *zsb = ZTOZSB(dzp);
|
||||
int zp_is_dir = S_ISDIR(ZTOI(zp)->i_mode);
|
||||
boolean_t unlinked = B_FALSE;
|
||||
sa_bulk_attr_t bulk[5];
|
||||
uint64_t mtime[2], ctime[2];
|
||||
int count = 0;
|
||||
int error;
|
||||
|
||||
dnlc_remove(ZTOV(dzp), dl->dl_name);
|
||||
#ifdef HAVE_DNLC
|
||||
dnlc_remove(ZTOI(dzp), dl->dl_name);
|
||||
#endif /* HAVE_DNLC */
|
||||
|
||||
if (!(flag & ZRENAMING)) {
|
||||
if (vn_vfswlock(vp)) /* prevent new mounts on zp */
|
||||
return (EBUSY);
|
||||
|
||||
if (vn_ismntpt(vp)) { /* don't remove mount point */
|
||||
vn_vfsunlock(vp);
|
||||
return (EBUSY);
|
||||
}
|
||||
|
||||
mutex_enter(&zp->z_lock);
|
||||
|
||||
if (zp_is_dir && !zfs_dirempty(zp)) {
|
||||
mutex_exit(&zp->z_lock);
|
||||
vn_vfsunlock(vp);
|
||||
return (EEXIST);
|
||||
}
|
||||
|
||||
@@ -839,16 +845,13 @@ zfs_link_destroy(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag,
|
||||
error = zfs_dropname(dl, zp, dzp, tx, flag);
|
||||
if (error != 0) {
|
||||
mutex_exit(&zp->z_lock);
|
||||
vn_vfsunlock(vp);
|
||||
return (error);
|
||||
}
|
||||
|
||||
if (zp->z_links <= zp_is_dir) {
|
||||
zfs_panic_recover("zfs: link count on %s is %u, "
|
||||
"should be at least %u",
|
||||
zp->z_vnode->v_path ? zp->z_vnode->v_path :
|
||||
"<unknown>", (int)zp->z_links,
|
||||
zp_is_dir + 1);
|
||||
zfs_panic_recover("zfs: link count on %lu is %u, "
|
||||
"should be at least %u", zp->z_id,
|
||||
(int)zp->z_links, zp_is_dir + 1);
|
||||
zp->z_links = zp_is_dir + 1;
|
||||
}
|
||||
if (--zp->z_links == zp_is_dir) {
|
||||
@@ -856,20 +859,19 @@ zfs_link_destroy(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag,
|
||||
zp->z_links = 0;
|
||||
unlinked = B_TRUE;
|
||||
} else {
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs),
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb),
|
||||
NULL, &ctime, sizeof (ctime));
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs),
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb),
|
||||
NULL, &zp->z_pflags, sizeof (zp->z_pflags));
|
||||
zfs_tstamp_update_setup(zp, STATE_CHANGED, mtime, ctime,
|
||||
B_TRUE);
|
||||
}
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zfsvfs),
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zsb),
|
||||
NULL, &zp->z_links, sizeof (zp->z_links));
|
||||
error = sa_bulk_update(zp->z_sa_hdl, bulk, count, tx);
|
||||
count = 0;
|
||||
ASSERT(error == 0);
|
||||
mutex_exit(&zp->z_lock);
|
||||
vn_vfsunlock(vp);
|
||||
} else {
|
||||
error = zfs_dropname(dl, zp, dzp, tx, flag);
|
||||
if (error != 0)
|
||||
@@ -879,15 +881,15 @@ zfs_link_destroy(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag,
|
||||
mutex_enter(&dzp->z_lock);
|
||||
dzp->z_size--; /* one dirent removed */
|
||||
dzp->z_links -= zp_is_dir; /* ".." link from zp */
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zfsvfs),
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zsb),
|
||||
NULL, &dzp->z_links, sizeof (dzp->z_links));
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zfsvfs),
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zsb),
|
||||
NULL, &dzp->z_size, sizeof (dzp->z_size));
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs),
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb),
|
||||
NULL, ctime, sizeof (ctime));
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zfsvfs),
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zsb),
|
||||
NULL, mtime, sizeof (mtime));
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs),
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb),
|
||||
NULL, &dzp->z_pflags, sizeof (dzp->z_pflags));
|
||||
zfs_tstamp_update_setup(dzp, CONTENT_MODIFIED, mtime, ctime, B_TRUE);
|
||||
error = sa_bulk_update(dzp->z_sa_hdl, bulk, count, tx);
|
||||
@@ -914,38 +916,40 @@ zfs_dirempty(znode_t *dzp)
|
||||
}
|
||||
|
||||
int
|
||||
zfs_make_xattrdir(znode_t *zp, vattr_t *vap, vnode_t **xvpp, cred_t *cr)
|
||||
zfs_make_xattrdir(znode_t *zp, vattr_t *vap, struct inode **xipp, cred_t *cr)
|
||||
{
|
||||
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
|
||||
zfs_sb_t *zsb = ZTOZSB(zp);
|
||||
znode_t *xzp;
|
||||
dmu_tx_t *tx;
|
||||
int error;
|
||||
zfs_acl_ids_t acl_ids;
|
||||
boolean_t fuid_dirtied;
|
||||
#ifdef DEBUG
|
||||
uint64_t parent;
|
||||
#endif
|
||||
|
||||
*xvpp = NULL;
|
||||
*xipp = NULL;
|
||||
|
||||
if (error = zfs_zaccess(zp, ACE_WRITE_NAMED_ATTRS, 0, B_FALSE, cr))
|
||||
if ((error = zfs_zaccess(zp, ACE_WRITE_NAMED_ATTRS, 0, B_FALSE, cr)))
|
||||
return (error);
|
||||
|
||||
if ((error = zfs_acl_ids_create(zp, IS_XATTR, vap, cr, NULL,
|
||||
&acl_ids)) != 0)
|
||||
return (error);
|
||||
if (zfs_acl_ids_overquota(zfsvfs, &acl_ids)) {
|
||||
if (zfs_acl_ids_overquota(zsb, &acl_ids)) {
|
||||
zfs_acl_ids_free(&acl_ids);
|
||||
return (EDQUOT);
|
||||
}
|
||||
|
||||
top:
|
||||
tx = dmu_tx_create(zfsvfs->z_os);
|
||||
tx = dmu_tx_create(zsb->z_os);
|
||||
dmu_tx_hold_sa_create(tx, acl_ids.z_aclp->z_acl_bytes +
|
||||
ZFS_SA_BASE_ATTR_SIZE);
|
||||
dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_TRUE);
|
||||
dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, FALSE, NULL);
|
||||
fuid_dirtied = zfsvfs->z_fuid_dirty;
|
||||
fuid_dirtied = zsb->z_fuid_dirty;
|
||||
if (fuid_dirtied)
|
||||
zfs_fuid_txhold(zfsvfs, tx);
|
||||
zfs_fuid_txhold(zsb, tx);
|
||||
error = dmu_tx_assign(tx, TXG_NOWAIT);
|
||||
if (error) {
|
||||
if (error == ERESTART) {
|
||||
@@ -960,24 +964,24 @@ top:
|
||||
zfs_mknode(zp, vap, tx, cr, IS_XATTR, &xzp, &acl_ids);
|
||||
|
||||
if (fuid_dirtied)
|
||||
zfs_fuid_sync(zfsvfs, tx);
|
||||
zfs_fuid_sync(zsb, tx);
|
||||
|
||||
#ifdef DEBUG
|
||||
error = sa_lookup(xzp->z_sa_hdl, SA_ZPL_PARENT(zfsvfs),
|
||||
error = sa_lookup(xzp->z_sa_hdl, SA_ZPL_PARENT(zsb),
|
||||
&parent, sizeof (parent));
|
||||
ASSERT(error == 0 && parent == zp->z_id);
|
||||
#endif
|
||||
|
||||
VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_XATTR(zfsvfs), &xzp->z_id,
|
||||
VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_XATTR(zsb), &xzp->z_id,
|
||||
sizeof (xzp->z_id), tx));
|
||||
|
||||
(void) zfs_log_create(zfsvfs->z_log, tx, TX_MKXATTR, zp,
|
||||
(void) zfs_log_create(zsb->z_log, tx, TX_MKXATTR, zp,
|
||||
xzp, "", NULL, acl_ids.z_fuidp, vap);
|
||||
|
||||
zfs_acl_ids_free(&acl_ids);
|
||||
dmu_tx_commit(tx);
|
||||
|
||||
*xvpp = ZTOV(xzp);
|
||||
*xipp = ZTOI(xzp);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@@ -990,15 +994,15 @@ top:
|
||||
* cr - credentials of caller
|
||||
* flags - flags from the VOP_LOOKUP call
|
||||
*
|
||||
* OUT: xzpp - pointer to extended attribute znode
|
||||
* OUT: xipp - pointer to extended attribute znode
|
||||
*
|
||||
* RETURN: 0 on success
|
||||
* error number on failure
|
||||
*/
|
||||
int
|
||||
zfs_get_xattrdir(znode_t *zp, vnode_t **xvpp, cred_t *cr, int flags)
|
||||
zfs_get_xattrdir(znode_t *zp, struct inode **xipp, cred_t *cr, int flags)
|
||||
{
|
||||
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
|
||||
zfs_sb_t *zsb = ZTOZSB(zp);
|
||||
znode_t *xzp;
|
||||
zfs_dirlock_t *dl;
|
||||
vattr_t va;
|
||||
@@ -1009,18 +1013,17 @@ top:
|
||||
return (error);
|
||||
|
||||
if (xzp != NULL) {
|
||||
*xvpp = ZTOV(xzp);
|
||||
*xipp = ZTOI(xzp);
|
||||
zfs_dirent_unlock(dl);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
if (!(flags & CREATE_XATTR_DIR)) {
|
||||
zfs_dirent_unlock(dl);
|
||||
return (ENOENT);
|
||||
}
|
||||
|
||||
if (zfsvfs->z_vfs->vfs_flag & VFS_RDONLY) {
|
||||
if (zsb->z_vfs->mnt_flags & MNT_READONLY) {
|
||||
zfs_dirent_unlock(dl);
|
||||
return (EROFS);
|
||||
}
|
||||
@@ -1035,12 +1038,11 @@ top:
|
||||
* Once in a directory the ability to read/write attributes
|
||||
* is controlled by the permissions on the attribute file.
|
||||
*/
|
||||
va.va_mask = AT_TYPE | AT_MODE | AT_UID | AT_GID;
|
||||
va.va_type = VDIR;
|
||||
va.va_mask = ATTR_MODE | ATTR_UID | ATTR_GID;
|
||||
va.va_mode = S_IFDIR | S_ISVTX | 0777;
|
||||
zfs_fuid_map_ids(zp, cr, &va.va_uid, &va.va_gid);
|
||||
|
||||
error = zfs_make_xattrdir(zp, &va, xvpp, cr);
|
||||
error = zfs_make_xattrdir(zp, &va, xipp, cr);
|
||||
zfs_dirent_unlock(dl);
|
||||
|
||||
if (error == ERESTART) {
|
||||
@@ -1067,25 +1069,24 @@ top:
|
||||
int
|
||||
zfs_sticky_remove_access(znode_t *zdp, znode_t *zp, cred_t *cr)
|
||||
{
|
||||
uid_t uid;
|
||||
uid_t uid;
|
||||
uid_t downer;
|
||||
uid_t fowner;
|
||||
zfsvfs_t *zfsvfs = zdp->z_zfsvfs;
|
||||
zfs_sb_t *zsb = ZTOZSB(zdp);
|
||||
|
||||
if (zdp->z_zfsvfs->z_replay)
|
||||
if (zsb->z_replay)
|
||||
return (0);
|
||||
|
||||
if ((zdp->z_mode & S_ISVTX) == 0)
|
||||
return (0);
|
||||
|
||||
downer = zfs_fuid_map_id(zfsvfs, zdp->z_uid, cr, ZFS_OWNER);
|
||||
fowner = zfs_fuid_map_id(zfsvfs, zp->z_uid, cr, ZFS_OWNER);
|
||||
downer = zfs_fuid_map_id(zsb, zdp->z_uid, cr, ZFS_OWNER);
|
||||
fowner = zfs_fuid_map_id(zsb, zp->z_uid, cr, ZFS_OWNER);
|
||||
|
||||
if ((uid = crgetuid(cr)) == downer || uid == fowner ||
|
||||
(ZTOV(zp)->v_type == VREG &&
|
||||
(S_ISDIR(ZTOI(zp)->i_mode) &&
|
||||
zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr) == 0))
|
||||
return (0);
|
||||
else
|
||||
return (secpolicy_vnode_remove(cr));
|
||||
}
|
||||
#endif /* HAVE_ZPL */
|
||||
|
||||
+85
-86
@@ -46,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.
|
||||
*
|
||||
*/
|
||||
@@ -196,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;
|
||||
@@ -234,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);
|
||||
@@ -275,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;
|
||||
@@ -319,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;
|
||||
}
|
||||
@@ -343,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);
|
||||
}
|
||||
}
|
||||
@@ -363,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 || zfsvfs->z_fuid_dirty)
|
||||
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);
|
||||
@@ -388,12 +387,12 @@ 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_uid, cr, ZFS_OWNER);
|
||||
*gidp = zfs_fuid_map_id(zp->z_zfsvfs, zp->z_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
|
||||
@@ -404,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) {
|
||||
@@ -499,13 +498,13 @@ zfs_fuid_node_add(zfs_fuid_info_t **fuidpp, const char *domain, uint32_t rid,
|
||||
* 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;
|
||||
|
||||
@@ -513,7 +512,7 @@ zfs_fuid_create_cred(zfsvfs_t *zfsvfs, zfs_fuid_type_t type,
|
||||
|
||||
ksid = crgetsid(cr, (type == ZFS_OWNER) ? KSID_OWNER : KSID_GROUP);
|
||||
|
||||
if (!zfsvfs->z_use_fuids || (ksid == NULL)) {
|
||||
if (!zsb->z_use_fuids || (ksid == NULL)) {
|
||||
id = (type == ZFS_OWNER) ? crgetuid(cr) : crgetgid(cr);
|
||||
|
||||
if (IS_EPHEMERAL(id))
|
||||
@@ -536,7 +535,7 @@ zfs_fuid_create_cred(zfsvfs_t *zfsvfs, zfs_fuid_type_t type,
|
||||
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);
|
||||
|
||||
@@ -554,10 +553,10 @@ 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
|
||||
@@ -578,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
|
||||
@@ -629,9 +628,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) {
|
||||
@@ -648,15 +647,15 @@ zfs_fuid_create(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr,
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -710,7 +709,7 @@ 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);
|
||||
@@ -718,7 +717,7 @@ zfs_groupmember(zfsvfs_t *zfsvfs, uint64_t id, cred_t *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);
|
||||
@@ -734,7 +733,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,
|
||||
@@ -752,7 +751,7 @@ 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);
|
||||
@@ -760,17 +759,17 @@ zfs_groupmember(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr)
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
+79
-126
@@ -432,7 +432,7 @@ zfs_set_slabel_policy(const char *name, char *strval, cred_t *cr)
|
||||
/*
|
||||
* If the existing dataset label is nondefault, check if the
|
||||
* dataset is mounted (label cannot be changed while mounted).
|
||||
* Get the zfsvfs; if there isn't one, then the dataset isn't
|
||||
* Get the zfs_sb_t; if there isn't one, then the dataset isn't
|
||||
* mounted (or isn't a dataset, doesn't exist, ...).
|
||||
*/
|
||||
if (strcasecmp(ds_hexsl, ZFS_MLSLABEL_DEFAULT) != 0) {
|
||||
@@ -849,20 +849,6 @@ zfs_secpolicy_create(zfs_cmd_t *zc, cred_t *cr)
|
||||
return (error);
|
||||
}
|
||||
|
||||
#ifdef HAVE_ZPL
|
||||
static int
|
||||
zfs_secpolicy_umount(zfs_cmd_t *zc, cred_t *cr)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = secpolicy_fs_unmount(cr, NULL);
|
||||
if (error) {
|
||||
error = dsl_deleg_access(zc->zc_name, ZFS_DELEG_PERM_MOUNT, cr);
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
#endif /* HAVE_ZPL */
|
||||
|
||||
/*
|
||||
* Policy for pool operations - create/destroy pools, add vdevs, etc. Requires
|
||||
* SYS_CONFIG privilege, which is not available in a local zone.
|
||||
@@ -1105,9 +1091,8 @@ put_nvlist(zfs_cmd_t *zc, nvlist_t *nvl)
|
||||
return (error);
|
||||
}
|
||||
|
||||
#ifdef HAVE_ZPL
|
||||
static int
|
||||
getzfsvfs(const char *dsname, zfsvfs_t **zfvp)
|
||||
get_zfs_sb(const char *dsname, zfs_sb_t **zsbp)
|
||||
{
|
||||
objset_t *os;
|
||||
int error;
|
||||
@@ -1121,9 +1106,9 @@ getzfsvfs(const char *dsname, zfsvfs_t **zfvp)
|
||||
}
|
||||
|
||||
mutex_enter(&os->os_user_ptr_lock);
|
||||
*zfvp = dmu_objset_get_user(os);
|
||||
if (*zfvp) {
|
||||
VFS_HOLD((*zfvp)->z_vfs);
|
||||
*zsbp = dmu_objset_get_user(os);
|
||||
if (*zsbp) {
|
||||
mntget((*zsbp)->z_vfs);
|
||||
} else {
|
||||
error = ESRCH;
|
||||
}
|
||||
@@ -1131,52 +1116,45 @@ getzfsvfs(const char *dsname, zfsvfs_t **zfvp)
|
||||
dmu_objset_rele(os, FTAG);
|
||||
return (error);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Find a zfsvfs_t for a mounted filesystem, or create our own, in which
|
||||
* Find a zfs_sb_t for a mounted filesystem, or create our own, in which
|
||||
* case its z_vfs will be NULL, and it will be opened as the owner.
|
||||
*/
|
||||
static int
|
||||
zfsvfs_hold(const char *name, void *tag, zfsvfs_t **zfvp, boolean_t writer)
|
||||
zfs_sb_hold(const char *name, void *tag, zfs_sb_t **zsbp, boolean_t writer)
|
||||
{
|
||||
#ifdef HAVE_ZPL
|
||||
int error = 0;
|
||||
|
||||
if (getzfsvfs(name, zfvp) != 0)
|
||||
error = zfsvfs_create(name, zfvp);
|
||||
if (get_zfs_sb(name, zsbp) != 0)
|
||||
error = zfs_sb_create(name, zsbp);
|
||||
if (error == 0) {
|
||||
rrw_enter(&(*zfvp)->z_teardown_lock, (writer) ? RW_WRITER :
|
||||
rrw_enter(&(*zsbp)->z_teardown_lock, (writer) ? RW_WRITER :
|
||||
RW_READER, tag);
|
||||
if ((*zfvp)->z_unmounted) {
|
||||
if ((*zsbp)->z_unmounted) {
|
||||
/*
|
||||
* XXX we could probably try again, since the unmounting
|
||||
* thread should be just about to disassociate the
|
||||
* objset from the zfsvfs.
|
||||
*/
|
||||
rrw_exit(&(*zfvp)->z_teardown_lock, tag);
|
||||
rrw_exit(&(*zsbp)->z_teardown_lock, tag);
|
||||
return (EBUSY);
|
||||
}
|
||||
}
|
||||
return (error);
|
||||
#else
|
||||
return ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
zfsvfs_rele(zfsvfs_t *zfsvfs, void *tag)
|
||||
zfs_sb_rele(zfs_sb_t *zsb, void *tag)
|
||||
{
|
||||
#ifdef HAVE_ZPL
|
||||
rrw_exit(&zfsvfs->z_teardown_lock, tag);
|
||||
rrw_exit(&zsb->z_teardown_lock, tag);
|
||||
|
||||
if (zfsvfs->z_vfs) {
|
||||
VFS_RELE(zfsvfs->z_vfs);
|
||||
if (zsb->z_vfs) {
|
||||
mntput(zsb->z_vfs);
|
||||
} else {
|
||||
dmu_objset_disown(zfsvfs->z_os, zfsvfs);
|
||||
zfsvfs_free(zfsvfs);
|
||||
dmu_objset_disown(zsb->z_os, zsb);
|
||||
zfs_sb_free(zsb);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -2086,7 +2064,6 @@ top:
|
||||
static int
|
||||
zfs_prop_set_userquota(const char *dsname, nvpair_t *pair)
|
||||
{
|
||||
#ifdef HAVE_ZPL
|
||||
const char *propname = nvpair_name(pair);
|
||||
uint64_t *valary;
|
||||
unsigned int vallen;
|
||||
@@ -2095,7 +2072,7 @@ zfs_prop_set_userquota(const char *dsname, nvpair_t *pair)
|
||||
zfs_userquota_prop_t type;
|
||||
uint64_t rid;
|
||||
uint64_t quota;
|
||||
zfsvfs_t *zfsvfs;
|
||||
zfs_sb_t *zsb;
|
||||
int err;
|
||||
|
||||
if (nvpair_type(pair) == DATA_TYPE_NVLIST) {
|
||||
@@ -2120,16 +2097,13 @@ zfs_prop_set_userquota(const char *dsname, nvpair_t *pair)
|
||||
rid = valary[1];
|
||||
quota = valary[2];
|
||||
|
||||
err = zfsvfs_hold(dsname, FTAG, &zfsvfs, B_FALSE);
|
||||
err = zfs_sb_hold(dsname, FTAG, &zsb, B_FALSE);
|
||||
if (err == 0) {
|
||||
err = zfs_set_userquota(zfsvfs, type, domain, rid, quota);
|
||||
zfsvfs_rele(zfsvfs, FTAG);
|
||||
err = zfs_set_userquota(zsb, type, domain, rid, quota);
|
||||
zfs_sb_rele(zsb, FTAG);
|
||||
}
|
||||
|
||||
return (err);
|
||||
#else
|
||||
return ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2185,15 +2159,13 @@ zfs_prop_set_special(const char *dsname, zprop_source_t source,
|
||||
break;
|
||||
case ZFS_PROP_VERSION:
|
||||
{
|
||||
zfsvfs_t *zfsvfs;
|
||||
zfs_sb_t *zsb;
|
||||
|
||||
if ((err = zfsvfs_hold(dsname, FTAG, &zfsvfs, B_TRUE)) != 0)
|
||||
if ((err = zfs_sb_hold(dsname, FTAG, &zsb, B_TRUE)) != 0)
|
||||
break;
|
||||
|
||||
#ifdef HAVE_ZPL
|
||||
err = zfs_set_version(zfsvfs, intval);
|
||||
#endif
|
||||
zfsvfs_rele(zfsvfs, FTAG);
|
||||
err = zfs_set_version(zsb, intval);
|
||||
zfs_sb_rele(zsb, FTAG);
|
||||
|
||||
if (err == 0 && intval >= ZPL_VERSION_USERSPACE) {
|
||||
zfs_cmd_t *zc;
|
||||
@@ -2748,7 +2720,7 @@ zfs_ioc_get_fsacl(zfs_cmd_t *zc)
|
||||
return (error);
|
||||
}
|
||||
|
||||
#ifdef HAVE_ZPL
|
||||
#ifdef HAVE_SNAPSHOT
|
||||
/*
|
||||
* Search the vfs list for a specified resource. Returns a pointer to it
|
||||
* or NULL if no suitable entry is found. The caller of this routine
|
||||
@@ -2764,7 +2736,7 @@ zfs_get_vfs(const char *resource)
|
||||
vfsp = rootvfs;
|
||||
do {
|
||||
if (strcmp(refstr_value(vfsp->vfs_resource), resource) == 0) {
|
||||
VFS_HOLD(vfsp);
|
||||
mntget(vfsp);
|
||||
vfs_found = vfsp;
|
||||
break;
|
||||
}
|
||||
@@ -2773,7 +2745,7 @@ zfs_get_vfs(const char *resource)
|
||||
vfs_list_unlock();
|
||||
return (vfs_found);
|
||||
}
|
||||
#endif /* HAVE_ZPL */
|
||||
#endif /* HAVE_SNAPSHOT */
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
@@ -3128,7 +3100,7 @@ out:
|
||||
int
|
||||
zfs_unmount_snap(const char *name, void *arg)
|
||||
{
|
||||
#ifdef HAVE_ZPL
|
||||
#ifdef HAVE_SNAPSHOT
|
||||
vfs_t *vfsp = NULL;
|
||||
|
||||
if (arg) {
|
||||
@@ -3148,14 +3120,14 @@ zfs_unmount_snap(const char *name, void *arg)
|
||||
int err;
|
||||
|
||||
if ((err = vn_vfswlock(vfsp->vfs_vnodecovered)) != 0) {
|
||||
VFS_RELE(vfsp);
|
||||
mntput(vfsp);
|
||||
return (err);
|
||||
}
|
||||
VFS_RELE(vfsp);
|
||||
mntput(vfsp);
|
||||
if ((err = dounmount(vfsp, flag, kcred)) != 0)
|
||||
return (err);
|
||||
}
|
||||
#endif /* HAVE_ZPL */
|
||||
#endif /* HAVE_SNAPSHOT */
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -3215,10 +3187,9 @@ zfs_ioc_destroy(zfs_cmd_t *zc)
|
||||
static int
|
||||
zfs_ioc_rollback(zfs_cmd_t *zc)
|
||||
{
|
||||
#ifdef HAVE_ZPL
|
||||
dsl_dataset_t *ds, *clone;
|
||||
int error;
|
||||
zfsvfs_t *zfsvfs;
|
||||
zfs_sb_t *zsb;
|
||||
char *clone_name;
|
||||
|
||||
error = dsl_dataset_hold(zc->zc_name, FTAG, &ds);
|
||||
@@ -3252,8 +3223,8 @@ zfs_ioc_rollback(zfs_cmd_t *zc)
|
||||
/*
|
||||
* Do clone swap.
|
||||
*/
|
||||
if (getzfsvfs(zc->zc_name, &zfsvfs) == 0) {
|
||||
error = zfs_suspend_fs(zfsvfs);
|
||||
if (get_zfs_sb(zc->zc_name, &zsb) == 0) {
|
||||
error = zfs_suspend_fs(zsb);
|
||||
if (error == 0) {
|
||||
int resume_err;
|
||||
|
||||
@@ -3265,10 +3236,10 @@ zfs_ioc_rollback(zfs_cmd_t *zc)
|
||||
} else {
|
||||
error = EBUSY;
|
||||
}
|
||||
resume_err = zfs_resume_fs(zfsvfs, zc->zc_name);
|
||||
resume_err = zfs_resume_fs(zsb, zc->zc_name);
|
||||
error = error ? error : resume_err;
|
||||
}
|
||||
VFS_RELE(zfsvfs->z_vfs);
|
||||
mntput(zsb->z_vfs);
|
||||
} else {
|
||||
if (dsl_dataset_tryown(ds, B_FALSE, FTAG)) {
|
||||
error = dsl_dataset_clone_swap(clone, ds, B_TRUE);
|
||||
@@ -3289,9 +3260,6 @@ out:
|
||||
if (ds)
|
||||
dsl_dataset_rele(ds, FTAG);
|
||||
return (error);
|
||||
#else
|
||||
return (ENOTSUP);
|
||||
#endif /* HAVE_ZPL */
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3741,29 +3709,25 @@ zfs_ioc_recv(zfs_cmd_t *zc)
|
||||
&zc->zc_action_handle);
|
||||
|
||||
if (error == 0) {
|
||||
#ifdef HAVE_ZPL
|
||||
zfsvfs_t *zfsvfs = NULL;
|
||||
zfs_sb_t *zsb = NULL;
|
||||
|
||||
if (getzfsvfs(tofs, &zfsvfs) == 0) {
|
||||
if (get_zfs_sb(tofs, &zsb) == 0) {
|
||||
/* online recv */
|
||||
int end_err;
|
||||
|
||||
error = zfs_suspend_fs(zfsvfs);
|
||||
error = zfs_suspend_fs(zsb);
|
||||
/*
|
||||
* If the suspend fails, then the recv_end will
|
||||
* likely also fail, and clean up after itself.
|
||||
*/
|
||||
end_err = dmu_recv_end(&drc);
|
||||
if (error == 0)
|
||||
error = zfs_resume_fs(zfsvfs, tofs);
|
||||
error = zfs_resume_fs(zsb, tofs);
|
||||
error = error ? error : end_err;
|
||||
VFS_RELE(zfsvfs->z_vfs);
|
||||
mntput(zsb->z_vfs);
|
||||
} else {
|
||||
error = dmu_recv_end(&drc);
|
||||
}
|
||||
#else
|
||||
error = dmu_recv_end(&drc);
|
||||
#endif /* HAVE_ZPL */
|
||||
}
|
||||
|
||||
zc->zc_cookie = off - fp->f_offset;
|
||||
@@ -4087,25 +4051,21 @@ zfs_ioc_promote(zfs_cmd_t *zc)
|
||||
static int
|
||||
zfs_ioc_userspace_one(zfs_cmd_t *zc)
|
||||
{
|
||||
#ifdef HAVE_ZPL
|
||||
zfsvfs_t *zfsvfs;
|
||||
zfs_sb_t *zsb;
|
||||
int error;
|
||||
|
||||
if (zc->zc_objset_type >= ZFS_NUM_USERQUOTA_PROPS)
|
||||
return (EINVAL);
|
||||
|
||||
error = zfsvfs_hold(zc->zc_name, FTAG, &zfsvfs, B_FALSE);
|
||||
error = zfs_sb_hold(zc->zc_name, FTAG, &zsb, B_FALSE);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
error = zfs_userspace_one(zfsvfs,
|
||||
error = zfs_userspace_one(zsb,
|
||||
zc->zc_objset_type, zc->zc_value, zc->zc_guid, &zc->zc_cookie);
|
||||
zfsvfs_rele(zfsvfs, FTAG);
|
||||
zfs_sb_rele(zsb, FTAG);
|
||||
|
||||
return (error);
|
||||
#else
|
||||
return (ENOTSUP);
|
||||
#endif /* HAVE_ZPL */
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4122,20 +4082,21 @@ zfs_ioc_userspace_one(zfs_cmd_t *zc)
|
||||
static int
|
||||
zfs_ioc_userspace_many(zfs_cmd_t *zc)
|
||||
{
|
||||
#ifdef HAVE_ZPL
|
||||
zfsvfs_t *zfsvfs;
|
||||
zfs_sb_t *zsb;
|
||||
int bufsize = zc->zc_nvlist_dst_size;
|
||||
int error;
|
||||
void *buf;
|
||||
|
||||
if (bufsize <= 0)
|
||||
return (ENOMEM);
|
||||
|
||||
int error = zfsvfs_hold(zc->zc_name, FTAG, &zfsvfs, B_FALSE);
|
||||
error = zfs_sb_hold(zc->zc_name, FTAG, &zsb, B_FALSE);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
void *buf = kmem_alloc(bufsize, KM_SLEEP);
|
||||
buf = kmem_alloc(bufsize, KM_SLEEP);
|
||||
|
||||
error = zfs_userspace_many(zfsvfs, zc->zc_objset_type, &zc->zc_cookie,
|
||||
error = zfs_userspace_many(zsb, zc->zc_objset_type, &zc->zc_cookie,
|
||||
buf, &zc->zc_nvlist_dst_size);
|
||||
|
||||
if (error == 0) {
|
||||
@@ -4144,12 +4105,9 @@ zfs_ioc_userspace_many(zfs_cmd_t *zc)
|
||||
zc->zc_nvlist_dst_size);
|
||||
}
|
||||
kmem_free(buf, bufsize);
|
||||
zfsvfs_rele(zfsvfs, FTAG);
|
||||
zfs_sb_rele(zsb, FTAG);
|
||||
|
||||
return (error);
|
||||
#else
|
||||
return (ENOTSUP);
|
||||
#endif /* HAVE_ZPL */
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4162,25 +4120,24 @@ zfs_ioc_userspace_many(zfs_cmd_t *zc)
|
||||
static int
|
||||
zfs_ioc_userspace_upgrade(zfs_cmd_t *zc)
|
||||
{
|
||||
#ifdef HAVE_ZPL
|
||||
objset_t *os;
|
||||
int error = 0;
|
||||
zfsvfs_t *zfsvfs;
|
||||
zfs_sb_t *zsb;
|
||||
|
||||
if (getzfsvfs(zc->zc_name, &zfsvfs) == 0) {
|
||||
if (!dmu_objset_userused_enabled(zfsvfs->z_os)) {
|
||||
if (get_zfs_sb(zc->zc_name, &zsb) == 0) {
|
||||
if (!dmu_objset_userused_enabled(zsb->z_os)) {
|
||||
/*
|
||||
* If userused is not enabled, it may be because the
|
||||
* objset needs to be closed & reopened (to grow the
|
||||
* objset_phys_t). Suspend/resume the fs will do that.
|
||||
*/
|
||||
error = zfs_suspend_fs(zfsvfs);
|
||||
error = zfs_suspend_fs(zsb);
|
||||
if (error == 0)
|
||||
error = zfs_resume_fs(zfsvfs, zc->zc_name);
|
||||
error = zfs_resume_fs(zsb, zc->zc_name);
|
||||
}
|
||||
if (error == 0)
|
||||
error = dmu_objset_userspace_upgrade(zfsvfs->z_os);
|
||||
VFS_RELE(zfsvfs->z_vfs);
|
||||
error = dmu_objset_userspace_upgrade(zsb->z_os);
|
||||
mntput(zsb->z_vfs);
|
||||
} else {
|
||||
/* XXX kind of reading contents without owning */
|
||||
error = dmu_objset_hold(zc->zc_name, FTAG, &os);
|
||||
@@ -4192,9 +4149,6 @@ zfs_ioc_userspace_upgrade(zfs_cmd_t *zc)
|
||||
}
|
||||
|
||||
return (error);
|
||||
#else
|
||||
return (ENOTSUP);
|
||||
#endif /* HAVE_ZPL */
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4456,10 +4410,10 @@ zfs_smb_acl_purge(znode_t *dzp)
|
||||
{
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t zap;
|
||||
zfsvfs_t *zfsvfs = dzp->z_zfsvfs;
|
||||
zfs_sb_t *zsb = ZTOZSB(dzp);
|
||||
int error;
|
||||
|
||||
for (zap_cursor_init(&zc, zfsvfs->z_os, dzp->z_id);
|
||||
for (zap_cursor_init(&zc, zsb->z_os, dzp->z_id);
|
||||
(error = zap_cursor_retrieve(&zc, &zap)) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
if ((error = VOP_REMOVE(ZTOV(dzp), zap.za_name, kcred,
|
||||
@@ -4479,7 +4433,7 @@ zfs_ioc_smb_acl(zfs_cmd_t *zc)
|
||||
znode_t *dzp;
|
||||
vnode_t *resourcevp = NULL;
|
||||
znode_t *sharedir;
|
||||
zfsvfs_t *zfsvfs;
|
||||
zfs_sb_t *zsb;
|
||||
nvlist_t *nvlist;
|
||||
char *src, *target;
|
||||
vattr_t vattr;
|
||||
@@ -4500,17 +4454,17 @@ zfs_ioc_smb_acl(zfs_cmd_t *zc)
|
||||
}
|
||||
|
||||
dzp = VTOZ(vp);
|
||||
zfsvfs = dzp->z_zfsvfs;
|
||||
ZFS_ENTER(zfsvfs);
|
||||
zsb = ZTOZSB(dzp);
|
||||
ZFS_ENTER(zsb);
|
||||
|
||||
/*
|
||||
* Create share dir if its missing.
|
||||
*/
|
||||
mutex_enter(&zfsvfs->z_lock);
|
||||
if (zfsvfs->z_shares_dir == 0) {
|
||||
mutex_enter(&zsb->z_lock);
|
||||
if (zsb->z_shares_dir == 0) {
|
||||
dmu_tx_t *tx;
|
||||
|
||||
tx = dmu_tx_create(zfsvfs->z_os);
|
||||
tx = dmu_tx_create(zsb->z_os);
|
||||
dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, TRUE,
|
||||
ZFS_SHARES_DIR);
|
||||
dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, FALSE, NULL);
|
||||
@@ -4518,29 +4472,28 @@ zfs_ioc_smb_acl(zfs_cmd_t *zc)
|
||||
if (error) {
|
||||
dmu_tx_abort(tx);
|
||||
} else {
|
||||
error = zfs_create_share_dir(zfsvfs, tx);
|
||||
error = zfs_create_share_dir(zsb, tx);
|
||||
dmu_tx_commit(tx);
|
||||
}
|
||||
if (error) {
|
||||
mutex_exit(&zfsvfs->z_lock);
|
||||
mutex_exit(&zsb->z_lock);
|
||||
VN_RELE(vp);
|
||||
ZFS_EXIT(zfsvfs);
|
||||
ZFS_EXIT(zsb);
|
||||
return (error);
|
||||
}
|
||||
}
|
||||
mutex_exit(&zfsvfs->z_lock);
|
||||
mutex_exit(&zsb->z_lock);
|
||||
|
||||
ASSERT(zfsvfs->z_shares_dir);
|
||||
if ((error = zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &sharedir)) != 0) {
|
||||
ASSERT(zsb->z_shares_dir);
|
||||
if ((error = zfs_zget(zsb, zsb->z_shares_dir, &sharedir)) != 0) {
|
||||
VN_RELE(vp);
|
||||
ZFS_EXIT(zfsvfs);
|
||||
ZFS_EXIT(zsb);
|
||||
return (error);
|
||||
}
|
||||
|
||||
switch (zc->zc_cookie) {
|
||||
case ZFS_SMB_ACL_ADD:
|
||||
vattr.va_mask = AT_MODE|AT_UID|AT_GID|AT_TYPE;
|
||||
vattr.va_type = VREG;
|
||||
vattr.va_mode = S_IFREG|0777;
|
||||
vattr.va_uid = 0;
|
||||
vattr.va_gid = 0;
|
||||
@@ -4565,7 +4518,7 @@ zfs_ioc_smb_acl(zfs_cmd_t *zc)
|
||||
if ((error = get_nvlist(zc->zc_nvlist_src,
|
||||
zc->zc_nvlist_src_size, zc->zc_iflags, &nvlist)) != 0) {
|
||||
VN_RELE(vp);
|
||||
ZFS_EXIT(zfsvfs);
|
||||
ZFS_EXIT(zsb);
|
||||
return (error);
|
||||
}
|
||||
if (nvlist_lookup_string(nvlist, ZFS_SMB_ACL_SRC, &src) ||
|
||||
@@ -4573,7 +4526,7 @@ zfs_ioc_smb_acl(zfs_cmd_t *zc)
|
||||
&target)) {
|
||||
VN_RELE(vp);
|
||||
VN_RELE(ZTOV(sharedir));
|
||||
ZFS_EXIT(zfsvfs);
|
||||
ZFS_EXIT(zsb);
|
||||
nvlist_free(nvlist);
|
||||
return (error);
|
||||
}
|
||||
@@ -4594,7 +4547,7 @@ zfs_ioc_smb_acl(zfs_cmd_t *zc)
|
||||
VN_RELE(vp);
|
||||
VN_RELE(ZTOV(sharedir));
|
||||
|
||||
ZFS_EXIT(zfsvfs);
|
||||
ZFS_EXIT(zsb);
|
||||
|
||||
return (error);
|
||||
#else
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_ZPL
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
@@ -411,9 +410,9 @@ zfs_log_symlink(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
|
||||
lr->lr_uid = zp->z_uid;
|
||||
lr->lr_gid = zp->z_gid;
|
||||
lr->lr_mode = zp->z_mode;
|
||||
(void) sa_lookup(zp->z_sa_hdl, SA_ZPL_GEN(zp->z_zfsvfs), &lr->lr_gen,
|
||||
(void) sa_lookup(zp->z_sa_hdl, SA_ZPL_GEN(ZTOZSB(zp)), &lr->lr_gen,
|
||||
sizeof (uint64_t));
|
||||
(void) sa_lookup(zp->z_sa_hdl, SA_ZPL_CRTIME(zp->z_zfsvfs),
|
||||
(void) sa_lookup(zp->z_sa_hdl, SA_ZPL_CRTIME(ZTOZSB(zp)),
|
||||
lr->lr_crtime, sizeof (uint64_t) * 2);
|
||||
bcopy(name, (char *)(lr + 1), namesize);
|
||||
bcopy(link, (char *)(lr + 1) + namesize, linksize);
|
||||
@@ -496,7 +495,7 @@ zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype,
|
||||
itx = zil_itx_create(txtype, sizeof (*lr) +
|
||||
(write_state == WR_COPIED ? len : 0));
|
||||
lr = (lr_write_t *)&itx->itx_lr;
|
||||
if (write_state == WR_COPIED && dmu_read(zp->z_zfsvfs->z_os,
|
||||
if (write_state == WR_COPIED && dmu_read(ZTOZSB(zp)->z_os,
|
||||
zp->z_id, off, len, lr + 1, DMU_READ_NO_PREFETCH) != 0) {
|
||||
zil_itx_destroy(itx);
|
||||
itx = zil_itx_create(txtype, sizeof (*lr));
|
||||
@@ -513,7 +512,7 @@ zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype,
|
||||
lr->lr_blkoff = 0;
|
||||
BP_ZERO(&lr->lr_blkptr);
|
||||
|
||||
itx->itx_private = zp->z_zfsvfs;
|
||||
itx->itx_private = ZTOZSB(zp);
|
||||
|
||||
if (!(ioflag & (FSYNC | FDSYNC)) && (zp->z_sync_cnt == 0) &&
|
||||
(fsync_cnt == 0))
|
||||
@@ -629,7 +628,7 @@ zfs_log_acl(zilog_t *zilog, dmu_tx_t *tx, znode_t *zp,
|
||||
if (zil_replaying(zilog, tx) || zp->z_unlinked)
|
||||
return;
|
||||
|
||||
txtype = (zp->z_zfsvfs->z_version < ZPL_VERSION_FUID) ?
|
||||
txtype = (ZTOZSB(zp)->z_version < ZPL_VERSION_FUID) ?
|
||||
TX_ACL_V0 : TX_ACL;
|
||||
|
||||
if (txtype == TX_ACL)
|
||||
@@ -667,14 +666,14 @@ zfs_log_acl(zilog_t *zilog, dmu_tx_t *tx, znode_t *zp,
|
||||
|
||||
start = (caddr_t)start + ZIL_ACE_LENGTH(aclbytes);
|
||||
|
||||
#ifdef HAVE_XVATTR
|
||||
if (fuidp) {
|
||||
start = zfs_log_fuid_ids(fuidp, start);
|
||||
(void) zfs_log_fuid_domains(fuidp, start);
|
||||
}
|
||||
#endif /* HAVE_XVATTR */
|
||||
}
|
||||
|
||||
itx->itx_sync = (zp->z_sync_cnt != 0);
|
||||
zil_itx_assign(zilog, itx, tx);
|
||||
}
|
||||
|
||||
#endif /* HAVE_ZPL */
|
||||
|
||||
@@ -134,7 +134,7 @@ zfs_range_lock_writer(znode_t *zp, rl_t *new)
|
||||
*/
|
||||
end_size = MAX(zp->z_size, new->r_off + len);
|
||||
if (end_size > zp->z_blksz && (!ISP2(zp->z_blksz) ||
|
||||
zp->z_blksz < zp->z_zfsvfs->z_max_blksz)) {
|
||||
zp->z_blksz < ZTOZSB(zp)->z_max_blksz)) {
|
||||
new->r_off = 0;
|
||||
new->r_len = UINT64_MAX;
|
||||
}
|
||||
|
||||
+39
-39
@@ -81,7 +81,7 @@ zfs_sa_readlink(znode_t *zp, uio_t *uio)
|
||||
MIN((size_t)bufsz, uio->uio_resid), UIO_READ, uio);
|
||||
} else {
|
||||
dmu_buf_t *dbp;
|
||||
if ((error = dmu_buf_hold(zp->z_zfsvfs->z_os, zp->z_id,
|
||||
if ((error = dmu_buf_hold(ZTOZSB(zp)->z_os, zp->z_id,
|
||||
0, FTAG, &dbp, DMU_READ_NO_PREFETCH)) == 0) {
|
||||
error = uiomove(dbp->db_data,
|
||||
MIN((size_t)bufsz, uio->uio_resid), UIO_READ, uio);
|
||||
@@ -107,7 +107,7 @@ zfs_sa_symlink(znode_t *zp, char *link, int len, dmu_tx_t *tx)
|
||||
dmu_buf_t *dbp;
|
||||
|
||||
zfs_grow_blocksize(zp, len, tx);
|
||||
VERIFY(0 == dmu_buf_hold(zp->z_zfsvfs->z_os,
|
||||
VERIFY(0 == dmu_buf_hold(ZTOZSB(zp)->z_os,
|
||||
zp->z_id, 0, FTAG, &dbp, DMU_READ_NO_PREFETCH));
|
||||
|
||||
dmu_buf_will_dirty(dbp, tx);
|
||||
@@ -122,13 +122,13 @@ zfs_sa_symlink(znode_t *zp, char *link, int len, dmu_tx_t *tx)
|
||||
void
|
||||
zfs_sa_get_scanstamp(znode_t *zp, xvattr_t *xvap)
|
||||
{
|
||||
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
|
||||
zfs_sb_t *zsb = ZTOZSB(zp);
|
||||
xoptattr_t *xoap;
|
||||
|
||||
ASSERT(MUTEX_HELD(&zp->z_lock));
|
||||
VERIFY((xoap = xva_getxoptattr(xvap)) != NULL);
|
||||
if (zp->z_is_sa) {
|
||||
if (sa_lookup(zp->z_sa_hdl, SA_ZPL_SCANSTAMP(zfsvfs),
|
||||
if (sa_lookup(zp->z_sa_hdl, SA_ZPL_SCANSTAMP(zsb),
|
||||
&xoap->xoa_av_scanstamp,
|
||||
sizeof (xoap->xoa_av_scanstamp)) != 0)
|
||||
return;
|
||||
@@ -156,13 +156,13 @@ zfs_sa_get_scanstamp(znode_t *zp, xvattr_t *xvap)
|
||||
void
|
||||
zfs_sa_set_scanstamp(znode_t *zp, xvattr_t *xvap, dmu_tx_t *tx)
|
||||
{
|
||||
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
|
||||
zfs_sb_t *zsb = ZTOZSB(zp);
|
||||
xoptattr_t *xoap;
|
||||
|
||||
ASSERT(MUTEX_HELD(&zp->z_lock));
|
||||
VERIFY((xoap = xva_getxoptattr(xvap)) != NULL);
|
||||
if (zp->z_is_sa)
|
||||
VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_SCANSTAMP(zfsvfs),
|
||||
VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_SCANSTAMP(zsb),
|
||||
&xoap->xoa_av_scanstamp,
|
||||
sizeof (xoap->xoa_av_scanstamp), tx));
|
||||
else {
|
||||
@@ -179,7 +179,7 @@ zfs_sa_set_scanstamp(znode_t *zp, xvattr_t *xvap, dmu_tx_t *tx)
|
||||
xoap->xoa_av_scanstamp, sizeof (xoap->xoa_av_scanstamp));
|
||||
|
||||
zp->z_pflags |= ZFS_BONUS_SCANSTAMP;
|
||||
VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_FLAGS(zfsvfs),
|
||||
VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_FLAGS(zsb),
|
||||
&zp->z_pflags, sizeof (uint64_t), tx));
|
||||
}
|
||||
}
|
||||
@@ -198,7 +198,7 @@ zfs_sa_upgrade(sa_handle_t *hdl, dmu_tx_t *tx)
|
||||
{
|
||||
dmu_buf_t *db = sa_get_db(hdl);
|
||||
znode_t *zp = sa_get_userdata(hdl);
|
||||
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
|
||||
zfs_sb_t *zsb = ZTOZSB(zp);
|
||||
int count = 0;
|
||||
sa_bulk_attr_t *bulk, *sa_attrs;
|
||||
zfs_acl_locator_cb_t locate = { 0 };
|
||||
@@ -216,7 +216,7 @@ zfs_sa_upgrade(sa_handle_t *hdl, dmu_tx_t *tx)
|
||||
* and ready the ACL would require special "locked"
|
||||
* interfaces that would be messy
|
||||
*/
|
||||
if (zp->z_acl_cached == NULL || ZTOV(zp)->v_type == VLNK)
|
||||
if (zp->z_acl_cached == NULL || S_ISLNK(ZTOI(zp)->i_mode))
|
||||
return;
|
||||
|
||||
/*
|
||||
@@ -237,16 +237,16 @@ zfs_sa_upgrade(sa_handle_t *hdl, dmu_tx_t *tx)
|
||||
|
||||
/* First do a bulk query of the attributes that aren't cached */
|
||||
bulk = kmem_alloc(sizeof(sa_bulk_attr_t) * 20, KM_SLEEP);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zfsvfs), NULL, &mtime, 16);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL, &ctime, 16);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CRTIME(zfsvfs), NULL, &crtime, 16);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zfsvfs), NULL, &mode, 8);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_PARENT(zfsvfs), NULL, &parent, 8);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_XATTR(zfsvfs), NULL, &xattr, 8);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_RDEV(zfsvfs), NULL, &rdev, 8);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_UID(zfsvfs), NULL, &uid, 8);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GID(zfsvfs), NULL, &gid, 8);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ZNODE_ACL(zfsvfs), NULL,
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zsb), NULL, &mtime, 16);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb), NULL, &ctime, 16);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CRTIME(zsb), NULL, &crtime, 16);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zsb), NULL, &mode, 8);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_PARENT(zsb), NULL, &parent, 8);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_XATTR(zsb), NULL, &xattr, 8);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_RDEV(zsb), NULL, &rdev, 8);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_UID(zsb), NULL, &uid, 8);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GID(zsb), NULL, &gid, 8);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ZNODE_ACL(zsb), NULL,
|
||||
&znode_acl, 88);
|
||||
|
||||
if (sa_bulk_lookup_locked(hdl, bulk, count) != 0) {
|
||||
@@ -260,42 +260,42 @@ zfs_sa_upgrade(sa_handle_t *hdl, dmu_tx_t *tx)
|
||||
*/
|
||||
count = 0;
|
||||
sa_attrs = kmem_zalloc(sizeof(sa_bulk_attr_t) * 20, KM_SLEEP);
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_MODE(zfsvfs), NULL, &mode, 8);
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_SIZE(zfsvfs), NULL,
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_MODE(zsb), NULL, &mode, 8);
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_SIZE(zsb), NULL,
|
||||
&zp->z_size, 8);
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_GEN(zfsvfs),
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_GEN(zsb),
|
||||
NULL, &zp->z_gen, 8);
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_UID(zfsvfs), NULL, &uid, 8);
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_GID(zfsvfs), NULL, &gid, 8);
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_PARENT(zfsvfs),
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_UID(zsb), NULL, &uid, 8);
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_GID(zsb), NULL, &gid, 8);
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_PARENT(zsb),
|
||||
NULL, &parent, 8);
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_FLAGS(zfsvfs), NULL,
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_FLAGS(zsb), NULL,
|
||||
&zp->z_pflags, 8);
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_ATIME(zfsvfs), NULL,
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_ATIME(zsb), NULL,
|
||||
zp->z_atime, 16);
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_MTIME(zfsvfs), NULL,
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_MTIME(zsb), NULL,
|
||||
&mtime, 16);
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_CTIME(zfsvfs), NULL,
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_CTIME(zsb), NULL,
|
||||
&ctime, 16);
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_CRTIME(zfsvfs), NULL,
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_CRTIME(zsb), NULL,
|
||||
&crtime, 16);
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_LINKS(zfsvfs), NULL,
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_LINKS(zsb), NULL,
|
||||
&zp->z_links, 8);
|
||||
if (zp->z_vnode->v_type == VBLK || zp->z_vnode->v_type == VCHR)
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_RDEV(zfsvfs), NULL,
|
||||
if (S_ISBLK(ZTOI(zp)->i_mode) || S_ISCHR(ZTOI(zp)->i_mode))
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_RDEV(zsb), NULL,
|
||||
&rdev, 8);
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_DACL_COUNT(zfsvfs), NULL,
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_DACL_COUNT(zsb), NULL,
|
||||
&zp->z_acl_cached->z_acl_count, 8);
|
||||
|
||||
if (zp->z_acl_cached->z_version < ZFS_ACL_VERSION_FUID)
|
||||
zfs_acl_xform(zp, zp->z_acl_cached, CRED());
|
||||
|
||||
locate.cb_aclp = zp->z_acl_cached;
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_DACL_ACES(zfsvfs),
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_DACL_ACES(zsb),
|
||||
zfs_acl_data_locator, &locate, zp->z_acl_cached->z_acl_bytes);
|
||||
|
||||
if (xattr)
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_XATTR(zfsvfs),
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_XATTR(zsb),
|
||||
NULL, &xattr, 8);
|
||||
|
||||
#ifdef HAVE_SCANSTAMP
|
||||
@@ -304,7 +304,7 @@ zfs_sa_upgrade(sa_handle_t *hdl, dmu_tx_t *tx)
|
||||
if (zp->z_pflags & ZFS_BONUS_SCANSTAMP) {
|
||||
bcopy((caddr_t)db->db_data + ZFS_OLD_ZNODE_PHYS_SIZE,
|
||||
scanstamp, AV_SCANSTAMP_SZ);
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_SCANSTAMP(zfsvfs),
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_SCANSTAMP(zsb),
|
||||
NULL, scanstamp, AV_SCANSTAMP_SZ);
|
||||
zp->z_pflags &= ~ZFS_BONUS_SCANSTAMP;
|
||||
}
|
||||
@@ -314,7 +314,7 @@ zfs_sa_upgrade(sa_handle_t *hdl, dmu_tx_t *tx)
|
||||
VERIFY(sa_replace_all_by_template_locked(hdl, sa_attrs,
|
||||
count, tx) == 0);
|
||||
if (znode_acl.z_acl_extern_obj)
|
||||
VERIFY(0 == dmu_object_free(zfsvfs->z_os,
|
||||
VERIFY(0 == dmu_object_free(zsb->z_os,
|
||||
znode_acl.z_acl_extern_obj, tx));
|
||||
|
||||
zp->z_is_sa = B_TRUE;
|
||||
@@ -328,7 +328,7 @@ done:
|
||||
void
|
||||
zfs_sa_upgrade_txholds(dmu_tx_t *tx, znode_t *zp)
|
||||
{
|
||||
if (!zp->z_zfsvfs->z_use_sa || zp->z_is_sa)
|
||||
if (!ZTOZSB(zp)->z_use_sa || zp->z_is_sa)
|
||||
return;
|
||||
|
||||
|
||||
|
||||
+479
-627
File diff suppressed because it is too large
Load Diff
+734
-1609
File diff suppressed because it is too large
Load Diff
+272
-448
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user