2009-09-02 12:24:46

by Aneesh Kumar K.V

[permalink] [raw]
Subject: POSIX ACL support for NFSV4 (using sideband protocol)

This patch series implement POSIX ACL support for NFSV4 clients
using sideband protocol. The ACL support can be disabled/enabled
using -o noacl/-o acl mount option. The feature enables to
view and modify POSIX acls from NFSv4 client.

-aneesh



2009-09-02 16:42:43

by J. Bruce Fields

[permalink] [raw]
Subject: Re: POSIX ACL support for NFSV4 (using sideband protocol)

On Wed, Sep 02, 2009 at 05:54:20PM +0530, Aneesh Kumar K.V wrote:
> This patch series implement POSIX ACL support for NFSV4 clients
> using sideband protocol.

What motivates this? Who exactly wants this and why? What would be
the advantages compared to other options, such as:

- native v4 support in filesystems, or
- improved client-side acl tools that provided a user interface
for v4 acls closer to that for v3 acls, or
- a v4.x extension to add support to the main protocol?

Is there interest in implementing this on any OS other than linux, or
would this be a linux-only extension for the forseeable future?

What sideband protocol exactly? If it's exactly the same protocol as
the one used with v3, there must be some slight mismatches: e.g. v4
filehandles are allowed to be longer. How do you deal with these?

--b.

> The ACL support can be disabled/enabled
> using -o noacl/-o acl mount option. The feature enables to
> view and modify POSIX acls from NFSv4 client.
_______________________________________________
NFSv4 mailing list
[email protected]
http://linux-nfs.org/cgi-bin/mailman/listinfo/nfsv4

2009-09-03 19:09:52

by Andreas Gruenbacher

[permalink] [raw]
Subject: Re: POSIX ACL support for NFSV4 (using sideband protocol)

On Wednesday, 2 September 2009 18:42:43 J. Bruce Fields wrote:
> On Wed, Sep 02, 2009 at 05:54:20PM +0530, Aneesh Kumar K.V wrote:
> > This patch series implement POSIX ACL support for NFSV4 clients
> > using sideband protocol.
>
> What motivates this? Who exactly wants this and why? What would be
> the advantages compared to other options, such as:
>
> - native v4 support in filesystems, or
> - improved client-side acl tools that provided a user interface
> for v4 acls closer to that for v3 acls, or
> - a v4.x extension to add support to the main protocol?

I can't speak for Aneesh, but my expectation is that we'll get native NFSv4
ACL support eventually, just maybe not in the next few years. Even then,
systems with native POSIX ACLs will coexist with machines with native NFSv4
ACLs for a long time, and so NFSv4's lack of decent support for POSIX ACLs is
a major problem.

I'm not sure what you mean by improved client-side tool. Some information is
unrecoverably lost when POSIX ACLs are converted into NFSv4 ACLs; no tool on
the client can make up for this. Besides, presenting server-side POSIX ACLs
as similar (but not quite identical) NFSv4 ACLs on the client is really not a
good idea: right now, clients can only guess which NFSv4 ACLs are actually
POSIX ACLs in disguise.

> Is there interest in implementing this on any OS other than linux, or
> would this be a linux-only extension for the forseeable future?

Good question. I would sure prefer a standard solution to a Linux specific
hack -- but that being said, I would prefer a solution to the current
mess ;-)

Thanks,
Andreas
_______________________________________________
NFSv4 mailing list
[email protected]
http://linux-nfs.org/cgi-bin/mailman/listinfo/nfsv4

2009-09-02 17:50:12

by Aneesh Kumar K.V

[permalink] [raw]
Subject: Re: POSIX ACL support for NFSV4 (using sideband protocol)

On Wed, Sep 02, 2009 at 12:42:43PM -0400, J. Bruce Fields wrote:
> On Wed, Sep 02, 2009 at 05:54:20PM +0530, Aneesh Kumar K.V wrote:
> > This patch series implement POSIX ACL support for NFSV4 clients
> > using sideband protocol.
>
> What motivates this? Who exactly wants this and why? What would be
> the advantages compared to other options, such as:
>
> - native v4 support in filesystems, or
> - improved client-side acl tools that provided a user interface
> for v4 acls closer to that for v3 acls, or
> - a v4.x extension to add support to the main protocol?
>
> Is there interest in implementing this on any OS other than linux, or
> would this be a linux-only extension for the forseeable future?
>
> What sideband protocol exactly? If it's exactly the same protocol as
> the one used with v3, there must be some slight mismatches: e.g. v4
> filehandles are allowed to be longer. How do you deal with these?
>

It is similar to v3 with longer file handle. Also it doesn't support
attribute update as a part of the acl calls. I does zap cache and expect
the client to do another call to get the updated attribute values. Primary
motivation is to avoid side band rpc having to handle compound request so
that we can keep it simple.

-aneesh

2009-09-02 18:27:39

by J. Bruce Fields

[permalink] [raw]
Subject: Re: POSIX ACL support for NFSV4 (using sideband protocol)

On Wed, Sep 02, 2009 at 11:19:57PM +0530, Aneesh Kumar K.V wrote:
> On Wed, Sep 02, 2009 at 12:42:43PM -0400, J. Bruce Fields wrote:
> > On Wed, Sep 02, 2009 at 05:54:20PM +0530, Aneesh Kumar K.V wrote:
> > > This patch series implement POSIX ACL support for NFSV4 clients
> > > using sideband protocol.
> >
> > What motivates this? Who exactly wants this and why? What would be
> > the advantages compared to other options, such as:
> >
> > - native v4 support in filesystems, or
> > - improved client-side acl tools that provided a user interface
> > for v4 acls closer to that for v3 acls, or
> > - a v4.x extension to add support to the main protocol?
> >
> > Is there interest in implementing this on any OS other than linux, or
> > would this be a linux-only extension for the forseeable future?
> >
> > What sideband protocol exactly? If it's exactly the same protocol as
> > the one used with v3, there must be some slight mismatches: e.g. v4
> > filehandles are allowed to be longer. How do you deal with these?
> >
>
> It is similar to v3 with longer file handle. Also it doesn't support
> attribute update as a part of the acl calls. I does zap cache and expect
> the client to do another call to get the updated attribute values. Primary
> motivation is to avoid side band rpc having to handle compound request so
> that we can keep it simple.

That doesn't really answer the "motivation" question.

If you really want to do this, writing the code is the easy part. The
really (extremely) hard part is coming up with good answers to the
questions above.

--b.
_______________________________________________
NFSv4 mailing list
[email protected]
http://linux-nfs.org/cgi-bin/mailman/listinfo/nfsv4

2009-09-03 16:08:45

by J. Bruce Fields

[permalink] [raw]
Subject: Re: POSIX ACL support for NFSV4 (using sideband protocol)

On Thu, Sep 03, 2009 at 10:35:35AM -0500, Steve French wrote:
> On Thu, Sep 3, 2009 at 8:55 AM, J. Bruce Fields<[email protected]> wrote:
> > On Thu, Sep 03, 2009 at 08:54:06AM -0500, Steve French wrote:
> >> if someone were able to convince the linux-fsdevel community to change
> >> fs/posix_acls.c
> >> (or add an fs/cifs_acls.c) to handle NFSv4/CIFS/NTFS ACL evaluation, and add
> >> support to store these richer ACLs on disk for the future (e.g. for
> >> btrfs), that would be
> >> great - but with no local file system in kernel which can store NFSv4 ACLs and
> >> no code to evaluate these ACLs in the VFS and with a NACK from fsdevel when
> >
> > I don't remember that--do you have a pointer?
>
> Aneesh mentioned one strongly worded objection (I remember more resistance
> from others too)
>
> http://kerneltrap.org/mailarchive/linux-fsdevel/2006/6/24/313526

Yes, Christoph's always been vehemently opposed. I share his distaste
for NFSv4/NT ACLs, but I agree with Trond that a solid implementation
with a demonstrated need from CIFS, NFSv4, NTFS, etc., would be likely
to overcome such objections.

--b.

2009-09-02 12:24:52

by Aneesh Kumar K.V

[permalink] [raw]
Subject: [RFC PATCH 1/8] nfs4: Posix acl server side side-band protocol support

Signed-off-by: Aneesh Kumar K.V <[email protected]>
---
fs/nfsd/Kconfig | 6 +
fs/nfsd/Makefile | 1 +
fs/nfsd/nfs4pacl.c | 322 +++++++++++++++++++++++++++++++++++++++++++++
fs/nfsd/nfssvc.c | 11 +-
include/linux/nfsd/nfsd.h | 7 +-
5 files changed, 341 insertions(+), 6 deletions(-)
create mode 100644 fs/nfsd/nfs4pacl.c

diff --git a/fs/nfsd/Kconfig b/fs/nfsd/Kconfig
index 503b9da..1156ae8 100644
--- a/fs/nfsd/Kconfig
+++ b/fs/nfsd/Kconfig
@@ -79,3 +79,9 @@ config NFSD_V4
available from http://linux-nfs.org/.

If unsure, say N.
+
+config NFSD_V4_PACL
+ bool "NFS server support for the NFSv4 POSIX ACL protocol extension"
+ depends on NFSD_V4
+ help
+ POSIX ACL sideband protocol extension
diff --git a/fs/nfsd/Makefile b/fs/nfsd/Makefile
index 9b118ee..05b37bb 100644
--- a/fs/nfsd/Makefile
+++ b/fs/nfsd/Makefile
@@ -11,3 +11,4 @@ nfsd-$(CONFIG_NFSD_V3) += nfs3proc.o nfs3xdr.o
nfsd-$(CONFIG_NFSD_V3_ACL) += nfs3acl.o
nfsd-$(CONFIG_NFSD_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4idmap.o \
nfs4acl.o nfs4callback.o nfs4recover.o
+nfsd-$(CONFIG_NFSD_V4_PACL) += nfs4pacl.o
diff --git a/fs/nfsd/nfs4pacl.c b/fs/nfsd/nfs4pacl.c
new file mode 100644
index 0000000..42d706a
--- /dev/null
+++ b/fs/nfsd/nfs4pacl.c
@@ -0,0 +1,322 @@
+/*
+ *
+ * Process version NFS4 POSIX ACL requests.
+ *
+ */
+
+#include <linux/sunrpc/svc.h>
+#include <linux/nfs4.h>
+#include <linux/nfsd/nfsd.h>
+#include <linux/nfsd/cache.h>
+#include <linux/posix_acl.h>
+#include <linux/nfsacl.h>
+
+
+#define nfs4svc_decode_voidargs NULL
+#define nfs4svc_release_void NULL
+struct nfsd4_voidargs {
+ int dummy;
+};
+#define nfsd4_voidres nfsd4_voidargs
+
+struct nfsd4_getpaclargs {
+ struct svc_fh fh;
+ int mask;
+};
+struct posix_acl;
+struct nfsd4_setpaclargs {
+ struct svc_fh fh;
+ int mask;
+ struct posix_acl *acl_access;
+ struct posix_acl *acl_default;
+};
+struct nfsd4_getpaclres {
+ __be32 status;
+ struct svc_fh fh;
+ int mask;
+ struct posix_acl *acl_access;
+ struct posix_acl *acl_default;
+};
+struct nfsd4_setpaclres {
+ __be32 status;
+ struct svc_fh fh;
+};
+union nfs4paclstore {
+ struct nfsd4_getpaclargs gaclargs;
+ struct nfsd4_setpaclargs saclargs;
+ struct nfsd4_getpaclres gaclres;
+ struct nfsd4_setpaclres saclres;
+};
+
+#define NFS4_SVC_ACLXDRSZ sizeof(union nfs4paclstore)
+
+/*
+ * NULL call.
+ */
+static __be32
+nfsd4_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
+{
+ return nfs_ok;
+}
+
+/*
+ * Get the Access and/or Default ACL of a file.
+ */
+static __be32 nfsd4_proc_getpacl(struct svc_rqst *rqstp,
+ struct nfsd4_getpaclargs *argp, struct nfsd4_getpaclres *resp)
+{
+ svc_fh *fh;
+ struct posix_acl *acl;
+ __be32 nfserr = 0;
+
+ fh = fh_copy(&resp->fh, &argp->fh);
+ nfserr = fh_verify(rqstp, &resp->fh, 0, NFSD_MAY_NOP);
+ if (nfserr)
+ goto err_out;
+ if (argp->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT)) {
+ nfserr = nfserr_inval;
+ goto err_out;
+ }
+ resp->mask = argp->mask;
+
+ if (resp->mask & (NFS_ACL|NFS_ACLCNT)) {
+ acl = nfsd_get_posix_acl(fh, ACL_TYPE_ACCESS);
+ if (IS_ERR(acl)) {
+ int err = PTR_ERR(acl);
+
+ if (err == -ENODATA || err == -EOPNOTSUPP)
+ acl = NULL;
+ else {
+ nfserr = nfserrno(err);
+ goto fail;
+ }
+ }
+ if (acl == NULL) {
+ /* Solaris returns the inode's minimum ACL. */
+
+ struct inode *inode = fh->fh_dentry->d_inode;
+ acl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL);
+ }
+ resp->acl_access = acl;
+ }
+ if (resp->mask & (NFS_DFACL|NFS_DFACLCNT)) {
+ /* Check how Solaris handles requests for the Default ACL
+ of a non-directory! */
+
+ acl = nfsd_get_posix_acl(fh, ACL_TYPE_DEFAULT);
+ if (IS_ERR(acl)) {
+ int err = PTR_ERR(acl);
+
+ if (err == -ENODATA || err == -EOPNOTSUPP)
+ acl = NULL;
+ else {
+ nfserr = nfserrno(err);
+ goto fail;
+ }
+ }
+ resp->acl_default = acl;
+ }
+
+ /*
+ * resp->acl_{access,default} are released in
+ * nfs4svc_release_getpacl.
+ */
+ resp->status = 0;
+ return 0;
+
+fail:
+ posix_acl_release(resp->acl_access);
+ posix_acl_release(resp->acl_default);
+err_out:
+ resp->status = nfserr;
+ return nfserr;
+}
+
+/*
+ * Set the Access and/or Default ACL of a file.
+ */
+static __be32 nfsd4_proc_setpacl(struct svc_rqst *rqstp,
+ struct nfsd4_setpaclargs *argp,
+ struct nfsd4_setpaclres *resp)
+{
+ svc_fh *fh;
+ __be32 nfserr = 0;
+
+ fh = fh_copy(&resp->fh, &argp->fh);
+ nfserr = fh_verify(rqstp, &resp->fh, 0, NFSD_MAY_SATTR);
+
+ if (!nfserr) {
+ nfserr = nfserrno( nfsd_set_posix_acl(
+ fh, ACL_TYPE_ACCESS, argp->acl_access));
+ }
+ if (!nfserr) {
+ nfserr = nfserrno( nfsd_set_posix_acl(
+ fh, ACL_TYPE_DEFAULT, argp->acl_default));
+ }
+
+ /* argp->acl_{access,default} may have been allocated in
+ nfs4svc_decode_setpaclargs. */
+ posix_acl_release(argp->acl_access);
+ posix_acl_release(argp->acl_default);
+ resp->status = nfserr;
+ return nfserr;
+}
+
+/*
+ * XDR decode functions
+ */
+__be32 *nfs4svc_decode_fh(__be32 *p, struct svc_fh *fhp)
+{
+ unsigned int size;
+ fh_init(fhp, NFS4_FHSIZE);
+ size = ntohl(*p++);
+ if (size > NFS4_FHSIZE)
+ return NULL;
+
+ memcpy(&fhp->fh_handle.fh_base, p, size);
+ fhp->fh_handle.fh_size = size;
+ return p + XDR_QUADLEN(size);
+}
+static int nfs4svc_decode_getpaclargs(struct svc_rqst *rqstp, __be32 *p,
+ struct nfsd4_getpaclargs *args)
+{
+ p = nfs4svc_decode_fh(p, &args->fh);
+ if (!p)
+ return 0;
+ args->mask = ntohl(*p); p++;
+
+ return xdr_argsize_check(rqstp, p);
+}
+
+
+static int nfs4svc_decode_setpaclargs(struct svc_rqst *rqstp, __be32 *p,
+ struct nfsd4_setpaclargs *args)
+{
+ struct kvec *head = rqstp->rq_arg.head;
+ unsigned int base;
+ int n;
+
+ p = nfs4svc_decode_fh(p, &args->fh);
+ if (!p)
+ return 0;
+ args->mask = ntohl(*p++);
+ if (args->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT) ||
+ !xdr_argsize_check(rqstp, p))
+ return 0;
+
+ base = (char *)p - (char *)head->iov_base;
+ n = nfsacl_decode(&rqstp->rq_arg, base, NULL,
+ (args->mask & NFS_ACL) ?
+ &args->acl_access : NULL);
+ if (n > 0)
+ n = nfsacl_decode(&rqstp->rq_arg, base + n, NULL,
+ (args->mask & NFS_DFACL) ?
+ &args->acl_default : NULL);
+ return (n > 0);
+}
+
+/*
+ * XDR encode functions
+ */
+extern int nfs4svc_encode_voidres(struct svc_rqst *rqstp,
+ __be32 *p, void *dummy);
+
+/* GETPACL */
+static int nfs4svc_encode_getpaclres(struct svc_rqst *rqstp, __be32 *p,
+ struct nfsd4_getpaclres *resp)
+{
+ struct dentry *dentry = resp->fh.fh_dentry;
+
+ if (resp->status == 0 && dentry && dentry->d_inode) {
+ struct inode *inode = dentry->d_inode;
+ struct kvec *head = rqstp->rq_res.head;
+ unsigned int base;
+ int n;
+ int w;
+
+ *p++ = htonl(resp->mask);
+ if (!xdr_ressize_check(rqstp, p))
+ return 0;
+ base = (char *)p - (char *)head->iov_base;
+
+ rqstp->rq_res.page_len = w = nfsacl_size(
+ (resp->mask & NFS_ACL) ? resp->acl_access : NULL,
+ (resp->mask & NFS_DFACL) ? resp->acl_default : NULL);
+ while (w > 0) {
+ if (!rqstp->rq_respages[rqstp->rq_resused++])
+ return 0;
+ w -= PAGE_SIZE;
+ }
+
+ n = nfsacl_encode(&rqstp->rq_res, base, inode,
+ resp->acl_access,
+ resp->mask & NFS_ACL, 0);
+ if (n > 0)
+ n = nfsacl_encode(&rqstp->rq_res, base + n, inode,
+ resp->acl_default,
+ resp->mask & NFS_DFACL,
+ NFS_ACL_DEFAULT);
+ if (n <= 0)
+ return 0;
+ } else
+ if (!xdr_ressize_check(rqstp, p))
+ return 0;
+
+ return 1;
+}
+
+/* SETPACL */
+static int nfs4svc_encode_setpaclres(struct svc_rqst *rqstp, __be32 *p,
+ struct nfsd4_setpaclres *resp)
+{
+ return xdr_ressize_check(rqstp, p);
+}
+
+/*
+ * XDR release functions
+ */
+static int nfs4svc_release_getpacl(struct svc_rqst *rqstp, __be32 *p,
+ struct nfsd4_getpaclres *resp)
+{
+ fh_put(&resp->fh);
+ posix_acl_release(resp->acl_access);
+ posix_acl_release(resp->acl_default);
+ return 1;
+}
+
+static int nfs4svc_release_setpacl(struct svc_rqst *rqstp, __be32 *p,
+ struct nfsd4_setpaclres *resp)
+{
+ fh_put(&resp->fh);
+ return 1;
+}
+
+#define PROC(name, argt, rest, relt, cache, respsize) \
+ { (svc_procfunc) nfsd4_proc_##name, \
+ (kxdrproc_t) nfs4svc_decode_##argt##args, \
+ (kxdrproc_t) nfs4svc_encode_##rest##res, \
+ (kxdrproc_t) nfs4svc_release_##relt, \
+ sizeof(struct nfsd4_##argt##args), \
+ sizeof(struct nfsd4_##rest##res), \
+ 0, \
+ cache, \
+ respsize, \
+ }
+
+#define ST 1 /* status*/
+#define ACL (1+NFS_ACL_MAX_ENTRIES*3) /* Access Control List */
+
+static struct svc_procedure nfsd_pacl_procedures4[] = {
+ PROC(null, void, void, void, RC_NOCACHE, ST),
+ PROC(getpacl, getpacl, getpacl, getpacl, RC_NOCACHE, ST+1+2*(1+ACL)),
+ PROC(setpacl, setpacl, setpacl, setpacl, RC_NOCACHE, ST),
+};
+
+struct svc_version nfsd_pacl_version4 = {
+ .vs_vers = 4,
+ .vs_nproc = 3,
+ .vs_proc = nfsd_pacl_procedures4,
+ .vs_dispatch = nfsd_dispatch,
+ .vs_xdrsize = NFS4_SVC_ACLXDRSZ,
+ .vs_hidden = 1,
+};
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 492c79b..e970a60 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -66,11 +66,12 @@ struct timeval nfssvc_boot;
DEFINE_MUTEX(nfsd_mutex);
struct svc_serv *nfsd_serv;

-#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
+#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) || defined(CONFIG_NFSD_V4_PACL)
static struct svc_stat nfsd_acl_svcstats;
static struct svc_version * nfsd_acl_version[] = {
[2] = &nfsd_acl_version2,
[3] = &nfsd_acl_version3,
+ [4] = &nfsd_pacl_version4,
};

#define NFSD_ACL_MINVERS 2
@@ -107,7 +108,7 @@ static struct svc_version * nfsd_version[] = {
static struct svc_version *nfsd_versions[NFSD_NRVERS];

struct svc_program nfsd_program = {
-#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
+#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) || defined(CONFIG_NFSD_V4_PACL)
.pg_next = &nfsd_acl_program,
#endif
.pg_prog = NFS_PROGRAM, /* program number */
@@ -129,14 +130,14 @@ int nfsd_vers(int vers, enum vers_op change)
switch(change) {
case NFSD_SET:
nfsd_versions[vers] = nfsd_version[vers];
-#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
+#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) || defined(CONFIG_NFSD_V4_PACL)
if (vers < NFSD_ACL_NRVERS)
nfsd_acl_versions[vers] = nfsd_acl_version[vers];
#endif
break;
case NFSD_CLEAR:
nfsd_versions[vers] = NULL;
-#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
+#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) || defined(CONFIG_NFSD_V4_PACL)
if (vers < NFSD_ACL_NRVERS)
nfsd_acl_versions[vers] = NULL;
#endif
@@ -213,7 +214,7 @@ void nfsd_reset_versions(void)
if (!found_one) {
for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++)
nfsd_program.pg_vers[i] = nfsd_version[i];
-#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
+#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) || defined(CONFIG_NFSD_V4_PACL)
for (i = NFSD_ACL_MINVERS; i < NFSD_ACL_NRVERS; i++)
nfsd_acl_program.pg_vers[i] =
nfsd_acl_version[i];
diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h
index 2b49d67..d9263b6 100644
--- a/include/linux/nfsd/nfsd.h
+++ b/include/linux/nfsd/nfsd.h
@@ -133,7 +133,7 @@ __be32 nfsd_permission(struct svc_rqst *, struct svc_export *,
struct dentry *, int);
int nfsd_sync_dir(struct dentry *dp);

-#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
+#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) || defined(CONFIG_NFSD_V4_PACL)
#ifdef CONFIG_NFSD_V2_ACL
extern struct svc_version nfsd_acl_version2;
#else
@@ -144,6 +144,11 @@ extern struct svc_version nfsd_acl_version3;
#else
#define nfsd_acl_version3 NULL
#endif
+#ifdef CONFIG_NFSD_V4_PACL
+extern struct svc_version nfsd_pacl_version4;
+#else
+#define nfsd_pacl_version4 NULL
+#endif
struct posix_acl *nfsd_get_posix_acl(struct svc_fh *, int);
int nfsd_set_posix_acl(struct svc_fh *, int, struct posix_acl *);
#endif
--
1.6.4.2.253.g0b1fac


2009-09-02 12:25:08

by Aneesh Kumar K.V

[permalink] [raw]
Subject: [RFC PATCH 5/8] nfsv4: Add nfsv4 rpc client side support

Signed-off-by: Aneesh Kumar K.V <[email protected]>
---
fs/nfs/client.c | 32 +++++++----
fs/nfs/nfs4xdr.c | 149 +++++++++++++++++++++++++++++++++++++++++++++++
include/linux/nfs_xdr.h | 25 ++++++++
include/linux/nfsacl.h | 2 +
4 files changed, 197 insertions(+), 11 deletions(-)

diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index ea3a6b7..31f4a0b 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -81,11 +81,15 @@ struct rpc_stat nfs_rpcstat = {
.program = &nfs_program
};

-
-#ifdef CONFIG_NFS_V3_ACL
+#if defined(CONFIG_NFS_V3_ACL) || defined(CONFIG_NFS4_FS_POSIX_ACL)
static struct rpc_stat nfsacl_rpcstat = { &nfsacl_program };
static struct rpc_version * nfsacl_version[] = {
+#ifdef CONFIG_NFS_V3_ACL
[3] = &nfsacl_version3,
+#endif
+#ifdef CONFIG_NFS4_FS_POSIX_ACL
+ [4] = &nfspacl_version4,
+#endif
};

struct rpc_program nfsacl_program = {
@@ -670,17 +674,18 @@ static int nfs_start_lockd(struct nfs_server *server)
}

/*
- * Initialise an NFSv3 ACL client connection
+ * Initialise an NFSv3/NFSv4 ACL client connection
*/
-#ifdef CONFIG_NFS_V3_ACL
-static void nfs_init_server_aclclient(struct nfs_server *server)
+#if defined(CONFIG_NFS_V3_ACL) || defined(CONFIG_NFS4_FS_POSIX_ACL)
+static void nfs_init_server_aclclient(struct nfs_server *server, int version)
{
- if (server->nfs_client->rpc_ops->version != 3)
+ if (server->nfs_client->rpc_ops->version != version)
goto out_noacl;
if (server->flags & NFS_MOUNT_NOACL)
goto out_noacl;

- server->client_acl = rpc_bind_new_program(server->client, &nfsacl_program, 3);
+ server->client_acl = rpc_bind_new_program(server->client,
+ &nfsacl_program, version);
if (IS_ERR(server->client_acl))
goto out_noacl;

@@ -692,7 +697,8 @@ out_noacl:
server->caps &= ~NFS_CAP_PACLS;
}
#else
-static inline void nfs_init_server_aclclient(struct nfs_server *server)
+static inline void nfs_init_server_aclclient(struct nfs_server *server,
+ int version)
{
server->flags &= ~NFS_MOUNT_NOACL;
server->caps &= ~NFS_CAP_PACLS;
@@ -843,7 +849,7 @@ static int nfs_init_server(struct nfs_server *server,

server->namelen = data->namlen;
/* Create a client RPC handle for the NFSv3 ACL management interface */
- nfs_init_server_aclclient(server);
+ nfs_init_server_aclclient(server, 3);
dprintk("<-- nfs_init_server() = 0 [new %p]\n", clp);
return 0;

@@ -1303,7 +1309,10 @@ static int nfs4_init_server(struct nfs_server *server,
server->port = data->nfs_server.port;

error = nfs_init_server_rpcclient(server, &timeparms, data->auth_flavors[0]);
-
+ if (error < 0)
+ goto error;
+ /* Create a client RPC handle for the NFSv4 ACL management interface */
+ nfs_init_server_aclclient(server, 4);
error:
/* Done */
dprintk("<-- nfs4_init_server() = %d\n", error);
@@ -1490,7 +1499,8 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
if (error < 0)
goto out_free_server;
if (!IS_ERR(source->client_acl))
- nfs_init_server_aclclient(server);
+ nfs_init_server_aclclient(server,
+ source->nfs_client->rpc_ops->version);

/* probe the filesystem info for this server filesystem */
error = nfs_probe_fsinfo(server, fh, &fattr_fsinfo);
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 617273e..eac604e 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -5502,8 +5502,157 @@ struct rpc_version nfs_version4 = {
.procs = nfs4_procedures
};

+#ifdef CONFIG_NFS4_FS_POSIX_ACL
+
+#define NFS4_fh_sz (1 + (NFS4_FHSIZE >> 2))
+#define NFS4_getpaclargs_sz (NFS4_fh_sz + 1)
+#define NFS4_setpaclargs_sz (NFS4_fh_sz + 1 + XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE))
+#define NFS4_getpaclres_sz (1 + 1 + XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE))
+#define NFS4_setpaclres_sz (1)
+
+/*
+ * Encode GETACL arguments
+ */
+static inline __be32 *
+nfs4_xdr_encode_fhandle(__be32 *p, const struct nfs_fh *fh)
+{
+ return xdr_encode_array(p, fh->data, fh->size);
+}
+
+static int
+nfs4_xdr_getpaclargs(struct rpc_rqst *req, __be32 *p,
+ struct nfs4_getpaclargs *args)
+{
+ struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
+ unsigned int replen;
+
+ p = nfs4_xdr_encode_fhandle(p, args->fh);
+ *p++ = htonl(args->mask);
+ req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
+
+ if (args->mask & (NFS_ACL | NFS_DFACL)) {
+ /* Inline the page array */
+ replen = (RPC_REPHDRSIZE + auth->au_rslack +
+ NFS4_getpaclres_sz) << 2;
+ xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, 0,
+ NFSACL_MAXPAGES << PAGE_SHIFT);
+ }
+ return 0;
+}
+
+/*
+ * Encode SETACL arguments
+ */
+static int
+nfs4_xdr_setpaclargs(struct rpc_rqst *req, __be32 *p,
+ struct nfs4_setpaclargs *args)
+{
+ struct xdr_buf *buf = &req->rq_snd_buf;
+ unsigned int base;
+ int err;
+
+ p = nfs4_xdr_encode_fhandle(p, NFS_FH(args->inode));
+ *p++ = htonl(args->mask);
+ req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
+ base = req->rq_slen;
+
+ if (args->npages != 0)
+ xdr_encode_pages(buf, args->pages, 0, args->len);
+ else
+ req->rq_slen = xdr_adjust_iovec(req->rq_svec,
+ p + XDR_QUADLEN(args->len));
+
+ err = nfsacl_encode(buf, base, args->inode,
+ (args->mask & NFS_ACL) ?
+ args->acl_access : NULL, 1, 0);
+ if (err > 0)
+ err = nfsacl_encode(buf, base + err, args->inode,
+ (args->mask & NFS_DFACL) ?
+ args->acl_default : NULL, 1,
+ NFS_ACL_DEFAULT);
+ return (err > 0) ? 0 : err;
+}
+
+/*
+ * Decode GETACL reply
+ */
+static int
+nfs4_xdr_getpaclres(struct rpc_rqst *req, __be32 *p,
+ struct nfs4_getpaclres *res)
+{
+ struct xdr_buf *buf = &req->rq_rcv_buf;
+ int status = ntohl(*p++);
+ struct posix_acl **acl;
+ unsigned int *aclcnt;
+ int err, base;
+
+ if (status != 0)
+ return nfs4_stat_to_errno(status);
+ res->mask = ntohl(*p++);
+ if (res->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT))
+ return -EINVAL;
+ base = (char *)p - (char *)req->rq_rcv_buf.head->iov_base;
+
+ acl = (res->mask & NFS_ACL) ? &res->acl_access : NULL;
+ aclcnt = (res->mask & NFS_ACLCNT) ? &res->acl_access_count : NULL;
+ err = nfsacl_decode(buf, base, aclcnt, acl);
+
+ acl = (res->mask & NFS_DFACL) ? &res->acl_default : NULL;
+ aclcnt = (res->mask & NFS_DFACLCNT) ? &res->acl_default_count : NULL;
+ if (err > 0)
+ err = nfsacl_decode(buf, base + err, aclcnt, acl);
+ return (err > 0) ? 0 : err;
+}
+
+/*
+ * Decode setacl reply.
+ */
+static int
+nfs4_xdr_setpaclres(struct rpc_rqst *req, __be32 *p, void *dummy)
+{
+ int status = ntohl(*p++);
+
+ if (status)
+ return nfs4_stat_to_errno(status);
+ return 0;
+}
+
+static struct rpc_procinfo nfs4_pacl_procedures[] = {
+ [NFSPROC4_CLNT_GETPACL] = {
+ .p_proc = NFSPROC4_CLNT_GETPACL,
+ .p_encode = (kxdrproc_t) nfs4_xdr_getpaclargs,
+ .p_decode = (kxdrproc_t) nfs4_xdr_getpaclres,
+ .p_arglen = NFS4_getpaclargs_sz,
+ .p_replen = NFS4_getpaclres_sz,
+ .p_statidx = NFSPROC4_CLNT_GETPACL,
+ .p_timer = 1,
+ .p_name = "GETPACL",
+ },
+ [NFSPROC4_CLNT_SETPACL] = {
+ .p_proc = NFSPROC4_CLNT_SETPACL,
+ .p_encode = (kxdrproc_t) nfs4_xdr_setpaclargs,
+ .p_decode = (kxdrproc_t) nfs4_xdr_setpaclres,
+ .p_arglen = NFS4_setpaclargs_sz,
+ .p_replen = NFS4_setpaclres_sz,
+ .p_statidx = NFSPROC4_CLNT_SETPACL,
+ .p_timer = 0,
+ .p_name = "SETPACL",
+ },
+};
+
+struct rpc_version nfspacl_version4 = {
+ .number = 4,
+ .nrprocs = sizeof(nfs4_pacl_procedures)/
+ sizeof(nfs4_pacl_procedures[0]),
+ .procs = nfs4_pacl_procedures,
+};
+#endif /* CONFIG_NFS4_FS_POSIX_ACL */
+
/*
* Local variables:
* c-basic-offset: 8
* End:
*/
+
+/* LocalWords: nfs
+ */
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 62f63fb..39acac6 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -886,6 +886,30 @@ struct nfs4_fs_locations_res {
struct nfs4_sequence_res seq_res;
};

+struct nfs4_getpaclargs {
+ struct nfs_fh *fh;
+ int mask;
+ struct page **pages;
+};
+
+struct nfs4_setpaclargs {
+ struct inode *inode;
+ int mask;
+ struct posix_acl *acl_access;
+ struct posix_acl *acl_default;
+ size_t len;
+ unsigned int npages;
+ struct page **pages;
+};
+
+struct nfs4_getpaclres {
+ int mask;
+ unsigned int acl_access_count;
+ unsigned int acl_default_count;
+ struct posix_acl *acl_access;
+ struct posix_acl *acl_default;
+};
+
#endif /* CONFIG_NFS_V4 */

struct nfstime4 {
@@ -1061,5 +1085,6 @@ extern struct rpc_version nfs_version4;

extern struct rpc_version nfsacl_version3;
extern struct rpc_program nfsacl_program;
+extern struct rpc_version nfspacl_version4;

#endif
diff --git a/include/linux/nfsacl.h b/include/linux/nfsacl.h
index 43011b6..15ffa58 100644
--- a/include/linux/nfsacl.h
+++ b/include/linux/nfsacl.h
@@ -16,6 +16,8 @@
#define ACLPROC3_GETACL 1
#define ACLPROC3_SETACL 2

+#define NFSPROC4_CLNT_GETPACL 1
+#define NFSPROC4_CLNT_SETPACL 2

/* Flags for the getacl/setacl mode */
#define NFS_ACL 0x0001
--
1.6.4.2.253.g0b1fac


2009-09-02 12:25:15

by Aneesh Kumar K.V

[permalink] [raw]
Subject: [RFC PATCH 7/8] nfsv4: Implement getfacl

Signed-off-by: Aneesh Kumar K.V <[email protected]>
---
fs/nfs/nfs4pacl.c | 31 +++++++++++++++++++++++++++++--
1 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/fs/nfs/nfs4pacl.c b/fs/nfs/nfs4pacl.c
index 162f4c5..a13a833 100644
--- a/fs/nfs/nfs4pacl.c
+++ b/fs/nfs/nfs4pacl.c
@@ -138,7 +138,22 @@ static size_t nfs4_xattr_list_pacl_default(struct inode *inode, char *list,
static int nfs4_xattr_get_pacl_default(struct inode *inode, const char *key,
void *buf, size_t buflen)
{
- return -EOPNOTSUPP;
+ int error = 0;
+ struct posix_acl *acl;
+
+ acl = nfs4_proc_getacl(inode, ACL_TYPE_DEFAULT);
+ if (IS_ERR(acl))
+ return PTR_ERR(acl);
+ else if (acl) {
+ if (acl->a_count == 0)
+ error = -ENODATA;
+ else
+ error = posix_acl_to_xattr(acl, buf, buflen);
+ posix_acl_release(acl);
+ } else
+ error = -ENODATA;
+
+ return error;
}

static int nfs4_xattr_set_pacl_default(struct inode *inode, const char *key,
@@ -179,7 +194,19 @@ static size_t nfs4_xattr_list_pacl_access(struct inode *inode, char *list,
static int nfs4_xattr_get_pacl_access(struct inode *inode, const char *key,
void *buf, size_t buflen)
{
- return -EOPNOTSUPP;
+ int error = 0;
+ struct posix_acl *acl;
+
+ acl = nfs4_proc_getacl(inode, ACL_TYPE_ACCESS);
+ if (IS_ERR(acl))
+ return PTR_ERR(acl);
+ else if (acl) {
+ error = posix_acl_to_xattr(acl, buf, buflen);
+ posix_acl_release(acl);
+ } else
+ error = -ENODATA;
+
+ return error;
}

static int nfs4_xattr_set_pacl_access(struct inode *inode, const char *key,
--
1.6.4.2.253.g0b1fac


2009-09-02 12:25:05

by Aneesh Kumar K.V

[permalink] [raw]
Subject: [RFC PATCH 4/8] nfs: use different capability flag for v4 and posix acl

NVFSv4 can now support V4 acl and posix ACL. Use different
flag indicate the capability

Signed-off-by: Aneesh Kumar K.V <[email protected]>
---
fs/nfs/client.c | 6 +++---
fs/nfs/nfs3acl.c | 8 ++++----
fs/nfs/nfs4proc.c | 4 ++--
fs/nfs/super.c | 2 +-
include/linux/nfs_fs_sb.h | 4 ++--
5 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 8d25ccb..ea3a6b7 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -685,17 +685,17 @@ static void nfs_init_server_aclclient(struct nfs_server *server)
goto out_noacl;

/* No errors! Assume that Sun nfsacls are supported */
- server->caps |= NFS_CAP_ACLS;
+ server->caps |= NFS_CAP_PACLS;
return;

out_noacl:
- server->caps &= ~NFS_CAP_ACLS;
+ server->caps &= ~NFS_CAP_PACLS;
}
#else
static inline void nfs_init_server_aclclient(struct nfs_server *server)
{
server->flags &= ~NFS_MOUNT_NOACL;
- server->caps &= ~NFS_CAP_ACLS;
+ server->caps &= ~NFS_CAP_PACLS;
}
#endif

diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c
index bac6051..963b5d6 100644
--- a/fs/nfs/nfs3acl.c
+++ b/fs/nfs/nfs3acl.c
@@ -201,7 +201,7 @@ struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type)
struct posix_acl *acl;
int status, count;

- if (!nfs_server_capable(inode, NFS_CAP_ACLS))
+ if (!nfs_server_capable(inode, NFS_CAP_PACLS))
return ERR_PTR(-EOPNOTSUPP);

status = nfs_revalidate_inode(server, inode);
@@ -242,7 +242,7 @@ struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type)
case -EPFNOSUPPORT:
case -EPROTONOSUPPORT:
dprintk("NFS_V3_ACL extension not supported; disabling\n");
- server->caps &= ~NFS_CAP_ACLS;
+ server->caps &= ~NFS_CAP_PACLS;
case -ENOTSUPP:
status = -EOPNOTSUPP;
default:
@@ -304,7 +304,7 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
int status;

status = -EOPNOTSUPP;
- if (!nfs_server_capable(inode, NFS_CAP_ACLS))
+ if (!nfs_server_capable(inode, NFS_CAP_PACLS))
goto out;

/* We are doing this here, because XDR marshalling can only
@@ -350,7 +350,7 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
case -EPROTONOSUPPORT:
dprintk("NFS_V3_ACL SETACL RPC not supported"
"(will not retry)\n");
- server->caps &= ~NFS_CAP_ACLS;
+ server->caps &= ~NFS_CAP_PACLS;
case -ENOTSUPP:
status = -EOPNOTSUPP;
}
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index eb93426..2c71885 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -1999,7 +1999,7 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
if (status == 0) {
memcpy(server->attr_bitmask, res.attr_bitmask, sizeof(server->attr_bitmask));
if (res.attr_bitmask[0] & FATTR4_WORD0_ACL)
- server->caps |= NFS_CAP_ACLS;
+ server->caps |= NFS_CAP_V4ACLS;
if (res.has_links != 0)
server->caps |= NFS_CAP_HARDLINKS;
if (res.has_symlinks != 0)
@@ -3077,7 +3077,7 @@ int nfs4_proc_renew(struct nfs_client *clp, struct rpc_cred *cred)

static inline int nfs4_server_supports_acls(struct nfs_server *server)
{
- return (server->caps & NFS_CAP_ACLS)
+ return (server->caps & NFS_CAP_V4ACLS)
&& (server->acl_bitmask & ACL4_SUPPORT_ALLOW_ACL)
&& (server->acl_bitmask & ACL4_SUPPORT_DENY_ACL);
}
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 2f2a5bd..abe9251 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -2317,7 +2317,7 @@ static void nfs4_fill_super(struct super_block *sb)

static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *args)
{
- args->flags &= ~(NFS_MOUNT_NONLM|NFS_MOUNT_NOACL|NFS_MOUNT_VER3);
+ args->flags &= ~(NFS_MOUNT_NONLM|NFS_CAP_V4ACLS|NFS_MOUNT_VER3);
}

/*
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index 19fe15d..2837ce3 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -165,9 +165,9 @@ struct nfs_server {
#define NFS_CAP_READDIRPLUS (1U << 0)
#define NFS_CAP_HARDLINKS (1U << 1)
#define NFS_CAP_SYMLINKS (1U << 2)
-#define NFS_CAP_ACLS (1U << 3)
+#define NFS_CAP_PACLS (1U << 3)
#define NFS_CAP_ATOMIC_OPEN (1U << 4)
-
+#define NFS_CAP_V4ACLS (1U << 8)

/* maximum number of slots to use */
#define NFS4_MAX_SLOT_TABLE RPC_MAX_SLOT_TABLE
--
1.6.4.2.253.g0b1fac


2009-09-02 12:24:58

by Aneesh Kumar K.V

[permalink] [raw]
Subject: [RFC PATCH 2/8] nfsv4: Switch to generic xattr handling code

This patch make nfsv4 use the generic xattr handling code
to get the nfsv4 acl. This will help us to add posix acl
support to nfsv4 in later patches

Signed-off-by: Aneesh Kumar K.V <[email protected]>
---
fs/nfs/dir.c | 9 +++++--
fs/nfs/nfs4_fs.h | 6 -----
fs/nfs/nfs4proc.c | 57 ++++++++++++++++++++++++++++++----------------------
fs/nfs/super.c | 3 ++
4 files changed, 42 insertions(+), 33 deletions(-)

diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 32062c3..f9278a2 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -33,6 +33,8 @@
#include <linux/namei.h>
#include <linux/mount.h>
#include <linux/sched.h>
+#include <linux/xattr.h>
+

#include "nfs4_fs.h"
#include "delegation.h"
@@ -117,9 +119,10 @@ const struct inode_operations nfs4_dir_inode_operations = {
.permission = nfs_permission,
.getattr = nfs_getattr,
.setattr = nfs_setattr,
- .getxattr = nfs4_getxattr,
- .setxattr = nfs4_setxattr,
- .listxattr = nfs4_listxattr,
+ .getxattr = generic_getxattr,
+ .setxattr = generic_setxattr,
+ .listxattr = generic_listxattr,
+ .removexattr = generic_removexattr,
};

#endif /* CONFIG_NFS_V4 */
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 6ea07a3..c9869f5 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -191,12 +191,6 @@ struct nfs4_state_maintenance_ops {
extern const struct dentry_operations nfs4_dentry_operations;
extern const struct inode_operations nfs4_dir_inode_operations;

-/* inode.c */
-extern ssize_t nfs4_getxattr(struct dentry *, const char *, void *, size_t);
-extern int nfs4_setxattr(struct dentry *, const char *, const void *, size_t, int);
-extern ssize_t nfs4_listxattr(struct dentry *, char *, size_t);
-
-
/* nfs4proc.c */
extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *);
extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct rpc_cred *);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 6917311..fa60261 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -49,6 +49,7 @@
#include <linux/mount.h>
#include <linux/module.h>
#include <linux/sunrpc/bc_xprt.h>
+#include <linux/xattr.h>

#include "nfs4_fs.h"
#include "delegation.h"
@@ -4172,42 +4173,37 @@ out:

#define XATTR_NAME_NFSV4_ACL "system.nfs4_acl"

-int nfs4_setxattr(struct dentry *dentry, const char *key, const void *buf,
- size_t buflen, int flags)
+static int nfs4_xattr_set_nfs4_acl(struct inode *inode, const char *key,
+ const void *buf, size_t buflen, int flags)
{
- struct inode *inode = dentry->d_inode;
-
- if (strcmp(key, XATTR_NAME_NFSV4_ACL) != 0)
- return -EOPNOTSUPP;
+ if (strcmp(key, "") != 0)
+ return -EINVAL;

return nfs4_proc_set_acl(inode, buf, buflen);
}

-/* The getxattr man page suggests returning -ENODATA for unknown attributes,
- * and that's what we'll do for e.g. user attributes that haven't been set.
- * But we'll follow ext2/ext3's lead by returning -EOPNOTSUPP for unsupported
- * attributes in kernel-managed attribute namespaces. */
-ssize_t nfs4_getxattr(struct dentry *dentry, const char *key, void *buf,
- size_t buflen)
+static int nfs4_xattr_get_nfs4_acl(struct inode *inode, const char *key,
+ void *buf, size_t buflen)
{
- struct inode *inode = dentry->d_inode;
-
- if (strcmp(key, XATTR_NAME_NFSV4_ACL) != 0)
- return -EOPNOTSUPP;
+ if (strcmp(key, "") != 0)
+ return -EINVAL;

return nfs4_proc_get_acl(inode, buf, buflen);
}

-ssize_t nfs4_listxattr(struct dentry *dentry, char *buf, size_t buflen)
+static size_t nfs4_xattr_list_nfs4_acl(struct inode *inode, char *list,
+ size_t list_len, const char *name,
+ size_t name_len)
{
size_t len = strlen(XATTR_NAME_NFSV4_ACL) + 1;

- if (!nfs4_server_supports_acls(NFS_SERVER(dentry->d_inode)))
+ if (!nfs4_server_supports_acls(NFS_SERVER(inode)))
return 0;
- if (buf && buflen < len)
+
+ if (list && len <= list_len)
+ memcpy(list, XATTR_NAME_NFSV4_ACL, len);
+ else
return -ERANGE;
- if (buf)
- memcpy(buf, XATTR_NAME_NFSV4_ACL, len);
return len;
}

@@ -4988,9 +4984,10 @@ static const struct inode_operations nfs4_file_inode_operations = {
.permission = nfs_permission,
.getattr = nfs_getattr,
.setattr = nfs_setattr,
- .getxattr = nfs4_getxattr,
- .setxattr = nfs4_setxattr,
- .listxattr = nfs4_listxattr,
+ .getxattr = generic_getxattr,
+ .setxattr = generic_setxattr,
+ .listxattr = generic_listxattr,
+ .removexattr = generic_removexattr,
};

const struct nfs_rpc_ops nfs_v4_clientops = {
@@ -5032,6 +5029,18 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
.close_context = nfs4_close_context,
};

+struct xattr_handler nfs4_xattr_nfs4_acl_handler = {
+ .prefix = XATTR_NAME_NFSV4_ACL,
+ .list = nfs4_xattr_list_nfs4_acl,
+ .get = nfs4_xattr_get_nfs4_acl,
+ .set = nfs4_xattr_set_nfs4_acl,
+};
+
+struct xattr_handler *nfs4_xattr_handlers[] = {
+ &nfs4_xattr_nfs4_acl_handler,
+ NULL
+};
+
/*
* Local variables:
* c-basic-offset: 8
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 0b4cbdc..2f2a5bd 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -242,6 +242,7 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type,
int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
static void nfs_kill_super(struct super_block *);
static int nfs_remount(struct super_block *sb, int *flags, char *raw_data);
+extern struct xattr_handler *nfs4_xattr_handlers[];

static struct file_system_type nfs_fs_type = {
.owner = THIS_MODULE,
@@ -2299,6 +2300,7 @@ static void nfs4_clone_super(struct super_block *sb,
sb->s_maxbytes = old_sb->s_maxbytes;
sb->s_time_gran = 1;
sb->s_op = old_sb->s_op;
+ sb->s_xattr = old_sb->s_xattr;
nfs_initialise_sb(sb);
}

@@ -2309,6 +2311,7 @@ static void nfs4_fill_super(struct super_block *sb)
{
sb->s_time_gran = 1;
sb->s_op = &nfs4_sops;
+ sb->s_xattr = nfs4_xattr_handlers;
nfs_initialise_sb(sb);
}

--
1.6.4.2.253.g0b1fac


2009-09-02 12:25:20

by Aneesh Kumar K.V

[permalink] [raw]
Subject: [RFC PATCH 8/8] nfsv4: Implement setfacl

Signed-off-by: Aneesh Kumar K.V <[email protected]>
---
fs/nfs/nfs4pacl.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 138 insertions(+), 2 deletions(-)

diff --git a/fs/nfs/nfs4pacl.c b/fs/nfs/nfs4pacl.c
index a13a833..1978739 100644
--- a/fs/nfs/nfs4pacl.c
+++ b/fs/nfs/nfs4pacl.c
@@ -110,6 +110,124 @@ getout:
return acl;
}

+static int nfs4_proc_setacls(struct inode *inode, struct posix_acl *acl,
+ struct posix_acl *dfacl)
+{
+ struct nfs_server *server = NFS_SERVER(inode);
+ struct page *pages[NFSACL_MAXPAGES];
+ struct nfs4_setpaclargs args = {
+ .inode = inode,
+ .mask = NFS_ACL,
+ .acl_access = acl,
+ .pages = pages,
+ };
+ struct rpc_message msg = {
+ .rpc_argp = &args,
+ };
+ int status;
+
+ status = -EOPNOTSUPP;
+ if (!nfs_server_capable(inode, NFS_CAP_PACLS))
+ goto out;
+
+ /* We are doing this here, because XDR marshalling can only
+ return -ENOMEM. */
+ status = -ENOSPC;
+ if (acl != NULL && acl->a_count > NFS_ACL_MAX_ENTRIES)
+ goto out;
+ if (dfacl != NULL && dfacl->a_count > NFS_ACL_MAX_ENTRIES)
+ goto out;
+ if (S_ISDIR(inode->i_mode)) {
+ args.mask |= NFS_DFACL;
+ args.acl_default = dfacl;
+ args.len = nfsacl_size(acl, dfacl);
+ } else
+ args.len = nfsacl_size(acl, NULL);
+
+ if (args.len > NFS_ACL_INLINE_BUFSIZE) {
+ unsigned int npages = 1 + ((args.len - 1) >> PAGE_SHIFT);
+
+ status = -ENOMEM;
+ do {
+ args.pages[args.npages] = alloc_page(GFP_KERNEL);
+ if (args.pages[args.npages] == NULL)
+ goto out_freepages;
+ args.npages++;
+ } while (args.npages < npages);
+ }
+
+ dprintk("NFSV4 call setacl\n");
+ msg.rpc_proc = &server->client_acl->cl_procinfo[NFSPROC4_CLNT_SETPACL];
+ status = rpc_call_sync(server->client_acl, &msg, 0);
+ nfs_access_zap_cache(inode);
+ nfs_zap_acl_cache(inode);
+ dprintk("NFSv4 reply setacl: %d\n", status);
+
+ switch (status) {
+ case 0:
+ if (!IS_ERR(dfacl))
+ set_cached_acl(inode, ACL_TYPE_DEFAULT, dfacl);
+ if (!IS_ERR(acl))
+ set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
+ break;
+ case -EPFNOSUPPORT:
+ case -EPROTONOSUPPORT:
+ dprintk("NFS_V4_PACL SETACL RPC not supported"
+ "(will not retry)\n");
+ server->caps &= ~NFS_CAP_PACLS;
+ case -ENOTSUPP:
+ status = -EOPNOTSUPP;
+ }
+out_freepages:
+ while (args.npages != 0) {
+ args.npages--;
+ __free_page(args.pages[args.npages]);
+ }
+out:
+ return status;
+}
+
+int nfs4_proc_setacl(struct inode *inode, int type, struct posix_acl *acl)
+{
+ int status;
+ struct posix_acl *alloc = NULL, *dfacl = NULL;
+
+ if (S_ISDIR(inode->i_mode)) {
+ switch (type) {
+ case ACL_TYPE_ACCESS:
+ alloc = dfacl = nfs4_proc_getacl(inode,
+ ACL_TYPE_DEFAULT);
+ if (IS_ERR(alloc))
+ goto fail;
+ break;
+
+ case ACL_TYPE_DEFAULT:
+ dfacl = acl;
+ alloc = acl = nfs4_proc_getacl(inode,
+ ACL_TYPE_ACCESS);
+ if (IS_ERR(alloc))
+ goto fail;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ } else if (type != ACL_TYPE_ACCESS)
+ return -EINVAL;
+
+ if (acl == NULL) {
+ alloc = acl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL);
+ if (IS_ERR(alloc))
+ goto fail;
+ }
+ status = nfs4_proc_setacls(inode, acl, dfacl);
+ posix_acl_release(alloc);
+ return status;
+
+fail:
+ return PTR_ERR(alloc);
+}
+
static size_t nfs4_xattr_list_pacl_default(struct inode *inode, char *list,
size_t list_len, const char *name,
size_t name_len)
@@ -159,7 +277,16 @@ static int nfs4_xattr_get_pacl_default(struct inode *inode, const char *key,
static int nfs4_xattr_set_pacl_default(struct inode *inode, const char *key,
const void *buf, size_t buflen, int flags)
{
- return -EOPNOTSUPP;
+ int error;
+ struct posix_acl *acl;
+
+ acl = posix_acl_from_xattr(buf, buflen);
+ if (IS_ERR(acl))
+ return PTR_ERR(acl);
+ error = nfs4_proc_setacl(inode, ACL_TYPE_DEFAULT, acl);
+ posix_acl_release(acl);
+
+ return error;
}

struct xattr_handler nfs4_xattr_pacl_default_handler = {
@@ -212,7 +339,16 @@ static int nfs4_xattr_get_pacl_access(struct inode *inode, const char *key,
static int nfs4_xattr_set_pacl_access(struct inode *inode, const char *key,
const void *buf, size_t buflen, int flags)
{
- return -EOPNOTSUPP;
+ int error;
+ struct posix_acl *acl;
+
+ acl = posix_acl_from_xattr(buf, buflen);
+ if (IS_ERR(acl))
+ return PTR_ERR(acl);
+ error = nfs4_proc_setacl(inode, ACL_TYPE_ACCESS, acl);
+ posix_acl_release(acl);
+
+ return error;
}


--
1.6.4.2.253.g0b1fac


2009-09-02 12:25:02

by Aneesh Kumar K.V

[permalink] [raw]
Subject: [RFC PATCH 3/8] nfsv4: Add support for posix ACL

Add posix ACL support. This implements POSIX over NFSV4 ACL.

Signed-off-by: Aneesh Kumar K.V <[email protected]>
---
fs/nfs/Kconfig | 6 +++++
fs/nfs/Makefile | 1 +
fs/nfs/nfs4pacl.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++
fs/nfs/nfs4proc.c | 7 +++++-
4 files changed, 75 insertions(+), 1 deletions(-)
create mode 100644 fs/nfs/nfs4pacl.c

diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig
index 2a77bc2..744ea00 100644
--- a/fs/nfs/Kconfig
+++ b/fs/nfs/Kconfig
@@ -101,3 +101,9 @@ config NFS_FSCACHE
help
Say Y here if you want NFS data to be cached locally on disc through
the general filesystem cache manager
+
+config NFS4_FS_POSIX_ACL
+ bool "NFS client support for NFSV4 posix acl support"
+ depends on NFS_V4
+ help
+ This option enables support for modifying POSIX ACL from NFS clients
diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
index 8451598..f888f5c 100644
--- a/fs/nfs/Makefile
+++ b/fs/nfs/Makefile
@@ -16,3 +16,4 @@ nfs-$(CONFIG_NFS_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \
nfs4namespace.o
nfs-$(CONFIG_SYSCTL) += sysctl.o
nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o
+nfs-$(CONFIG_NFS4_FS_POSIX_ACL) += nfs4pacl.o
diff --git a/fs/nfs/nfs4pacl.c b/fs/nfs/nfs4pacl.c
new file mode 100644
index 0000000..c1c2b04
--- /dev/null
+++ b/fs/nfs/nfs4pacl.c
@@ -0,0 +1,62 @@
+#include <linux/fs.h>
+#include <linux/nfs.h>
+#include <linux/nfs3.h>
+#include <linux/nfs_fs.h>
+#include <linux/posix_acl_xattr.h>
+#include <linux/nfsacl.h>
+#include <linux/xattr.h>
+
+#include "internal.h"
+
+static size_t nfs4_xattr_list_pacl_default(struct inode *inode, char *list,
+ size_t list_len, const char *name,
+ size_t name_len)
+{
+ return 0;
+}
+
+static int nfs4_xattr_get_pacl_default(struct inode *inode, const char *key,
+ void *buf, size_t buflen)
+{
+ return -EOPNOTSUPP;
+}
+
+static int nfs4_xattr_set_pacl_default(struct inode *inode, const char *key,
+ const void *buf, size_t buflen, int flags)
+{
+ return -EOPNOTSUPP;
+}
+
+struct xattr_handler nfs4_xattr_pacl_default_handler = {
+ .prefix = POSIX_ACL_XATTR_DEFAULT,
+ .list = nfs4_xattr_list_pacl_default,
+ .get = nfs4_xattr_get_pacl_default,
+ .set = nfs4_xattr_set_pacl_default,
+};
+
+static size_t nfs4_xattr_list_pacl_access(struct inode *inode, char *list,
+ size_t list_len, const char *name,
+ size_t name_len)
+{
+ return 0;
+}
+
+static int nfs4_xattr_get_pacl_access(struct inode *inode, const char *key,
+ void *buf, size_t buflen)
+{
+ return -EOPNOTSUPP;
+}
+
+static int nfs4_xattr_set_pacl_access(struct inode *inode, const char *key,
+ const void *buf, size_t buflen, int flags)
+{
+ return -EOPNOTSUPP;
+}
+
+
+struct xattr_handler nfs4_xattr_pacl_access_handler = {
+ .prefix = POSIX_ACL_XATTR_ACCESS,
+ .list = nfs4_xattr_list_pacl_access,
+ .get = nfs4_xattr_get_pacl_access,
+ .set = nfs4_xattr_set_pacl_access,
+};
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index fa60261..eb93426 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -5035,9 +5035,14 @@ struct xattr_handler nfs4_xattr_nfs4_acl_handler = {
.get = nfs4_xattr_get_nfs4_acl,
.set = nfs4_xattr_set_nfs4_acl,
};
-
+extern struct xattr_handler nfs4_xattr_pacl_access_handler;
+extern struct xattr_handler nfs4_xattr_pacl_default_handler;
struct xattr_handler *nfs4_xattr_handlers[] = {
&nfs4_xattr_nfs4_acl_handler,
+#ifdef CONFIG_NFS4_FS_POSIX_ACL
+ &nfs4_xattr_pacl_access_handler,
+ &nfs4_xattr_pacl_default_handler,
+#endif
NULL
};

--
1.6.4.2.253.g0b1fac


2009-09-02 12:25:14

by Aneesh Kumar K.V

[permalink] [raw]
Subject: [RFC PATCH 6/8] nfsv4: Implement posix listxattr

Signed-off-by: Aneesh Kumar K.V <[email protected]>
---
fs/nfs/nfs4pacl.c | 141 +++++++++++++++++++++++++++++++++++++++++++++++++++-
fs/nfs/nfs4proc.c | 4 ++
2 files changed, 142 insertions(+), 3 deletions(-)

diff --git a/fs/nfs/nfs4pacl.c b/fs/nfs/nfs4pacl.c
index c1c2b04..162f4c5 100644
--- a/fs/nfs/nfs4pacl.c
+++ b/fs/nfs/nfs4pacl.c
@@ -7,12 +7,132 @@
#include <linux/xattr.h>

#include "internal.h"
+#define NFSDBG_FACILITY NFSDBG_PROC
+
+struct posix_acl *nfs4_proc_getacl(struct inode *inode, int type)
+{
+ struct nfs_server *server = NFS_SERVER(inode);
+ struct nfs4_getpaclres res;
+ struct page *pages[NFSACL_MAXPAGES] = { };
+ struct nfs4_getpaclargs args = {
+ .fh = NFS_FH(inode),
+ /* The xdr layer may allocate pages here. */
+ .pages = pages,
+ };
+ struct rpc_message msg = {
+ .rpc_argp = &args,
+ .rpc_resp = &res,
+ };
+ struct posix_acl *acl;
+ int status, count;
+
+ memset(&res, 0, sizeof(struct nfs4_getpaclres));
+ if (!nfs_server_capable(inode, NFS_CAP_PACLS))
+ return ERR_PTR(-EOPNOTSUPP);
+
+ status = nfs_revalidate_inode(server, inode);
+ if (status < 0)
+ return ERR_PTR(status);
+ acl = get_cached_acl(inode, type);
+ if (acl != ACL_NOT_CACHED)
+ return acl;
+ acl = NULL;
+
+ /*
+ * Only get the access acl when explicitly requested: We don't
+ * need it for access decisions, and only some applications use
+ * it. Applications which request the access acl first are not
+ * penalized from this optimization.
+ */
+ if (type == ACL_TYPE_ACCESS)
+ args.mask |= NFS_ACLCNT|NFS_ACL;
+ if (S_ISDIR(inode->i_mode))
+ args.mask |= NFS_DFACLCNT|NFS_DFACL;
+ if (args.mask == 0)
+ return NULL;
+
+ dprintk("NFS4 call getacl\n");
+ msg.rpc_proc = &server->client_acl->cl_procinfo[NFSPROC4_CLNT_GETPACL];
+ status = rpc_call_sync(server->client_acl, &msg, 0);
+ dprintk("NFS4 reply getacl: %d\n", status);
+
+ /* pages may have been allocated at the xdr layer. */
+ for (count = 0; count < NFSACL_MAXPAGES && args.pages[count]; count++)
+ __free_page(args.pages[count]);
+
+ switch (status) {
+ case 0:
+ break;
+ case -EPFNOSUPPORT:
+ case -EPROTONOSUPPORT:
+ dprintk("NFS_V4_PACL extension not supported; disabling\n");
+ server->caps &= ~NFS_CAP_PACLS;
+ case -ENOTSUPP:
+ status = -EOPNOTSUPP;
+ default:
+ goto getout;
+ }
+ if ((args.mask & res.mask) != args.mask) {
+ status = -EIO;
+ goto getout;
+ }
+
+ if (res.acl_access != NULL) {
+ if (posix_acl_equiv_mode(res.acl_access, NULL) == 0) {
+ posix_acl_release(res.acl_access);
+ res.acl_access = NULL;
+ }
+ }
+ if (res.mask & NFS_ACL)
+ set_cached_acl(inode, type, res.acl_access);
+ if (res.mask & NFS_DFACL)
+ set_cached_acl(inode, type, res.acl_default);
+
+ switch (type) {
+ case ACL_TYPE_ACCESS:
+ acl = res.acl_access;
+ res.acl_access = NULL;
+ break;
+
+ case ACL_TYPE_DEFAULT:
+ acl = res.acl_default;
+ res.acl_default = NULL;
+ }
+
+getout:
+ posix_acl_release(res.acl_access);
+ posix_acl_release(res.acl_default);
+
+ if (status != 0) {
+ posix_acl_release(acl);
+ acl = ERR_PTR(status);
+ }
+ return acl;
+}

static size_t nfs4_xattr_list_pacl_default(struct inode *inode, char *list,
size_t list_len, const char *name,
size_t name_len)
{
- return 0;
+ int ret = 0;
+ struct posix_acl *acl;
+ size_t len = strlen(POSIX_ACL_XATTR_DEFAULT) + 1;
+
+ if (S_ISDIR(inode->i_mode)) {
+ acl = nfs4_proc_getacl(inode, ACL_TYPE_DEFAULT);
+ if (IS_ERR(acl))
+ return PTR_ERR(acl);
+ if (acl) {
+ if (list && len <= list_len) {
+ memcpy(list, POSIX_ACL_XATTR_DEFAULT, len);
+ ret = len;
+ } else
+ ret = -ERANGE;
+ posix_acl_release(acl);
+ }
+ return ret;
+ }
+ return ret;
}

static int nfs4_xattr_get_pacl_default(struct inode *inode, const char *key,
@@ -35,10 +155,25 @@ struct xattr_handler nfs4_xattr_pacl_default_handler = {
};

static size_t nfs4_xattr_list_pacl_access(struct inode *inode, char *list,
- size_t list_len, const char *name,
+ size_t list_len, const char *name,
size_t name_len)
{
- return 0;
+ int ret = 0;
+ struct posix_acl *acl;
+ size_t len = strlen(POSIX_ACL_XATTR_ACCESS) + 1;
+
+ acl = nfs4_proc_getacl(inode, ACL_TYPE_ACCESS);
+ if (IS_ERR(acl))
+ return PTR_ERR(acl);
+ if (acl) {
+ if (list && len <= list_len) {
+ memcpy(list, POSIX_ACL_XATTR_ACCESS, len);
+ ret = len;
+ } else
+ ret = -ERANGE;
+ posix_acl_release(acl);
+ }
+ return ret;
}

static int nfs4_xattr_get_pacl_access(struct inode *inode, const char *key,
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 2c71885..b2e8fe4 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -3120,6 +3120,10 @@ static void nfs4_set_cached_acl(struct inode *inode, struct nfs4_cached_acl *acl
static void nfs4_zap_acl_attr(struct inode *inode)
{
nfs4_set_cached_acl(inode, NULL);
+#ifdef CONFIG_NFS4_FS_POSIX_ACL
+ forget_cached_acl(inode, ACL_TYPE_DEFAULT);
+ forget_cached_acl(inode, ACL_TYPE_ACCESS);
+#endif
}

static inline ssize_t nfs4_read_cached_acl(struct inode *inode, char *buf, size_t buflen)
--
1.6.4.2.253.g0b1fac


2009-10-05 17:09:37

by Andreas Gruenbacher

[permalink] [raw]
Subject: Re: POSIX ACL support for NFSV4 (using sideband protocol)

On Monday 05 October 2009 18:44:34 Steve French wrote:
> Recently I looked through NFSv4.1 spec, and it seems to address some
> ACL incompatibilities (with CIFS) by extending the NFSv4 ACL model.
>
> Should we be aiming for an eventual interface that would work for NFSv4.1
> or limiting it to current NFSv4?

I think Automatic Inheritance [*] is important for current Windows clients:
without it it's basically impossible to manage the permissions of entire
directory trees without shooting yourself in the foot.

[*] http://www.nfsv4-editor.org/draft-25/draft-ietf-nfsv4-minorversion1-25.html#auto_inherit

> Any idea on the state of NFSv4.1 it seems to be stuck for almost a year?

Sorry, don't know.

Andreas
_______________________________________________
NFSv4 mailing list
[email protected]
http://linux-nfs.org/cgi-bin/mailman/listinfo/nfsv4

2009-10-05 17:19:05

by Steve French

[permalink] [raw]
Subject: Re: POSIX ACL support for NFSV4 (using sideband protocol)

On Mon, Oct 5, 2009 at 12:09 PM, Andreas Gruenbacher <[email protected]> wrote:
> On Monday 05 October 2009 18:44:34 Steve French wrote:
>> Recently I looked through NFSv4.1 spec, and it seems to address some
>> ACL incompatibilities (with CIFS) by extending the NFSv4 ACL model.
>>
>> Should we be aiming for an eventual interface that would work for NFSv4.1
>> or limiting it to current NFSv4?
>
> I think Automatic Inheritance [*] is important for current Windows clients:
> without it it's basically impossible to manage the permissions of entire
> directory trees without shooting yourself in the foot.

Yes - that piece among the various NFSv41 ACL changes also
jumped out to me as I scanned the NFSv4.1 summary ... in part
because I was looking at some Samba mapping problems (CIFS to NFSv4
ACLs) recently. In any case, seems very useful (even without
any CIFS compatibility issues).


--
Thanks,

Steve
_______________________________________________
NFSv4 mailing list
[email protected]
http://linux-nfs.org/cgi-bin/mailman/listinfo/nfsv4