Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 11 Jul 2008 07:57:09 GMT
From:      Edward Tomasz Napierala <trasz@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 145052 for review
Message-ID:  <200807110757.m6B7v9r9001950@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=145052

Change 145052 by trasz@trasz_traszkan on 2008/07/11 07:56:31

	Add the possibility to get and set NFS4 ACLs in ZFS.

Affected files ...

.. //depot/projects/soc2008/trasz_nfs4acl/TODO#11 edit
.. //depot/projects/soc2008/trasz_nfs4acl/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/acl_compat.c#1 add
.. //depot/projects/soc2008/trasz_nfs4acl/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/acl_compat.h#1 add
.. //depot/projects/soc2008/trasz_nfs4acl/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_acl.h#2 edit
.. //depot/projects/soc2008/trasz_nfs4acl/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h#2 edit
.. //depot/projects/soc2008/trasz_nfs4acl/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c#2 edit
.. //depot/projects/soc2008/trasz_nfs4acl/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_replay.c#2 edit
.. //depot/projects/soc2008/trasz_nfs4acl/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c#2 edit
.. //depot/projects/soc2008/trasz_nfs4acl/sys/modules/zfs/Makefile#2 edit

Differences ...

==== //depot/projects/soc2008/trasz_nfs4acl/TODO#11 (text+ko) ====

@@ -46,7 +46,7 @@
   ACL_DELETE_CHILD 
   ACL_DELETE 
 
-- Attach ZFS to the framework.
+- Add granular access control to ZFS.
 
 - Write code to do the same operations on UFS and ZFS and compare results.
 

==== //depot/projects/soc2008/trasz_nfs4acl/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_acl.h#2 (text+ko) ====

@@ -87,13 +87,9 @@
 #ifdef _KERNEL
 void zfs_perm_init(struct znode *, struct znode *, int, vattr_t *,
     dmu_tx_t *, cred_t *);
-#ifdef TODO
 int zfs_getacl(struct znode *, vsecattr_t *, cred_t *);
-#endif
 int zfs_mode_update(struct znode *, uint64_t, dmu_tx_t  *);
-#ifdef TODO
 int zfs_setacl(struct znode *, vsecattr_t *, cred_t *);
-#endif
 void zfs_acl_rele(void *);
 void zfs_ace_byteswap(ace_t *, int);
 extern int zfs_zaccess(struct znode *, int, cred_t *);

==== //depot/projects/soc2008/trasz_nfs4acl/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h#2 (text+ko) ====

@@ -117,4 +117,16 @@
 	}								\
 } while (0)
 
+typedef struct vsecattr {
+	uint_t		vsa_mask;	/* See below */
+	int		vsa_aclcnt;	/* ACL entry count */
+	void		*vsa_aclentp;	/* pointer to ACL entries */
+	int		vsa_dfaclcnt;	/* default ACL entry count */
+	void		*vsa_dfaclentp;	/* pointer to default ACL entries */
+	size_t		vsa_aclentsz;	/* ACE size in bytes of vsa_aclentp */
+} vsecattr_t;
+
+#define	VSA_ACE			0x0010
+#define	VSA_ACECNT		0x0020
+
 #endif	/* _SYS_ZFS_CONTEXT_H */

==== //depot/projects/soc2008/trasz_nfs4acl/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c#2 (text+ko) ====

@@ -1096,7 +1096,6 @@
 	return (0);
 }
 
-#ifdef TODO
 /*
  * Retrieve a files ACL
  */
@@ -1145,9 +1144,7 @@
 
 	return (0);
 }
-#endif	/* TODO */
 
-#ifdef TODO
 /*
  * Set a files ACL
  */
@@ -1222,7 +1219,6 @@
 
 	return (error);
 }
-#endif	/* TODO */
 
 static int
 zfs_ace_access(ace_t *zacep, int *working_mode)

