PERFORCE change 145052 for review
Edward Tomasz Napierala
trasz at FreeBSD.org
Fri Jul 11 07:57:10 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=145052
Change 145052 by trasz at 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
More information about the p4-projects
mailing list