diff options
author | delphij <delphij@FreeBSD.org> | 2009-12-28 22:15:11 +0000 |
---|---|---|
committer | delphij <delphij@FreeBSD.org> | 2009-12-28 22:15:11 +0000 |
commit | 2414a09002c0b7080b6044e995d127de758f3e12 (patch) | |
tree | 1430d12f92f54e2d6f42cd1c36726627c2427969 /sys/cddl | |
parent | 0b0591131cdc07568e203ce41632d17adc436efb (diff) | |
download | FreeBSD-src-2414a09002c0b7080b6044e995d127de758f3e12.zip FreeBSD-src-2414a09002c0b7080b6044e995d127de758f3e12.tar.gz |
Apply OpenSolaris revision 8012 which brings our zpool to version 14,
making it possible for zpools created on OpenSolaris 2009.06 be used
on FreeBSD.
PR: kern/141800
Submitted by: mm
Reviewed by: pjd, trasz
Obtained from: OpenSolaris
MFC after: 2 weeks
Diffstat (limited to 'sys/cddl')
6 files changed, 121 insertions, 97 deletions
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 |