==== //depot/projects/soc2008/trasz_nfs4acl/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_replay.c#2 (text+ko) ====

@@ -372,9 +372,7 @@
 zfs_replay_acl(zfsvfs_t *zfsvfs, lr_acl_t *lr, boolean_t byteswap)
 {
 	ace_t *ace = (ace_t *)(lr + 1);	/* ace array follows lr_acl_t */
-#ifdef TODO
 	vsecattr_t vsa;
-#endif
 	znode_t *zp;
 	int error;
 

==== //depot/projects/soc2008/trasz_nfs4acl/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c#2 (text+ko) ====

@@ -68,6 +68,8 @@
 #include <sys/sf_buf.h>
 #include <sys/sched.h>
 
+#include "acl_compat.h"
+
 /*
  * Programming rules.
  *
@@ -3087,12 +3089,15 @@
 		*valp = (int)SPA_MINBLOCKSIZE;
 		return (0);
 
+	case _PC_EXTENDED_SECURITY_NP:
+		*valp = 1;
+		return (0);
+
 	default:
 		return (EOPNOTSUPP);
 	}
 }
 
-#ifdef TODO
 /*ARGSUSED*/
 static int
 zfs_getsecattr(vnode_t *vp, vsecattr_t *vsecp, int flag, cred_t *cr)
@@ -3107,9 +3112,7 @@
 
 	return (error);
 }
-#endif	/* TODO */
 
-#ifdef TODO
 /*ARGSUSED*/
 static int
 zfs_setsecattr(vnode_t *vp, vsecattr_t *vsecp, int flag, cred_t *cr)
@@ -3123,7 +3126,6 @@
 	ZFS_EXIT(zfsvfs);
 	return (error);
 }
-#endif	/* TODO */
 
 static int
 zfs_freebsd_open(ap)
@@ -3533,6 +3535,126 @@
 	return (error);
 }
 
