svn commit: r214626 - in stable/8: lib/libc/posix1e sys/kern sys/sys

Edward Tomasz Napierala trasz at FreeBSD.org
Mon Nov 1 15:36:48 UTC 2010


Author: trasz
Date: Mon Nov  1 15:36:47 2010
New Revision: 214626
URL: http://svn.freebsd.org/changeset/base/214626

Log:
  MFC r212906:
  
  First step at adopting FreeBSD to support PSARC/2010/029.  This makes
  acl_is_trivial_np(3) properly recognize the new trivial ACLs.  From
  the user point of view, that means "ls -l" no longer shows plus signs
  for all the files when running ZFS v28.

Modified:
  stable/8/lib/libc/posix1e/acl_strip.c
  stable/8/sys/kern/subr_acl_nfs4.c
  stable/8/sys/sys/acl.h
Directory Properties:
  stable/8/lib/libc/   (props changed)
  stable/8/lib/libc/locale/   (props changed)
  stable/8/lib/libc/stdtime/   (props changed)
  stable/8/lib/libc/sys/   (props changed)
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/lib/libc/posix1e/acl_strip.c
==============================================================================
--- stable/8/lib/libc/posix1e/acl_strip.c	Mon Nov  1 15:18:57 2010	(r214625)
+++ stable/8/lib/libc/posix1e/acl_strip.c	Mon Nov  1 15:36:47 2010	(r214626)
@@ -31,19 +31,21 @@ __FBSDID("$FreeBSD$");
 #include <stdio.h>
 #include <assert.h>
 #include <sys/acl.h>
+#include <sys/stat.h>
 
 #include "acl_support.h"
 
 /*
- * These two routines from sys/kern/subr_acl_nfs4.c are used by both kernel
+ * These three routines from sys/kern/subr_acl_nfs4.c are used by both kernel
  * and libc.
  */
+void	acl_nfs4_trivial_from_mode(struct acl *aclp, mode_t mode);
 void	acl_nfs4_sync_acl_from_mode(struct acl *aclp, mode_t mode,
 	    int file_owner_id);
 void	acl_nfs4_sync_mode_from_acl(mode_t *_mode, const struct acl *aclp);
 
 static acl_t
