From owner-p4-projects@FreeBSD.ORG Fri Jul 11 07:57:10 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 4F9C71065678; Fri, 11 Jul 2008 07:57:10 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 151D81065670 for ; Fri, 11 Jul 2008 07:57:10 +0000 (UTC) (envelope-from trasz@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 114DA8FC21 for ; Fri, 11 Jul 2008 07:57:10 +0000 (UTC) (envelope-from trasz@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id m6B7v9OT001952 for ; Fri, 11 Jul 2008 07:57:09 GMT (envelope-from trasz@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.2/8.14.1/Submit) id m6B7v9r9001950 for perforce@freebsd.org; Fri, 11 Jul 2008 07:57:09 GMT (envelope-from trasz@freebsd.org) Date: Fri, 11 Jul 2008 07:57:09 GMT Message-Id: <200807110757.m6B7v9r9001950@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to trasz@freebsd.org using -f From: Edward Tomasz Napierala To: Perforce Change Reviews Cc: Subject: PERFORCE change 145052 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 11 Jul 2008 07:57:10 -0000 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 #include +#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