[CFR][ZFS] merge Illumos rev. 13370 (resurrect "aclmode" property)

Pawel Jakub Dawidek pjd at FreeBSD.org
Wed Jun 29 17:54:13 UTC 2011


On Mon, Jun 20, 2011 at 11:16:35AM +0200, Martin Matuska wrote:
> Resurrect "aclmode" property for ZFS.
> The Illumos changeset includes Issues submitted by trasz (279, 664).
> 
> https://www.illumos.org/issues/742
> https://www.illumos.org/issues/664
> https://www.illumos.org/issues/279
> https://www.illumos.org/projects/illumos-gate/repository/revisions/13370
> 
> If there are no objections, I will commit this to -HEAD.

No objection from me, although I'd prefer to wait for Edward's opinion.
AFAIK he is also fine, but we should wait. It may take a short while as
he just become a father:)

> Index: cddl/contrib/opensolaris/cmd/zfs/zfs.8
> ===================================================================
> --- cddl/contrib/opensolaris/cmd/zfs/zfs.8	(revision 223325)
> +++ cddl/contrib/opensolaris/cmd/zfs/zfs.8	(working copy)
> @@ -6,6 +6,7 @@
>  .\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License").  You may not use this file except in compliance with the License. You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing.
>  .\"  See the License for the specific language governing permissions and limitations under the License. When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE.  If applicable, add the following below this CDDL HEADER, with
>  .\" the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
> +.\" Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
>  .TH zfs 1M "24 Sep 2009" "SunOS 5.11" "System Administration Commands"
>  .SH NAME
>  zfs \- configures ZFS file systems
> @@ -630,7 +631,7 @@
>  .ad
>  .sp .6
>  .RS 4n
> -Controls how an \fBACL\fR is modified during \fBchmod\fR(2). A file system with an \fBaclmode\fR property of \fBdiscard\fR deletes all \fBACL\fR entries that do not represent the mode of the file. An \fBaclmode\fR property of \fBgroupmask\fR (the default) reduces user or group permissions. The permissions are reduced, such that they are no greater than the group permission bits, unless it is a user entry that has the same \fBUID\fR as the owner of the file or directory. In this case, the \fBACL\fR permissions are reduced so that they are no greater than owner permission bits. A file system with an \fBaclmode\fR property of \fBpassthrough\fR indicates that no changes are made to the \fBACL\fR other than generating the necessary \fBACL\fR entries to represent the new mode of the file or directory.
> +Controls how an \fBACL\fR is modified during \fBchmod\fR(2). A file system with an \fBaclmode\fR property of \fBdiscard\fR (the default) deletes all \fBACL\fR entries that do not represent the mode of the file. An \fBaclmode\fR property of \fBgroupmask\fR reduces permissions granted in all \fBALLOW\fR entries found in the \fBACL\fR such that they are no greater than the group permissions specified by \fBchmod\fR.  A file system with an \fBaclmode\fR property of \fBpassthrough\fR indicates that no changes are made to the \fBACL\fR other than creating or updating the necessary \fBACL\fR entries to represent the new mode of the file or directory.
>  .RE
>  
>  .sp
> @@ -2685,7 +2686,7 @@
>  pool/home/bob  readonly              off                    default
>  pool/home/bob  zoned                 off                    default
>  pool/home/bob  snapdir               hidden                 default
> -pool/home/bob  aclmode               groupmask              default
> +pool/home/bob  aclmode               discard                default
>  pool/home/bob  aclinherit            restricted             default
>  pool/home/bob  canmount              on                     default
>  pool/home/bob  shareiscsi            off                    default
> Index: sys/cddl/contrib/opensolaris/common/acl/acl_common.c
> ===================================================================
> --- sys/cddl/contrib/opensolaris/common/acl/acl_common.c	(revision 223325)
> +++ sys/cddl/contrib/opensolaris/common/acl/acl_common.c	(working copy)
> @@ -20,6 +20,7 @@
>   */
>  /*
>   * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
> + * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
>   */
>  
>  #include <sys/types.h>
> @@ -376,7 +377,7 @@
>   * by nfsace, assuming aclent_t -> nfsace semantics.
>   */
>  static uint32_t
> -mode_to_ace_access(mode_t mode, int isdir, int isowner, int isallow)
> +mode_to_ace_access(mode_t mode, boolean_t isdir, int isowner, int isallow)
>  {
>  	uint32_t access = 0;
>  	int haswriteperm = 0;
> @@ -419,7 +420,7 @@
>  			access |= ACE_DELETE_CHILD;
>  	}
>  	/* exec */
> -	if (mode & 01) {
> +	if (mode & S_IXOTH) {
>  		access |= ACE_EXECUTE;
>  	}
>  
> @@ -670,7 +671,7 @@
>  }
>  
>  static int
> -convert_aent_to_ace(aclent_t *aclentp, int aclcnt, int isdir,
> +convert_aent_to_ace(aclent_t *aclentp, int aclcnt, boolean_t isdir,
>      ace_t **retacep, int *retacecnt)
>  {
>  	ace_t *acep;
> @@ -696,7 +697,7 @@
>  		dfaclcnt = aclcnt - i;
>  	}
>  
> -	if (dfaclcnt && isdir == 0) {
> +	if (dfaclcnt && !isdir) {
>  		return (EINVAL);
>  	}
>  
> @@ -734,7 +735,7 @@
>  }
>  
>  static int
> -ace_mask_to_mode(uint32_t  mask, o_mode_t *modep, int isdir)
> +ace_mask_to_mode(uint32_t  mask, o_mode_t *modep, boolean_t isdir)
>  {
>  	int error = 0;
>  	o_mode_t mode = 0;
> @@ -1031,7 +1032,7 @@
>  }
>  
>  static int
> -ace_allow_to_mode(uint32_t mask, o_mode_t *modep, int isdir)
> +ace_allow_to_mode(uint32_t mask, o_mode_t *modep, boolean_t isdir)
>  {
>  	/* ACE_READ_ACL and ACE_READ_ATTRIBUTES must both be set */
>  	if ((mask & (ACE_READ_ACL | ACE_READ_ATTRIBUTES)) !=
> @@ -1044,7 +1045,7 @@
>  
>  static int
>  acevals_to_aent(acevals_t *vals, aclent_t *dest, ace_list_t *list,
> -    uid_t owner, gid_t group, int isdir)
> +    uid_t owner, gid_t group, boolean_t isdir)
>  {
>  	int error;
>  	uint32_t  flips = ACE_POSIX_SUPPORTED_BITS;
> @@ -1084,7 +1085,7 @@
>  
>  static int
>  ace_list_to_aent(ace_list_t *list, aclent_t **aclentp, int *aclcnt,
> -    uid_t owner, gid_t group, int isdir)
> +    uid_t owner, gid_t group, boolean_t isdir)
>  {
>  	int error = 0;
>  	aclent_t *aent, *result = NULL;
> @@ -1264,7 +1265,7 @@
>  static int
>  ln_ace_to_aent(ace_t *ace, int n, uid_t owner, gid_t group,
>      aclent_t **aclentp, int *aclcnt, aclent_t **dfaclentp, int *dfaclcnt,
> -    int isdir)
> +    boolean_t isdir)
>  {
>  	int error = 0;
>  	ace_t *acep;
> @@ -1459,7 +1460,7 @@
>  }
>  
>  static int
> -convert_ace_to_aent(ace_t *acebufp, int acecnt, int isdir,
> +convert_ace_to_aent(ace_t *acebufp, int acecnt, boolean_t isdir,
>      uid_t owner, gid_t group, aclent_t **retaclentp, int *retaclcnt)
>  {
>  	int error = 0;
> @@ -1501,7 +1502,7 @@
>  
>  
>  int
> -acl_translate(acl_t *aclp, int target_flavor, int isdir, uid_t owner,
> +acl_translate(acl_t *aclp, int target_flavor, boolean_t isdir, uid_t owner,
>      gid_t group)
>  {
>  	int aclcnt;
> @@ -1573,101 +1574,105 @@
>  }
>  
>  void
> -acl_trivial_access_masks(mode_t mode, uint32_t *allow0, uint32_t *deny1,
> -    uint32_t *deny2, uint32_t *owner, uint32_t *group, uint32_t *everyone)
> +acl_trivial_access_masks(mode_t mode, boolean_t isdir, trivial_acl_t *masks)
>  {
> -	*deny1 = *deny2 = *allow0 = *group = 0;
> +	uint32_t read_mask = ACE_READ_DATA;
> +	uint32_t write_mask = ACE_WRITE_DATA|ACE_APPEND_DATA;
> +	uint32_t execute_mask = ACE_EXECUTE;
>  
> +	(void) isdir;	/* will need this later */
> +
> +	masks->deny1 = 0;
>  	if (!(mode & S_IRUSR) && (mode & (S_IRGRP|S_IROTH)))
> -		*deny1 |= ACE_READ_DATA;
> +		masks->deny1 |= read_mask;
>  	if (!(mode & S_IWUSR) && (mode & (S_IWGRP|S_IWOTH)))
> -		*deny1 |= ACE_WRITE_DATA|ACE_APPEND_DATA;
> +		masks->deny1 |= write_mask;
>  	if (!(mode & S_IXUSR) && (mode & (S_IXGRP|S_IXOTH)))
> -		*deny1 |= ACE_EXECUTE;
> +		masks->deny1 |= execute_mask;
>  
> +	masks->deny2 = 0;
>  	if (!(mode & S_IRGRP) && (mode & S_IROTH))
> -		*deny2 = ACE_READ_DATA;
> +		masks->deny2 |= read_mask;
>  	if (!(mode & S_IWGRP) && (mode & S_IWOTH))
> -		*deny2 |= ACE_WRITE_DATA|ACE_APPEND_DATA;
> +		masks->deny2 |= write_mask;
>  	if (!(mode & S_IXGRP) && (mode & S_IXOTH))
> -		*deny2 |= ACE_EXECUTE;
> +		masks->deny2 |= execute_mask;
>  
> +	masks->allow0 = 0;
>  	if ((mode & S_IRUSR) && (!(mode & S_IRGRP) && (mode & S_IROTH)))
> -		*allow0 |= ACE_READ_DATA;
> +		masks->allow0 |= read_mask;
>  	if ((mode & S_IWUSR) && (!(mode & S_IWGRP) && (mode & S_IWOTH)))
> -		*allow0 |= ACE_WRITE_DATA|ACE_APPEND_DATA;
> +		masks->allow0 |= write_mask;
>  	if ((mode & S_IXUSR) && (!(mode & S_IXGRP) && (mode & S_IXOTH)))
> -		*allow0 |= ACE_EXECUTE;
> +		masks->allow0 |= execute_mask;
>  
> -	*owner = ACE_WRITE_ATTRIBUTES|ACE_WRITE_OWNER|ACE_WRITE_ACL|
> +	masks->owner = ACE_WRITE_ATTRIBUTES|ACE_WRITE_OWNER|ACE_WRITE_ACL|
>  	    ACE_WRITE_NAMED_ATTRS|ACE_READ_ACL|ACE_READ_ATTRIBUTES|
>  	    ACE_READ_NAMED_ATTRS|ACE_SYNCHRONIZE;
>  	if (mode & S_IRUSR)
> -		*owner |= ACE_READ_DATA;
> +		masks->owner |= read_mask;
>  	if (mode & S_IWUSR)
> -		*owner |= ACE_WRITE_DATA|ACE_APPEND_DATA;
> +		masks->owner |= write_mask;
>  	if (mode & S_IXUSR)
> -		*owner |= ACE_EXECUTE;
> +		masks->owner |= execute_mask;
>  
> -	*group = ACE_READ_ACL|ACE_READ_ATTRIBUTES| ACE_READ_NAMED_ATTRS|
> +	masks->group = ACE_READ_ACL|ACE_READ_ATTRIBUTES|ACE_READ_NAMED_ATTRS|
>  	    ACE_SYNCHRONIZE;
>  	if (mode & S_IRGRP)
> -		*group |= ACE_READ_DATA;
> +		masks->group |= read_mask;
>  	if (mode & S_IWGRP)
> -		*group |= ACE_WRITE_DATA|ACE_APPEND_DATA;
> +		masks->group |= write_mask;
>  	if (mode & S_IXGRP)
> -		*group |= ACE_EXECUTE;
> +		masks->group |= execute_mask;
>  
> -	*everyone = ACE_READ_ACL|ACE_READ_ATTRIBUTES| ACE_READ_NAMED_ATTRS|
> +	masks->everyone = ACE_READ_ACL|ACE_READ_ATTRIBUTES|ACE_READ_NAMED_ATTRS|
>  	    ACE_SYNCHRONIZE;
>  	if (mode & S_IROTH)
> -		*everyone |= ACE_READ_DATA;
> +		masks->everyone |= read_mask;
>  	if (mode & S_IWOTH)
> -		*everyone |= ACE_WRITE_DATA|ACE_APPEND_DATA;
> +		masks->everyone |= write_mask;
>  	if (mode & S_IXOTH)
> -		*everyone |= ACE_EXECUTE;
> +		masks->everyone |= execute_mask;
>  }
>  
>  int
> -acl_trivial_create(mode_t mode, ace_t **acl, int *count)
> +acl_trivial_create(mode_t mode, boolean_t isdir, ace_t **acl, int *count)
>  {
> -	uint32_t	deny1, deny2;
> -	uint32_t	allow0;
> -	uint32_t	owner, group, everyone;
> -	int 		index = 0;
> +	int		index = 0;
>  	int		error;
> +	trivial_acl_t	masks;
>  
>  	*count = 3;
> -	acl_trivial_access_masks(mode, &allow0, &deny1, &deny2, &owner, &group,
> -	    &everyone);
> +	acl_trivial_access_masks(mode, isdir, &masks);
>  
> -	if (allow0)
> +	if (masks.allow0)
>  		(*count)++;
> -	if (deny1)
> +	if (masks.deny1)
>  		(*count)++;
> -	if (deny2)
> +	if (masks.deny2)
>  		(*count)++;
>  
>  	if ((error = cacl_malloc((void **)acl, *count * sizeof (ace_t))) != 0)
>  		return (error);
>  
> -	if (allow0) {
> -		SET_ACE(acl, index, -1, allow0, ACE_ACCESS_ALLOWED_ACE_TYPE,
> -		    ACE_OWNER);
> +	if (masks.allow0) {
> +		SET_ACE(acl, index, -1, masks.allow0,
> +		    ACE_ACCESS_ALLOWED_ACE_TYPE, ACE_OWNER);
>  	}
> -	if (deny1) {
> -		SET_ACE(acl, index, -1, deny1, ACE_ACCESS_DENIED_ACE_TYPE,
> -		    ACE_OWNER);
> +	if (masks.deny1) {
> +		SET_ACE(acl, index, -1, masks.deny1,
> +		    ACE_ACCESS_DENIED_ACE_TYPE, ACE_OWNER);
>  	}
> -	if (deny2) {
> -		SET_ACE(acl, index, -1, deny2, ACE_ACCESS_DENIED_ACE_TYPE,
> -		    ACE_GROUP|ACE_IDENTIFIER_GROUP);
> +	if (masks.deny2) {
> +		SET_ACE(acl, index, -1, masks.deny2,
> +		    ACE_ACCESS_DENIED_ACE_TYPE, ACE_GROUP|ACE_IDENTIFIER_GROUP);
>  	}
>  
> -	SET_ACE(acl, index, -1, owner, ACE_ACCESS_ALLOWED_ACE_TYPE, ACE_OWNER);
> -	SET_ACE(acl, index, -1, group, ACE_ACCESS_ALLOWED_ACE_TYPE,
> +	SET_ACE(acl, index, -1, masks.owner, ACE_ACCESS_ALLOWED_ACE_TYPE,
> +	    ACE_OWNER);
> +	SET_ACE(acl, index, -1, masks.group, ACE_ACCESS_ALLOWED_ACE_TYPE,
>  	    ACE_IDENTIFIER_GROUP|ACE_GROUP);
> -	SET_ACE(acl, index, -1, everyone, ACE_ACCESS_ALLOWED_ACE_TYPE,
> +	SET_ACE(acl, index, -1, masks.everyone, ACE_ACCESS_ALLOWED_ACE_TYPE,
>  	    ACE_EVERYONE);
>  
>  	return (0);
> Index: sys/cddl/contrib/opensolaris/common/acl/acl_common.h
> ===================================================================
> --- sys/cddl/contrib/opensolaris/common/acl/acl_common.h	(revision 223325)
> +++ sys/cddl/contrib/opensolaris/common/acl/acl_common.h	(working copy)
> @@ -20,6 +20,7 @@
>   */
>  /*
>   * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
> + * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
>   */
>  
>  #ifndef	_ACL_COMMON_H
> @@ -33,7 +34,14 @@
>  extern "C" {
>  #endif
>  
> -extern ace_t trivial_acl[6];
> +typedef struct trivial_acl {
> +	uint32_t	allow0;		/* allow mask for bits only in owner */
> +	uint32_t	deny1;		/* deny mask for bits not in owner */
> +	uint32_t	deny2;		/* deny mask for bits not in group */
> +	uint32_t	owner;		/* allow mask matching mode */
> +	uint32_t	group;		/* allow mask matching mode */
> +	uint32_t	everyone;	/* allow mask matching mode */
> +} trivial_acl_t;
>  
>  extern int acltrivial(const char *);
>  extern void adjust_ace_pair(ace_t *pair, mode_t mode);
> @@ -45,14 +53,14 @@
>  #if !defined(_KERNEL)
>  extern acl_t *acl_alloc(acl_type_t);
>  extern void acl_free(acl_t *aclp);
> -extern int acl_translate(acl_t *aclp, int target_flavor,
> -    int isdir, uid_t owner, gid_t group);
> +extern int acl_translate(acl_t *aclp, int target_flavor, boolean_t isdir,
> +    uid_t owner, gid_t group);
>  #endif	/* !_KERNEL */
>  void ksort(caddr_t v, int n, int s, int (*f)());
>  int cmp2acls(void *a, void *b);
> -int acl_trivial_create(mode_t mode, ace_t **acl, int *count);
> -void acl_trivial_access_masks(mode_t mode, uint32_t *allow0, uint32_t *deny1,
> -    uint32_t *deny2, uint32_t *owner, uint32_t *group, uint32_t *everyone);
> +int acl_trivial_create(mode_t mode, boolean_t isdir, ace_t **acl, int *count);
> +void acl_trivial_access_masks(mode_t mode, boolean_t isdir,
> +    trivial_acl_t *masks);
>  
>  #ifdef	__cplusplus
>  }
> Index: sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c
> ===================================================================
> --- sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c	(revision 223325)
> +++ sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c	(working copy)
> @@ -104,6 +104,13 @@
>  		{ NULL }
>  	};
>  
> +	static zprop_index_t acl_mode_table[] = {
> +		{ "discard",	ZFS_ACL_DISCARD },
> +		{ "groupmask",	ZFS_ACL_GROUPMASK },
> +		{ "passthrough", ZFS_ACL_PASSTHROUGH },
> +		{ NULL }
> +	};
> +
>  	static zprop_index_t acl_inherit_table[] = {
>  		{ "discard",	ZFS_ACL_DISCARD },
>  		{ "noallow",	ZFS_ACL_NOALLOW },
> @@ -207,6 +214,9 @@
>  	zprop_register_index(ZFS_PROP_SNAPDIR, "snapdir", ZFS_SNAPDIR_HIDDEN,
>  	    PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
>  	    "hidden | visible", "SNAPDIR", snapdir_table);
> +	zprop_register_index(ZFS_PROP_ACLMODE, "aclmode", ZFS_ACL_DISCARD,
> +	    PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
> +	    "discard | groupmask | passthrough", "ACLMODE", acl_mode_table);
>  	zprop_register_index(ZFS_PROP_ACLINHERIT, "aclinherit",
>  	    ZFS_ACL_RESTRICTED, PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
>  	    "discard | noallow | restricted | passthrough | passthrough-x",
> @@ -370,13 +380,6 @@
>  	zprop_register_hidden(ZFS_PROP_OBJSETID, "objsetid", PROP_TYPE_NUMBER,
>  	    PROP_READONLY, ZFS_TYPE_DATASET, "OBJSETID");
>  
> -	/*
> -	 * Property to be removed once libbe is integrated
> -	 */
> -	zprop_register_hidden(ZFS_PROP_PRIVATE, "priv_prop",
> -	    PROP_TYPE_NUMBER, PROP_READONLY, ZFS_TYPE_FILESYSTEM,
> -	    "PRIV_PROP");
> -
>  	/* oddball properties */
>  	zprop_register_impl(ZFS_PROP_CREATION, "creation", PROP_TYPE_NUMBER, 0,
>  	    NULL, PROP_READONLY, ZFS_TYPE_DATASET,
> Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
> ===================================================================
> --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c	(revision 223325)
> +++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c	(working copy)
> @@ -3223,7 +3223,8 @@
>  		uint64_t acl_obj;
>  		new_mode = (pmode & S_IFMT) | (vap->va_mode & ~S_IFMT);
>  
> -		zfs_acl_chmod_setattr(zp, &aclp, new_mode);
> +		if (err = zfs_acl_chmod_setattr(zp, &aclp, new_mode))
> +			goto out;
>  
>  		mutex_enter(&zp->z_lock);
>  		if (!zp->z_is_sa && ((acl_obj = zfs_external_acl(zp)) != 0)) {
> Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
> ===================================================================
> --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c	(revision 223325)
> +++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c	(working copy)
> @@ -364,6 +364,14 @@
>  }
>  
>  static void
> +acl_mode_changed_cb(void *arg, uint64_t newval)
> +{
> +	zfsvfs_t *zfsvfs = arg;
> +
> +	zfsvfs->z_acl_mode = newval;
> +}
> +
> +static void
>  acl_inherit_changed_cb(void *arg, uint64_t newval)
>  {
>  	zfsvfs_t *zfsvfs = arg;
> @@ -488,6 +496,8 @@
>  	error = error ? error : dsl_prop_register(ds,
>  	    "snapdir", snapdir_changed_cb, zfsvfs);
>  	error = error ? error : dsl_prop_register(ds,
> +	    "aclmode", acl_mode_changed_cb, zfsvfs);
> +	error = error ? error : dsl_prop_register(ds,
>  	    "aclinherit", acl_inherit_changed_cb, zfsvfs);
>  	error = error ? error : dsl_prop_register(ds,
>  	    "vscan", vscan_changed_cb, zfsvfs);
> @@ -525,6 +535,7 @@
>  	(void) dsl_prop_unregister(ds, "setuid", setuid_changed_cb, zfsvfs);
>  	(void) dsl_prop_unregister(ds, "exec", exec_changed_cb, zfsvfs);
>  	(void) dsl_prop_unregister(ds, "snapdir", snapdir_changed_cb, zfsvfs);
> +	(void) dsl_prop_unregister(ds, "aclmode", acl_mode_changed_cb, zfsvfs);
>  	(void) dsl_prop_unregister(ds, "aclinherit", acl_inherit_changed_cb,
>  	    zfsvfs);
>  	(void) dsl_prop_unregister(ds, "vscan", vscan_changed_cb, zfsvfs);
> @@ -1202,6 +1213,9 @@
>  		VERIFY(dsl_prop_unregister(ds, "snapdir", snapdir_changed_cb,
>  		    zfsvfs) == 0);
>  
> +		VERIFY(dsl_prop_unregister(ds, "aclmode", acl_mode_changed_cb,
> +		    zfsvfs) == 0);
> +
>  		VERIFY(dsl_prop_unregister(ds, "aclinherit",
>  		    acl_inherit_changed_cb, zfsvfs) == 0);
>  
> Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c
> ===================================================================
> --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c	(revision 223325)
> +++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c	(working copy)
> @@ -20,6 +20,7 @@
>   */
>  /*
>   * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
> + * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
>   */
>  
>  #include <sys/types.h>
> @@ -1327,76 +1328,9 @@
>  	return (sa_bulk_update(zp->z_sa_hdl, bulk, count, tx));
>  }
>  
> -/*
> - * Update access mask for prepended ACE
> - *
> - * This applies the "groupmask" value for aclmode property.
> - */
>  static void
> -zfs_acl_prepend_fixup(zfs_acl_t *aclp, void  *acep, void  *origacep,
> -    mode_t mode, uint64_t owner)
> +zfs_acl_chmod(vtype_t vtype, uint64_t mode, boolean_t trim, zfs_acl_t *aclp)
>  {
> -	int	rmask, wmask, xmask;
> -	int	user_ace;
> -	uint16_t aceflags;
> -	uint32_t origmask, acepmask;
> -	uint64_t fuid;
> -
> -	aceflags = aclp->z_ops.ace_flags_get(acep);
> -	fuid = aclp->z_ops.ace_who_get(acep);
> -	origmask = aclp->z_ops.ace_mask_get(origacep);
> -	acepmask = aclp->z_ops.ace_mask_get(acep);
> -
> -	user_ace = (!(aceflags &
> -	    (ACE_OWNER|ACE_GROUP|ACE_IDENTIFIER_GROUP)));
> -
> -	if (user_ace && (fuid == owner)) {
> -		rmask = S_IRUSR;
> -		wmask = S_IWUSR;
> -		xmask = S_IXUSR;
> -	} else {
> -		rmask = S_IRGRP;
> -		wmask = S_IWGRP;
> -		xmask = S_IXGRP;
> -	}
> -
> -	if (origmask & ACE_READ_DATA) {
> -		if (mode & rmask) {
> -			acepmask &= ~ACE_READ_DATA;
> -		} else {
> -			acepmask |= ACE_READ_DATA;
> -		}
> -	}
> -
> -	if (origmask & ACE_WRITE_DATA) {
> -		if (mode & wmask) {
> -			acepmask &= ~ACE_WRITE_DATA;
> -		} else {
> -			acepmask |= ACE_WRITE_DATA;
> -		}
> -	}
> -
> -	if (origmask & ACE_APPEND_DATA) {
> -		if (mode & wmask) {
> -			acepmask &= ~ACE_APPEND_DATA;
> -		} else {
> -			acepmask |= ACE_APPEND_DATA;
> -		}
> -	}
> -
> -	if (origmask & ACE_EXECUTE) {
> -		if (mode & xmask) {
> -			acepmask &= ~ACE_EXECUTE;
> -		} else {
> -			acepmask |= ACE_EXECUTE;
> -		}
> -	}
> -	aclp->z_ops.ace_mask_set(acep, acepmask);
> -}
> -
> -static void
> -zfs_acl_chmod(zfsvfs_t *zfsvfs, uint64_t mode, zfs_acl_t *aclp)
> -{
>  	void		*acep = NULL;
>  	uint64_t	who;
>  	int		new_count, new_bytes;
> @@ -1407,30 +1341,31 @@
>  	zfs_acl_node_t	*newnode;
>  	size_t 		abstract_size = aclp->z_ops.ace_abstract_size();
>  	void 		*zacep;
> -	uint32_t 	owner, group, everyone;
> -	uint32_t	deny1, deny2, allow0;
> +	boolean_t	isdir;
> +	trivial_acl_t	masks;
>  
>  	new_count = new_bytes = 0;
>  
> -	acl_trivial_access_masks((mode_t)mode, &allow0, &deny1, &deny2,
> -	    &owner, &group, &everyone);
> +	isdir = (vtype == VDIR);
>  
> +	acl_trivial_access_masks((mode_t)mode, isdir, &masks);
> +
>  	newnode = zfs_acl_node_alloc((abstract_size * 6) + aclp->z_acl_bytes);
>  
>  	zacep = newnode->z_acldata;
> -	if (allow0) {
> -		zfs_set_ace(aclp, zacep, allow0, ALLOW, -1, ACE_OWNER);
> +	if (masks.allow0) {
> +		zfs_set_ace(aclp, zacep, masks.allow0, ALLOW, -1, ACE_OWNER);
>  		zacep = (void *)((uintptr_t)zacep + abstract_size);
>  		new_count++;
>  		new_bytes += abstract_size;
> -	} if (deny1) {
> -		zfs_set_ace(aclp, zacep, deny1, DENY, -1, ACE_OWNER);
> +	} if (masks.deny1) {
> +		zfs_set_ace(aclp, zacep, masks.deny1, DENY, -1, ACE_OWNER);
>  		zacep = (void *)((uintptr_t)zacep + abstract_size);
>  		new_count++;
>  		new_bytes += abstract_size;
>  	}
> -	if (deny2) {
> -		zfs_set_ace(aclp, zacep, deny2, DENY, -1, OWNING_GROUP);
> +	if (masks.deny2) {
> +		zfs_set_ace(aclp, zacep, masks.deny2, DENY, -1, OWNING_GROUP);
>  		zacep = (void *)((uintptr_t)zacep + abstract_size);
>  		new_count++;
>  		new_bytes += abstract_size;
> @@ -1449,10 +1384,17 @@
>  			continue;
>  		}
>  
> +		/*
> +		 * If this ACL has any inheritable ACEs, mark that in
> +		 * the hints (which are later masked into the pflags)
> +		 * so create knows to do inheritance.
> +		 */
> +		if (isdir && (inherit_flags &
> +		    (ACE_FILE_INHERIT_ACE|ACE_DIRECTORY_INHERIT_ACE)))
> +			aclp->z_hints |= ZFS_INHERIT_ACE;
> +
>  		if ((type != ALLOW && type != DENY) ||
>  		    (inherit_flags & ACE_INHERIT_ONLY_ACE)) {
> -			if (inherit_flags)
> -				aclp->z_hints |= ZFS_INHERIT_ACE;
>  			switch (type) {
>  			case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
>  			case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE:
> @@ -1465,20 +1407,13 @@
>  
>  			/*
>  			 * Limit permissions to be no greater than
> -			 * group permissions
> +			 * group permissions.
> +			 * The "aclinherit" and "aclmode" properties
> +			 * affect policy for create and chmod(2),
> +			 * respectively.
>  			 */
> -			if (type == ALLOW && zfsvfs->z_acl_inherit == ZFS_ACL_RESTRICTED) {
> -				if (!(mode & S_IRGRP))
> -					access_mask &= ~ACE_READ_DATA;
> -				if (!(mode & S_IWGRP))
> -					access_mask &=
> -					    ~(ACE_WRITE_DATA|ACE_APPEND_DATA);
> -				if (!(mode & S_IXGRP))
> -					access_mask &= ~ACE_EXECUTE;
> -				access_mask &=
> -				    ~(ACE_WRITE_OWNER|ACE_WRITE_ACL|
> -				    ACE_WRITE_ATTRIBUTES|ACE_WRITE_NAMED_ATTRS);
> -			}
> +			if ((type == ALLOW) && trim)
> +				access_mask &= masks.group;
>  		}
>  		zfs_set_ace(aclp, zacep, access_mask, type, who, iflags);
>  		ace_size = aclp->z_ops.ace_size(acep);
> @@ -1486,11 +1421,11 @@
>  		new_count++;
>  		new_bytes += ace_size;
>  	}
> -	zfs_set_ace(aclp, zacep, owner, 0, -1, ACE_OWNER);
> +	zfs_set_ace(aclp, zacep, masks.owner, 0, -1, ACE_OWNER);
>  	zacep = (void *)((uintptr_t)zacep + abstract_size);
> -	zfs_set_ace(aclp, zacep, group, 0, -1, OWNING_GROUP);
> +	zfs_set_ace(aclp, zacep, masks.group, 0, -1, OWNING_GROUP);
>  	zacep = (void *)((uintptr_t)zacep + abstract_size);
> -	zfs_set_ace(aclp, zacep, everyone, 0, -1, ACE_EVERYONE);
> +	zfs_set_ace(aclp, zacep, masks.everyone, 0, -1, ACE_EVERYONE);
>  
>  	new_count += 3;
>  	new_bytes += abstract_size * 3;
> @@ -1502,17 +1437,27 @@
>  	list_insert_tail(&aclp->z_acl, newnode);
>  }
>  
> -void
> +int
>  zfs_acl_chmod_setattr(znode_t *zp, zfs_acl_t **aclp, uint64_t mode)
>  {
> +	int error = 0;
> +
>  	mutex_enter(&zp->z_acl_lock);
>  	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);
> +	if (zp->z_zfsvfs->z_acl_mode == ZFS_ACL_DISCARD)
> +		*aclp = zfs_acl_alloc(zfs_acl_version_zp(zp));
> +	else
> +		error = zfs_acl_node_read(zp, B_TRUE, aclp, B_TRUE);
> +
> +	if (error == 0) {
> +		(*aclp)->z_hints = zp->z_pflags & V4_ACL_WIDE_FLAGS;
> +		zfs_acl_chmod(ZTOV(zp)->v_type, mode,
> +		    (zp->z_zfsvfs->z_acl_mode == ZFS_ACL_GROUPMASK), *aclp);
> +	}
>  	mutex_exit(&zp->z_lock);
>  	mutex_exit(&zp->z_acl_lock);
> -	ASSERT(*aclp);
> +
> +	return (error);
>  }
>  
>  /*
> @@ -1764,8 +1709,8 @@
>  	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 &&
> -		    (dzp->z_pflags & ZFS_INHERIT_ACE)) &&
> +		if (!(flag & IS_ROOT_NODE) &&
> +		    (dzp->z_pflags & ZFS_INHERIT_ACE) &&
>  		    !(dzp->z_pflags & ZFS_XATTR)) {
>  			VERIFY(0 == zfs_acl_node_read(dzp, B_TRUE,
>  			    &paclp, B_FALSE));
> @@ -1782,7 +1727,9 @@
>  		if (need_chmod) {
>  			acl_ids->z_aclp->z_hints |= (vap->va_type == VDIR) ?
>  			    ZFS_ACL_AUTO_INHERIT : 0;
> -			zfs_acl_chmod(zfsvfs, acl_ids->z_mode, acl_ids->z_aclp);
> +			zfs_acl_chmod(vap->va_type, acl_ids->z_mode,
> +			    (zfsvfs->z_acl_inherit == ZFS_ACL_RESTRICTED),
> +			    acl_ids->z_aclp);
>  		}
>  	}
>  
> Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_vfsops.h
> ===================================================================
> --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_vfsops.h	(revision 223325)
> +++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_vfsops.h	(working copy)
> @@ -55,6 +55,7 @@
>  	boolean_t	z_fuid_dirty;   /* need to sync fuid table ? */
>  	struct zfs_fuid_info	*z_fuid_replay; /* fuid info for replay */
>  	zilog_t		*z_log;		/* intent log pointer */
> +	uint_t		z_acl_mode;	/* acl chmod/mode behavior */
>  	uint_t		z_acl_inherit;	/* acl inheritance behavior */
>  	zfs_case_t	z_case;		/* case-sense */
>  	boolean_t	z_utf8;		/* utf8-only */
> Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_acl.h
> ===================================================================
> --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_acl.h	(revision 223325)
> +++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_acl.h	(working copy)
> @@ -217,7 +217,7 @@
>  extern int zfs_zaccess_rwx(struct znode *, mode_t, int, cred_t *);
>  extern int zfs_zaccess_unix(struct znode *, mode_t, cred_t *);
>  extern int zfs_acl_access(struct znode *, int, cred_t *);
> -void zfs_acl_chmod_setattr(struct znode *, zfs_acl_t **, uint64_t);
> +int zfs_acl_chmod_setattr(struct znode *, zfs_acl_t **, uint64_t);
>  int zfs_zaccess_delete(struct znode *, struct znode *, cred_t *);
>  int zfs_zaccess_rename(struct znode *, struct znode *,
>      struct znode *, struct znode *, cred_t *cr);
> Index: sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h
> ===================================================================
> --- sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h	(revision 223325)
> +++ sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h	(working copy)
> @@ -89,7 +89,7 @@
>  	ZFS_PROP_READONLY,
>  	ZFS_PROP_ZONED,
>  	ZFS_PROP_SNAPDIR,
> -	ZFS_PROP_PRIVATE,		/* not exposed to user, temporary */
> +	ZFS_PROP_ACLMODE,
>  	ZFS_PROP_ACLINHERIT,
>  	ZFS_PROP_CREATETXG,		/* not exposed to the user */
>  	ZFS_PROP_NAME,			/* not exposed to the user */
> 

-- 
Pawel Jakub Dawidek                       http://www.wheelsystems.com
FreeBSD committer                         http://www.FreeBSD.org
Am I Evil? Yes, I Am!                     http://yomoli.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 196 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/zfs-devel/attachments/20110629/dfebb926/attachment-0001.pgp


More information about the zfs-devel mailing list