-_nfs4_acl_strip_np(const acl_t aclp, int recalculate_mask)
+_nfs4_acl_strip_np(const acl_t aclp, int canonical_six)
 {
 	acl_t newacl;
 	mode_t mode = 0;
@@ -57,7 +59,10 @@ _nfs4_acl_strip_np(const acl_t aclp, int
 	_acl_brand_as(newacl, ACL_BRAND_NFS4);
 
 	acl_nfs4_sync_mode_from_acl(&mode, &(aclp->ats_acl));
-	acl_nfs4_sync_acl_from_mode(&(newacl->ats_acl), mode, -1);
+	if (canonical_six)
+		acl_nfs4_sync_acl_from_mode(&(newacl->ats_acl), mode, -1);
+	else
+		acl_nfs4_trivial_from_mode(&(newacl->ats_acl), mode);
 
 	return (newacl);
 }
@@ -136,7 +141,7 @@ acl_strip_np(const acl_t aclp, int recal
 {
 	switch (_acl_brand(aclp)) {
 	case ACL_BRAND_NFS4:
-		return (_nfs4_acl_strip_np(aclp, recalculate_mask));
+		return (_nfs4_acl_strip_np(aclp, 1));
 
 	case ACL_BRAND_POSIX:
 		return (_posix1e_acl_strip_np(aclp, recalculate_mask));
@@ -185,10 +190,25 @@ acl_is_trivial_np(const acl_t aclp, int 
 		}
 			
 		/*
-		 * Calculate trivial ACL - using acl_strip_np - and compare
+		 * Calculate trivial ACL - using acl_strip_np(3) - and compare
 		 * with the original.
 		 */
-		tmpacl = acl_strip_np(aclp, 0);
+		tmpacl = _nfs4_acl_strip_np(aclp, 0);
+		if (tmpacl == NULL)
+			return (-1);
+
+		differs = _acl_differs(aclp, tmpacl);
+		acl_free(tmpacl);
+
+		if (differs == 0) {
+			*trivialp = 1;
+			return (0);
+		}
+
+		/*
+		 * Try again with an old-style, "canonical six" trivial ACL.
+		 */
+		tmpacl = _nfs4_acl_strip_np(aclp, 1);
 		if (tmpacl == NULL)
 			return (-1);
 

Modified: stable/8/sys/kern/subr_acl_nfs4.c
==============================================================================
--- stable/8/sys/kern/subr_acl_nfs4.c	Mon Nov  1 15:18:57 2010	(r214625)
+++ stable/8/sys/kern/subr_acl_nfs4.c	Mon Nov  1 15:36:47 2010	(r214626)
@@ -323,6 +323,83 @@ _acl_duplicate_entry(struct acl *aclp, i
 	return (&(aclp->acl_entry[entry_index + 1]));
 }
 
+/*
+ * Calculate trivial ACL in a manner compatible with PSARC/2010/029.
+ * Note that this results in an ACL different from (but semantically
+ * equal to) the "canonical six" trivial ACL computed using algorithm
+ * described in draft-ietf-nfsv4-minorversion1-03.txt, 3.16.6.2.
+ */
+void
+acl_nfs4_trivial_from_mode(struct acl *aclp, mode_t mode)
+{
+	acl_perm_t user_allow_first = 0, user_deny = 0, group_deny = 0;
+	acl_perm_t user_allow, group_allow, everyone_allow;
+
+	KASSERT(aclp->acl_cnt == 0, ("aclp->acl_cnt == 0"));
+
+	user_allow = group_allow = everyone_allow = ACL_READ_ACL |
+	    ACL_READ_ATTRIBUTES | ACL_READ_NAMED_ATTRS | ACL_SYNCHRONIZE;
+	user_allow |= ACL_WRITE_ACL | ACL_WRITE_OWNER | ACL_WRITE_ATTRIBUTES |
+	    ACL_WRITE_NAMED_ATTRS;
+
+	if (mode & S_IRUSR)
+		user_allow |= ACL_READ_DATA;
+	if (mode & S_IWUSR)
+		user_allow |= (ACL_WRITE_DATA | ACL_APPEND_DATA);
+	if (mode & S_IXUSR)
+		user_allow |= ACL_EXECUTE;
+
+	if (mode & S_IRGRP)
+		group_allow |= ACL_READ_DATA;
+	if (mode & S_IWGRP)
+		group_allow |= (ACL_WRITE_DATA | ACL_APPEND_DATA);
+	if (mode & S_IXGRP)
+		group_allow |= ACL_EXECUTE;
+
+	if (mode & S_IROTH)
+		everyone_allow |= ACL_READ_DATA;
+	if (mode & S_IWOTH)
+		everyone_allow |= (ACL_WRITE_DATA | ACL_APPEND_DATA);
+	if (mode & S_IXOTH)
+		everyone_allow |= ACL_EXECUTE;
+
+	user_deny = ((group_allow | everyone_allow) & ~user_allow);
+	group_deny = everyone_allow & ~group_allow;
+	user_allow_first = group_deny & ~user_deny;
+
+#if 1
+	/*
+	 * This is a workaround for what looks like a bug in ZFS - trivial
+	 * ACL for mode 0077 should look like this:
+	 *
+	 *    owner@:rwxp----------:------:deny
+	 *    owner@:------aARWcCos:------:allow
+	 *    group@:rwxp--a-R-c--s:------:allow
+	 * everyone@:rwxp--a-R-c--s:------:allow
+	 *
+	 * Instead, ZFS makes it like this:
+	 *
+	 *    owner@:rwx-----------:------:deny
+	 *    owner@:------aARWcCos:------:allow
+	 *    group@:rwxp--a-R-c--s:------:allow
+	 * everyone@:rwxp--a-R-c--s:------:allow
+	 */
+	user_allow_first &= ~ACL_APPEND_DATA;
+	user_deny &= ~ACL_APPEND_DATA;
+	group_deny &= ~ACL_APPEND_DATA;
+#endif
+
+	if (user_allow_first != 0)
+		_acl_append(aclp, ACL_USER_OBJ, user_allow_first, ACL_ENTRY_TYPE_ALLOW);
+	if (user_deny != 0)
+		_acl_append(aclp, ACL_USER_OBJ, user_deny, ACL_ENTRY_TYPE_DENY);
+	if (group_deny != 0)
+		_acl_append(aclp, ACL_GROUP_OBJ, group_deny, ACL_ENTRY_TYPE_DENY);
+	_acl_append(aclp, ACL_USER_OBJ, user_allow, ACL_ENTRY_TYPE_ALLOW);
+	_acl_append(aclp, ACL_GROUP_OBJ, group_allow, ACL_ENTRY_TYPE_ALLOW);
+	_acl_append(aclp, ACL_EVERYONE, everyone_allow, ACL_ENTRY_TYPE_ALLOW);
+}
+
 void
 acl_nfs4_sync_acl_from_mode(struct acl *aclp, mode_t mode, int file_owner_id)
 {

Modified: stable/8/sys/sys/acl.h
==============================================================================
--- stable/8/sys/sys/acl.h	Mon Nov  1 15:18:57 2010	(r214625)
+++ stable/8/sys/sys/acl.h	Mon Nov  1 15:36:47 2010	(r214626)
@@ -285,6 +285,8 @@ mode_t			acl_posix1e_newfilemode(mode_t 
 struct acl		*acl_alloc(int flags);
 void			acl_free(struct acl *aclp);
 
+void			acl_nfs4_trivial_from_mode(struct acl *aclp,
+			    mode_t mode);
 void			acl_nfs4_sync_acl_from_mode(struct acl *aclp,
 			    mode_t mode, int file_owner_id);
 void			acl_nfs4_sync_mode_from_acl(mode_t *mode,


More information about the svn-src-stable-8 mailing list