+int
+zfs_freebsd_getacl(ap)
+	struct vop_getacl_args /* {
+		struct vnode *vp;
+		acl_type_t type;
+		struct acl *aclp;
+		struct ucred *cred;
+		struct thread *td;
+	} */ *ap;
+{
+	int		error;
+	vsecattr_t      vsecattr;
+	int		aclbsize;	/* size of acl list in bytes */
+
+	if (ap->a_type != ACL_TYPE_NFS4)
+		return (EOPNOTSUPP);
+
+	/* Mostly taken from common/syscall/acl.c. */
+
+	vsecattr.vsa_mask = VSA_ACE | VSA_ACECNT;
+	if (error = zfs_getsecattr(ap->a_vp, &vsecattr, 0, CRED()))
+		return (error);
+
+	aclbsize = vsecattr.vsa_aclcnt * sizeof (ace_t);
+	if (vsecattr.vsa_aclcnt > ACL_MAX_ENTRIES) {
+		printf("GETACL: no space\n");
+		error = ENOSPC;
+		goto errout;
+	}
+
+	error = acl_from_aces(ap->a_aclp, vsecattr.vsa_aclentp, vsecattr.vsa_aclcnt);
+	if (error)
+		goto errout;
+
+	if (vsecattr.vsa_aclcnt)
+		kmem_free(vsecattr.vsa_aclentp, vsecattr.vsa_aclentsz);
+
+	return (0);
+
+errout:
+        if (aclbsize && vsecattr.vsa_aclentp)
+                kmem_free(vsecattr.vsa_aclentp, aclbsize);
+        return (error);
+}
+
+int
+zfs_freebsd_setacl(ap)
+	struct vop_setacl_args /* {
+		struct vnode *vp;
+		acl_type_t type;
+		struct acl *aclp;
+		struct ucred *cred;
+		struct thread *td;
+	} */ *ap;
+{
+	int		error;
+	vsecattr_t      vsecattr;
+	int		aclbsize;	/* size of acl list in bytes */
+	aclent_t	*aaclp;
+
+	if (ap->a_type != ACL_TYPE_NFS4)
+		return (EOPNOTSUPP);
+
+	/* Mostly taken from common/syscall/acl.c. */
+
+	error = VOP_ACCESS(ap->a_vp, VADMIN, ap->a_cred, ap->a_td);
+	if (error)
+		return (error);
+
+	if (ap->a_aclp->acl_cnt < 1 || ap->a_aclp->acl_cnt > MAX_ACL_ENTRIES)
+		return (EINVAL);
+
+	vsecattr.vsa_mask = VSA_ACE;
+	aclbsize = ap->a_aclp->acl_cnt * sizeof (ace_t);
+	vsecattr.vsa_aclentp = kmem_alloc(aclbsize, KM_SLEEP);
+	aaclp = vsecattr.vsa_aclentp;
+	vsecattr.vsa_aclentsz = aclbsize;
+
+	error = aces_from_acl(vsecattr.vsa_aclentp, &(vsecattr.vsa_aclcnt), ap->a_aclp);
+	if (error) {
+		kmem_free(aaclp, aclbsize);
+		return (EINVAL);
+	}
+
+#if 0
+	(void) VOP_RWLOCK(ap->a_vp, V_WRITELOCK_TRUE, NULL);
+#endif
+	if (error = zfs_setsecattr(ap->a_vp, &vsecattr, 0, CRED())) {
+		kmem_free(aaclp, aclbsize);
+#if 0
+		VOP_RWUNLOCK(ap->a_vp, V_WRITELOCK_TRUE, NULL);
+#endif
+		return (error);
+	}
+	kmem_free(aaclp, aclbsize);
+#if 0
+	VOP_RWUNLOCK(ap->a_vp, V_WRITELOCK_TRUE, NULL);
+#endif
+
+	return (0);
+}
+
+int
+zfs_freebsd_aclcheck(ap)
+	struct vop_aclcheck_args /* {
+		struct vnode *vp;
+		acl_type_t type;
+		struct acl *aclp;
+		struct ucred *cred;
+		struct thread *td;
+	} */ *ap;
+{
+	if (ap->a_type != ACL_TYPE_NFS4)
+		return (EOPNOTSUPP);
+
+	printf("ACLCHECK\n");
+
+	return (EOPNOTSUPP);
+}
+
 struct vop_vector zfs_vnodeops;
 struct vop_vector zfs_fifoops;
 
@@ -3568,6 +3690,9 @@
 	.vop_pathconf =	zfs_freebsd_pathconf,
 	.vop_bmap =	VOP_EOPNOTSUPP,
 	.vop_fid =	zfs_freebsd_fid,
+	.vop_getacl =	zfs_freebsd_getacl,
+	.vop_setacl =	zfs_freebsd_setacl,
+	.vop_aclcheck =	zfs_freebsd_aclcheck,
 };
 
 struct vop_vector zfs_fifoops = {
@@ -3581,4 +3706,7 @@
 	.vop_setattr =	zfs_freebsd_setattr,
 	.vop_write =	VOP_PANIC,
 	.vop_fid =	zfs_freebsd_fid,
+	.vop_getacl =	zfs_freebsd_getacl,
+	.vop_setacl =	zfs_freebsd_setacl,
+	.vop_aclcheck =	zfs_freebsd_aclcheck,
 };

==== //depot/projects/soc2008/trasz_nfs4acl/sys/modules/zfs/Makefile#2 (text+ko) ====

@@ -63,6 +63,7 @@
 ZFS_SRCS=	${ZFS_OBJS:C/.o$/.c/}
 SRCS+=	${ZFS_SRCS}
 SRCS+=	vdev_geom.c
+SRCS+=	acl_compat.c
 
 # Use UMA for ZIO allocation. This is not stable.
 #CFLAGS+=-DZIO_USE_UMA



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200807110757.m6B7v9r9001950>