summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cddl/contrib/opensolaris/cmd/zpool/zpool_main.c2
-rw-r--r--sys/cddl/boot/zfs/zfsimpl.h6
-rw-r--r--sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c3
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_acl.h3
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c192
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c8
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h6
7 files changed, 123 insertions, 97 deletions
diff --git a/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c b/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c
index 2388df9..2970371 100644
--- a/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c
+++ b/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c
@@ -3488,6 +3488,8 @@ zpool_do_upgrade(int argc, char **argv)
(void) printf(gettext(" 11 Improved scrub performance\n"));
(void) printf(gettext(" 12 Snapshot properties\n"));
(void) printf(gettext(" 13 snapused property\n"));
+ (void) printf(gettext(" 14 passthrough-x aclinherit "
+ "support\n"));
(void) printf(gettext("For more information on a particular "
"version, including supported releases, see:\n\n"));
(void) printf("http://www.opensolaris.org/os/community/zfs/"
diff --git a/sys/cddl/boot/zfs/zfsimpl.h b/sys/cddl/boot/zfs/zfsimpl.h
index 688bb5c..1149eac 100644
--- a/sys/cddl/boot/zfs/zfsimpl.h
+++ b/sys/cddl/boot/zfs/zfsimpl.h
@@ -479,13 +479,14 @@ typedef enum {
#define SPA_VERSION_11 11ULL
#define SPA_VERSION_12 12ULL
#define SPA_VERSION_13 13ULL
+#define SPA_VERSION_14 14ULL
/*
* When bumping up SPA_VERSION, make sure GRUB ZFS understand the on-disk
* format change. Go to usr/src/grub/grub-0.95/stage2/{zfs-include/, fsys_zfs*},
* and do the appropriate changes.
*/
-#define SPA_VERSION SPA_VERSION_13
-#define SPA_VERSION_STRING "13"
+#define SPA_VERSION SPA_VERSION_14
+#define SPA_VERSION_STRING "14"
/*
* Symbolic names for the changes that caused a SPA_VERSION switch.
@@ -520,6 +521,7 @@ typedef enum {
#define SPA_VERSION_DSL_SCRUB SPA_VERSION_11
#define SPA_VERSION_SNAP_PROPS SPA_VERSION_12
#define SPA_VERSION_USED_BREAKDOWN SPA_VERSION_13
+#define SPA_VERSION_PASSTHROUGH_X SPA_VERSION_14
/*
* The following are configuration names used in the nvlist describing a pool's
diff --git a/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c b/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c
index fef05ab..70c08ad 100644
--- a/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c
+++ b/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c
@@ -97,6 +97,7 @@ zfs_prop_init(void)
{ "restricted", ZFS_ACL_RESTRICTED },
{ "passthrough", ZFS_ACL_PASSTHROUGH },
{ "secure", ZFS_ACL_RESTRICTED }, /* bkwrd compatability */
+ { "passthrough-x", ZFS_ACL_PASSTHROUGH_X },
{ NULL }
};
@@ -173,7 +174,7 @@ zfs_prop_init(void)
"discard | groupmask | passthrough", "ACLMODE", acl_mode_table);
register_index(ZFS_PROP_ACLINHERIT, "aclinherit", ZFS_ACL_RESTRICTED,
PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
- "discard | noallow | restricted | passthrough",
+ "discard | noallow | restricted | passthrough | passthrough-x",
"ACLINHERIT", acl_inherit_table);
register_index(ZFS_PROP_COPIES, "copies", 1,
PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_acl.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_acl.h
index df148c6..f87823c 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_acl.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_acl.h
@@ -26,8 +26,6 @@
#ifndef _SYS_FS_ZFS_ACL_H
#define _SYS_FS_ZFS_ACL_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifdef _KERNEL
#include <sys/cred.h>
#endif
@@ -180,6 +178,7 @@ typedef struct zfs_acl {
#define ZFS_ACL_GROUPMASK 2
#define ZFS_ACL_PASSTHROUGH 3
#define ZFS_ACL_RESTRICTED 4
+#define ZFS_ACL_PASSTHROUGH_X 5
struct znode;
struct zfsvfs;
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c
index a43d85c..eb93721 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c
@@ -1663,7 +1663,8 @@ zfs_ace_can_use(znode_t *zp, uint16_t acep_flags)
* inherit inheritable ACEs from parent
*/
static zfs_acl_t *
-zfs_acl_inherit(znode_t *zp, zfs_acl_t *paclp, boolean_t *need_chmod)
+zfs_acl_inherit(znode_t *zp, zfs_acl_t *paclp, uint64_t mode,
+ boolean_t *need_chmod)
{
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
void *pacep;
@@ -1676,112 +1677,123 @@ zfs_acl_inherit(znode_t *zp, zfs_acl_t *paclp, boolean_t *need_chmod)
size_t ace_size;
void *data1, *data2;
size_t data1sz, data2sz;
- enum vtype vntype = ZTOV(zp)->v_type;
+ boolean_t vdir = ZTOV(zp)->v_type == VDIR;
+ boolean_t vreg = ZTOV(zp)->v_type == VREG;
+ boolean_t passthrough, passthrough_x, noallow;
+
+ passthrough_x =
+ zfsvfs->z_acl_inherit == ZFS_ACL_PASSTHROUGH_X;
+ passthrough = passthrough_x ||
+ zfsvfs->z_acl_inherit == ZFS_ACL_PASSTHROUGH;
+ noallow =
+ zfsvfs->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) {
- while (pacep = zfs_acl_next_ace(paclp, pacep, &who,
- &access_mask, &iflags, &type)) {
+ if (zfsvfs->z_acl_inherit == ZFS_ACL_DISCARD)
+ return (aclp);
+ while (pacep = zfs_acl_next_ace(paclp, pacep, &who,
+ &access_mask, &iflags, &type)) {
- /*
- * don't inherit bogus ACEs
- */
- if (!zfs_acl_valid_ace_type(type, iflags))
- continue;
+ /*
+ * don't inherit bogus ACEs
+ */
+ if (!zfs_acl_valid_ace_type(type, iflags))
+ continue;
- if (zfsvfs->z_acl_inherit == ZFS_ACL_NOALLOW &&
- type == ALLOW)
- continue;
+ if (noallow && type == ALLOW)
+ continue;
- ace_size = aclp->z_ops.ace_size(pacep);
+ ace_size = aclp->z_ops.ace_size(pacep);
- if (!zfs_ace_can_use(zp, iflags))
- continue;
+ if (!zfs_ace_can_use(zp, iflags))
+ continue;
- /*
- * If owner@, group@, or everyone@ inheritable
- * then zfs_acl_chmod() isn't needed.
- */
- if (zfsvfs->z_acl_inherit ==
- ZFS_ACL_PASSTHROUGH &&
- ((iflags & (ACE_OWNER|ACE_EVERYONE)) ||
- ((iflags & OWNING_GROUP) ==
- OWNING_GROUP)) && (vntype == VREG ||
- (vntype == VDIR &&
- (iflags & ACE_DIRECTORY_INHERIT_ACE))))
- *need_chmod = B_FALSE;
-
- aclnode = zfs_acl_node_alloc(ace_size);
- list_insert_tail(&aclp->z_acl, aclnode);
- acep = aclnode->z_acldata;
- zfs_set_ace(aclp, acep, access_mask, type,
- who, iflags|ACE_INHERITED_ACE);
+ /*
+ * If owner@, group@, or everyone@ inheritable
+ * then zfs_acl_chmod() isn't needed.
+ */
+ if (passthrough &&
+ ((iflags & (ACE_OWNER|ACE_EVERYONE)) ||
+ ((iflags & OWNING_GROUP) ==
+ OWNING_GROUP)) && (vreg || (vdir && (iflags &
+ ACE_DIRECTORY_INHERIT_ACE)))) {
+ *need_chmod = B_FALSE;
+
+ if (!vdir && passthrough_x &&
+ ((mode & (S_IXUSR | S_IXGRP | S_IXOTH)) == 0)) {
+ access_mask &= ~ACE_EXECUTE;
+ }
+ }
+
+ aclnode = zfs_acl_node_alloc(ace_size);
+ list_insert_tail(&aclp->z_acl, aclnode);
+ acep = aclnode->z_acldata;
+
+ zfs_set_ace(aclp, acep, access_mask, type,
+ who, iflags|ACE_INHERITED_ACE);
+
+ /*
+ * Copy special opaque data if any
+ */
+ if ((data1sz = paclp->z_ops.ace_data(pacep, &data1)) != 0) {
+ VERIFY((data2sz = aclp->z_ops.ace_data(acep,
+ &data2)) == data1sz);
+ bcopy(data1, data2, data2sz);
+ }
+ aclp->z_acl_count++;
+ aclnode->z_ace_count++;
+ aclp->z_acl_bytes += aclnode->z_size;
+ newflags = aclp->z_ops.ace_flags_get(acep);
+
+ if (vdir)
+ aclp->z_hints |= ZFS_INHERIT_ACE;
+
+ if ((iflags & ACE_NO_PROPAGATE_INHERIT_ACE) || !vdir) {
+ newflags &= ~ALL_INHERIT;
+ aclp->z_ops.ace_flags_set(acep,
+ newflags|ACE_INHERITED_ACE);
+ zfs_restricted_update(zfsvfs, aclp, acep);
+ continue;
+ }
+
+ ASSERT(vdir);
+
+ newflags = aclp->z_ops.ace_flags_get(acep);
+ if ((iflags & (ACE_FILE_INHERIT_ACE |
+ ACE_DIRECTORY_INHERIT_ACE)) !=
+ ACE_FILE_INHERIT_ACE) {
+ aclnode2 = zfs_acl_node_alloc(ace_size);
+ list_insert_tail(&aclp->z_acl, aclnode2);
+ acep2 = aclnode2->z_acldata;
+ zfs_set_ace(aclp, acep2,
+ access_mask, type, who,
+ iflags|ACE_INHERITED_ACE);
+ newflags |= ACE_INHERIT_ONLY_ACE;
+ aclp->z_ops.ace_flags_set(acep, newflags);
+ newflags &= ~ALL_INHERIT;
+ aclp->z_ops.ace_flags_set(acep2,
+ newflags|ACE_INHERITED_ACE);
/*
* Copy special opaque data if any
*/
- if ((data1sz = paclp->z_ops.ace_data(pacep,
+ if ((data1sz = aclp->z_ops.ace_data(acep,
&data1)) != 0) {
- VERIFY((data2sz = aclp->z_ops.ace_data(acep,
+ VERIFY((data2sz =
+ aclp->z_ops.ace_data(acep2,
&data2)) == data1sz);
- bcopy(data1, data2, data2sz);
+ bcopy(data1, data2, data1sz);
}
aclp->z_acl_count++;
- aclnode->z_ace_count++;
+ aclnode2->z_ace_count++;
aclp->z_acl_bytes += aclnode->z_size;
- newflags = aclp->z_ops.ace_flags_get(acep);
-
- if (vntype == VDIR)
- aclp->z_hints |= ZFS_INHERIT_ACE;
-
- if ((iflags & ACE_NO_PROPAGATE_INHERIT_ACE) ||
- (vntype != VDIR)) {
- newflags &= ~ALL_INHERIT;
- aclp->z_ops.ace_flags_set(acep,
- newflags|ACE_INHERITED_ACE);
- zfs_restricted_update(zfsvfs, aclp, acep);
- continue;
- }
-
- ASSERT(vntype == VDIR);
-
- newflags = aclp->z_ops.ace_flags_get(acep);
- if ((iflags & (ACE_FILE_INHERIT_ACE |
- ACE_DIRECTORY_INHERIT_ACE)) !=
- ACE_FILE_INHERIT_ACE) {
- aclnode2 = zfs_acl_node_alloc(ace_size);
- list_insert_tail(&aclp->z_acl, aclnode2);
- acep2 = aclnode2->z_acldata;
- zfs_set_ace(aclp, acep2,
- access_mask, type, who,
- iflags|ACE_INHERITED_ACE);
- newflags |= ACE_INHERIT_ONLY_ACE;
- aclp->z_ops.ace_flags_set(acep, newflags);
- newflags &= ~ALL_INHERIT;
- aclp->z_ops.ace_flags_set(acep2,
- newflags|ACE_INHERITED_ACE);
-
- /*
- * Copy special opaque data if any
- */
- if ((data1sz = aclp->z_ops.ace_data(acep,
- &data1)) != 0) {
- VERIFY((data2sz =
- aclp->z_ops.ace_data(acep2,
- &data2)) == data1sz);
- bcopy(data1, data2, data1sz);
- }
- aclp->z_acl_count++;
- aclnode2->z_ace_count++;
- aclp->z_acl_bytes += aclnode->z_size;
- zfs_restricted_update(zfsvfs, aclp, acep2);
- } else {
- newflags |= ACE_INHERIT_ONLY_ACE;
- aclp->z_ops.ace_flags_set(acep,
- newflags|ACE_INHERITED_ACE);
- }
+ zfs_restricted_update(zfsvfs, aclp, acep2);
+ } else {
+ newflags |= ACE_INHERIT_ONLY_ACE;
+ aclp->z_ops.ace_flags_set(acep,
+ newflags|ACE_INHERITED_ACE);
}
}
return (aclp);
@@ -1876,7 +1888,7 @@ zfs_perm_init(znode_t *zp, znode_t *parent, int flag,
mutex_enter(&parent->z_acl_lock);
VERIFY(0 == zfs_acl_node_read(parent, &paclp, B_FALSE));
mutex_exit(&parent->z_acl_lock);
- aclp = zfs_acl_inherit(zp, paclp, &need_chmod);
+ aclp = zfs_acl_inherit(zp, paclp, mode, &need_chmod);
zfs_acl_free(paclp);
} else {
aclp = zfs_acl_alloc(zfs_acl_version_zp(zp));
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
index 080643a..00e446b 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
@@ -1491,6 +1491,14 @@ zfs_set_prop_nvlist(const char *name, nvlist_t *nvl)
if (zpl_earlier_version(name, ZPL_VERSION_FUID))
return (ENOTSUP);
break;
+
+ case ZFS_PROP_ACLINHERIT:
+ if (nvpair_type(elem) == DATA_TYPE_UINT64 &&
+ nvpair_value_uint64(elem, &intval) == 0)
+ if (intval == ZFS_ACL_PASSTHROUGH_X &&
+ zfs_earlier_version(name,
+ SPA_VERSION_PASSTHROUGH_X))
+ return (ENOTSUP);
}
}
diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h b/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h
index 70da8ae..2f7e747 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h
@@ -253,13 +253,14 @@ typedef enum zfs_cache_type {
#define SPA_VERSION_11 11ULL
#define SPA_VERSION_12 12ULL
#define SPA_VERSION_13 13ULL
+#define SPA_VERSION_14 14ULL
/*
* When bumping up SPA_VERSION, make sure GRUB ZFS understands the on-disk
* format change. Go to usr/src/grub/grub-0.95/stage2/{zfs-include/, fsys_zfs*},
* and do the appropriate changes.
*/
-#define SPA_VERSION SPA_VERSION_13
-#define SPA_VERSION_STRING "13"
+#define SPA_VERSION SPA_VERSION_14
+#define SPA_VERSION_STRING "14"
/*
* Symbolic names for the changes that caused a SPA_VERSION switch.
@@ -294,6 +295,7 @@ typedef enum zfs_cache_type {
#define SPA_VERSION_DSL_SCRUB SPA_VERSION_11
#define SPA_VERSION_SNAP_PROPS SPA_VERSION_12
#define SPA_VERSION_USED_BREAKDOWN SPA_VERSION_13
+#define SPA_VERSION_PASSTHROUGH_X SPA_VERSION_14
/*
* ZPL version - rev'd whenever an incompatible on-disk format change
OpenPOWER on IntegriCloud