nfs: remove incorrect usage of nfs4 compound response hdr.status
[safe/jmp/linux-2.6] / fs / nfs / nfs3acl.c
index 451112f..cef6255 100644 (file)
@@ -2,9 +2,11 @@
 #include <linux/nfs.h>
 #include <linux/nfs3.h>
 #include <linux/nfs_fs.h>
-#include <linux/xattr_acl.h>
+#include <linux/posix_acl_xattr.h>
 #include <linux/nfsacl.h>
 
+#include "internal.h"
+
 #define NFSDBG_FACILITY        NFSDBG_PROC
 
 ssize_t nfs3_listxattr(struct dentry *dentry, char *buffer, size_t size)
@@ -53,9 +55,9 @@ ssize_t nfs3_getxattr(struct dentry *dentry, const char *name,
        struct posix_acl *acl;
        int type, error = 0;
 
-       if (strcmp(name, XATTR_NAME_ACL_ACCESS) == 0)
+       if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0)
                type = ACL_TYPE_ACCESS;
-       else if (strcmp(name, XATTR_NAME_ACL_DEFAULT) == 0)
+       else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0)
                type = ACL_TYPE_DEFAULT;
        else
                return -EOPNOTSUPP;
@@ -82,9 +84,9 @@ int nfs3_setxattr(struct dentry *dentry, const char *name,
        struct posix_acl *acl;
        int type, error;
 
-       if (strcmp(name, XATTR_NAME_ACL_ACCESS) == 0)
+       if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0)
                type = ACL_TYPE_ACCESS;
-       else if (strcmp(name, XATTR_NAME_ACL_DEFAULT) == 0)
+       else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0)
                type = ACL_TYPE_DEFAULT;
        else
                return -EOPNOTSUPP;
@@ -103,9 +105,9 @@ int nfs3_removexattr(struct dentry *dentry, const char *name)
        struct inode *inode = dentry->d_inode;
        int type;
 
-       if (strcmp(name, XATTR_NAME_ACL_ACCESS) == 0)
+       if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0)
                type = ACL_TYPE_ACCESS;
-       else if (strcmp(name, XATTR_NAME_ACL_DEFAULT) == 0)
+       else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0)
                type = ACL_TYPE_DEFAULT;
        else
                return -EOPNOTSUPP;
@@ -115,11 +117,11 @@ int nfs3_removexattr(struct dentry *dentry, const char *name)
 
 static void __nfs3_forget_cached_acls(struct nfs_inode *nfsi)
 {
-       if (nfsi->acl_access != ERR_PTR(-EAGAIN)) {
+       if (!IS_ERR(nfsi->acl_access)) {
                posix_acl_release(nfsi->acl_access);
                nfsi->acl_access = ERR_PTR(-EAGAIN);
        }
-       if (nfsi->acl_default != ERR_PTR(-EAGAIN)) {
+       if (!IS_ERR(nfsi->acl_default)) {
                posix_acl_release(nfsi->acl_default);
                nfsi->acl_default = ERR_PTR(-EAGAIN);
        }
@@ -137,7 +139,7 @@ void nfs3_forget_cached_acls(struct inode *inode)
 static struct posix_acl *nfs3_get_cached_acl(struct inode *inode, int type)
 {
        struct nfs_inode *nfsi = NFS_I(inode);
-       struct posix_acl *acl = ERR_PTR(-EAGAIN);
+       struct posix_acl *acl = ERR_PTR(-EINVAL);
 
        spin_lock(&inode->i_lock);
        switch(type) {
@@ -150,12 +152,13 @@ static struct posix_acl *nfs3_get_cached_acl(struct inode *inode, int type)
                        break;
 
                default:
-                       return ERR_PTR(-EINVAL);
+                       goto out;
        }
-       if (acl == ERR_PTR(-EAGAIN))
+       if (IS_ERR(acl))
                acl = ERR_PTR(-EAGAIN);
        else
                acl = posix_acl_dup(acl);
+out:
        spin_unlock(&inode->i_lock);
        dprintk("NFS: nfs3_get_cached_acl(%s/%ld, %d) = %p\n", inode->i_sb->s_id,
                inode->i_ino, type, acl);
@@ -171,8 +174,10 @@ static void nfs3_cache_acls(struct inode *inode, struct posix_acl *acl,
                inode->i_ino, acl, dfacl);
        spin_lock(&inode->i_lock);
        __nfs3_forget_cached_acls(NFS_I(inode));
-       nfsi->acl_access = posix_acl_dup(acl);
-       nfsi->acl_default = posix_acl_dup(dfacl);
+       if (!IS_ERR(acl))
+               nfsi->acl_access = posix_acl_dup(acl);
+       if (!IS_ERR(dfacl))
+               nfsi->acl_default = posix_acl_dup(dfacl);
        spin_unlock(&inode->i_lock);
 }
 
@@ -189,6 +194,10 @@ struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type)
        struct nfs3_getaclres res = {
                .fattr =        &fattr,
        };
+       struct rpc_message msg = {
+               .rpc_argp       = &args,
+               .rpc_resp       = &res,
+       };
        struct posix_acl *acl;
        int status, count;
 
@@ -198,6 +207,8 @@ struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type)
        status = nfs_revalidate_inode(server, inode);
        if (status < 0)
                return ERR_PTR(status);
+       if (NFS_I(inode)->cache_validity & NFS_INO_INVALID_ACL)
+               nfs_zap_acl_cache(inode);
        acl = nfs3_get_cached_acl(inode, type);
        if (acl != ERR_PTR(-EAGAIN))
                return acl;
@@ -217,8 +228,9 @@ struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type)
                return NULL;
 
        dprintk("NFS call getacl\n");
