From: NeilBrown <neilb@cse.unsw.edu.au>

When a client sends an ACL that is a legal NFSv4 ACL, but that we don't
support (because we can't represent it using a POSIX ACL), the correct error
to return is NFS4ERR_ATTRNOTSUPP.

(rfc3530, section 5.11.1: "If the server recieves a request to set an ACE that
it cannot store, it MUST reject the request with NFS4ERR_ATTRNOTSUPP.  If the
server receives a request to set an ACE that it can store but cannot enforce,
the server SHOULD reject the request with NFS4ERR_ATTRNOTSUPP").

Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/fs/nfsd/nfs4acl.c |    3 +++
 25-akpm/fs/nfsd/nfs4xdr.c |    5 ++++-
 25-akpm/fs/nfsd/vfs.c     |    7 +++++--
 3 files changed, 12 insertions(+), 3 deletions(-)

diff -puN fs/nfsd/nfs4acl.c~nfsd4-acl-error-fix fs/nfsd/nfs4acl.c
--- 25/fs/nfsd/nfs4acl.c~nfsd4-acl-error-fix	2005-03-21 22:50:06.000000000 -0800
+++ 25-akpm/fs/nfsd/nfs4acl.c	2005-03-21 22:50:06.000000000 -0800
@@ -93,6 +93,9 @@ deny_mask(u32 allow_mask, unsigned int f
 	return ret;
 }
 
+/* XXX: modify functions to return NFS errors; they're only ever
+ * used by nfs code, after all.... */
+
 static int
 mode_from_nfs4(u32 perm, unsigned short *mode, unsigned int flags)
 {
diff -puN fs/nfsd/nfs4xdr.c~nfsd4-acl-error-fix fs/nfsd/nfs4xdr.c
--- 25/fs/nfsd/nfs4xdr.c~nfsd4-acl-error-fix	2005-03-21 22:50:06.000000000 -0800
+++ 25-akpm/fs/nfsd/nfs4xdr.c	2005-03-21 22:50:06.000000000 -0800
@@ -1331,7 +1331,10 @@ nfsd4_encode_fattr(struct svc_fh *fhp, s
 		if (bmval0 & FATTR4_WORD0_ACL) {
 			if (status == -EOPNOTSUPP)
 				bmval0 &= ~FATTR4_WORD0_ACL;
-			else if (status != 0)
+			else if (status == -EINVAL) {
+				status = nfserr_attrnotsupp;
+				goto out;
+			} else if (status != 0)
 				goto out_nfserr;
 		}
 	}
diff -puN fs/nfsd/vfs.c~nfsd4-acl-error-fix fs/nfsd/vfs.c
--- 25/fs/nfsd/vfs.c~nfsd4-acl-error-fix	2005-03-21 22:50:06.000000000 -0800
+++ 25-akpm/fs/nfsd/vfs.c	2005-03-21 22:50:06.000000000 -0800
@@ -393,7 +393,7 @@ set_nfsv4_acl_one(struct dentry *dentry,
 	}
 out:
 	kfree(buf);
-	return (error);
+	return error;
 }
 
 int
@@ -417,7 +417,10 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqst
 		flags = NFS4_ACL_DIR;
 
 	error = nfs4_acl_nfsv4_to_posix(acl, &pacl, &dpacl, flags);
-	if (error < 0)
+	if (error == -EINVAL) {
+		error = nfserr_attrnotsupp;
+		goto out;
+	} else if (error < 0)
 		goto out_nfserr;
 
 	if (pacl) {
_