-       status = rpc_call(server->client_acl, ACLPROC3_GETACL,
-                         &args, &res, 0);
+       msg.rpc_proc = &server->client_acl->cl_procinfo[ACLPROC3_GETACL];
+       nfs_fattr_init(&fattr);
+       status = rpc_call_sync(server->client_acl, &msg, 0);
        dprintk("NFS reply getacl: %d\n", status);
 
        /* pages may have been allocated at the xdr layer. */
@@ -249,7 +261,9 @@ struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type)
                        res.acl_access = NULL;
                }
        }
-       nfs3_cache_acls(inode, res.acl_access, res.acl_default);
+       nfs3_cache_acls(inode,
+               (res.mask & NFS_ACL)   ? res.acl_access  : ERR_PTR(-EINVAL),
+               (res.mask & NFS_DFACL) ? res.acl_default : ERR_PTR(-EINVAL));
 
        switch(type) {
                case ACL_TYPE_ACCESS:
@@ -285,6 +299,10 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
                .acl_access = acl,
                .pages = pages,
        };
+       struct rpc_message msg = {
+               .rpc_argp       = &args,
+               .rpc_resp       = &fattr,
+       };
        int status, count;
 
        status = -EOPNOTSUPP;
@@ -304,11 +322,11 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
        }
 
        dprintk("NFS call setacl\n");
-       nfs_begin_data_update(inode);
-       status = rpc_call(server->client_acl, ACLPROC3_SETACL,
-                         &args, &fattr, 0);
-       NFS_FLAGS(inode) |= NFS_INO_INVALID_ACCESS;
-       nfs_end_data_update(inode);
+       msg.rpc_proc = &server->client_acl->cl_procinfo[ACLPROC3_SETACL];
+       nfs_fattr_init(&fattr);
+       status = rpc_call_sync(server->client_acl, &msg, 0);
+       nfs_access_zap_cache(inode);
+       nfs_zap_acl_cache(inode);
        dprintk("NFS reply setacl: %d\n", status);
 
        /* pages may have been allocated at the xdr layer. */
@@ -318,6 +336,7 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
        switch (status) {
                case 0:
                        status = nfs_refresh_inode(inode, &fattr);
+                       nfs3_cache_acls(inode, acl, dfacl);
                        break;
                case -EPFNOSUPPORT:
                case -EPROTONOSUPPORT: