Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=76b32999dfff6e59252a8af17a5671a4cf3bcf9b
Commit:     76b32999dfff6e59252a8af17a5671a4cf3bcf9b
Parent:     af22f94ae02ab9dd4fd7fe628c8434a59cc293be
Author:     Trond Myklebust <[EMAIL PROTECTED]>
AuthorDate: Fri Aug 10 17:45:11 2007 -0400
Committer:  Trond Myklebust <[EMAIL PROTECTED]>
CommitDate: Tue Oct 9 17:18:38 2007 -0400

    NFSv4: Make NFSv4 ACCESS calls return attributes too...
    
    It doesn't really make sense to cache an access call without also
    revalidating the attributes.
    
    Signed-off-by: Trond Myklebust <[EMAIL PROTECTED]>
---
 fs/nfs/nfs4proc.c       |   11 +++++++++--
 fs/nfs/nfs4xdr.c        |   27 ++++++++++++++++++++-------
 include/linux/nfs_xdr.h |    3 +++
 3 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 5aa0dd1..0e366a3 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -62,7 +62,6 @@ struct nfs4_opendata;
 static int _nfs4_proc_open(struct nfs4_opendata *data);
 static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct 
nfs_fsinfo *);
 static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server 
*);
-static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry 
*entry);
 static int nfs4_handle_exception(const struct nfs_server *server, int 
errorcode, struct nfs4_exception *exception);
 static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs_client 
*clp);
 static int _nfs4_proc_lookup(struct inode *dir, const struct qstr *name, 
struct nfs_fh *fhandle, struct nfs_fattr *fattr);
@@ -1726,10 +1725,16 @@ static int nfs4_proc_lookup(struct inode *dir, struct 
qstr *name, struct nfs_fh
 
 static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry 
*entry)
 {
+       struct nfs_server *server = NFS_SERVER(inode);
+       struct nfs_fattr fattr;
        struct nfs4_accessargs args = {
                .fh = NFS_FH(inode),
+               .bitmask = server->attr_bitmask,
+       };
+       struct nfs4_accessres res = {
+               .server = server,
+               .fattr = &fattr,
        };
-       struct nfs4_accessres res = { 0 };
        struct rpc_message msg = {
                .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_ACCESS],
                .rpc_argp = &args,
@@ -1755,6 +1760,7 @@ static int _nfs4_proc_access(struct inode *inode, struct 
nfs_access_entry *entry
                if (mode & MAY_EXEC)
                        args.access |= NFS4_ACCESS_EXECUTE;
        }
+       nfs_fattr_init(&fattr);
        status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
        if (!status) {
                entry->mask = 0;
@@ -1764,6 +1770,7 @@ static int _nfs4_proc_access(struct inode *inode, struct 
nfs_access_entry *entry
                        entry->mask |= MAY_WRITE;
                if (res.access & (NFS4_ACCESS_LOOKUP|NFS4_ACCESS_EXECUTE))
                        entry->mask |= MAY_EXEC;
+               nfs_refresh_inode(inode, &fattr);
        }
        return status;
 }
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 5f353d4..51dd380 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -376,10 +376,12 @@ static int nfs4_stat_to_errno(int);
                                decode_locku_maxsz)
 #define NFS4_enc_access_sz     (compound_encode_hdr_maxsz + \
                                encode_putfh_maxsz + \
-                               encode_access_maxsz)
+                               encode_access_maxsz + \
+                               encode_getattr_maxsz)
 #define NFS4_dec_access_sz     (compound_decode_hdr_maxsz + \
                                decode_putfh_maxsz + \
-                               decode_access_maxsz)
+                               decode_access_maxsz + \
+                               decode_getattr_maxsz)
 #define NFS4_enc_getattr_sz    (compound_encode_hdr_maxsz + \
                                encode_putfh_maxsz + \
                                encode_getattr_maxsz)
@@ -1375,14 +1377,20 @@ static int nfs4_xdr_enc_access(struct rpc_rqst *req, 
__be32 *p, const struct nfs
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr = {
-               .nops = 2,
+               .nops = 3,
        };
        int status;
 
        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
        encode_compound_hdr(&xdr, &hdr);
-       if ((status = encode_putfh(&xdr, args->fh)) == 0)
-               status = encode_access(&xdr, args->access);
+       status = encode_putfh(&xdr, args->fh);
+       if (status != 0)
+               goto out;
+       status = encode_access(&xdr, args->access);
+       if (status != 0)
+               goto out;
+       status = encode_getfattr(&xdr, args->bitmask);
+out:
        return status;
 }
 
@@ -3784,8 +3792,13 @@ static int nfs4_xdr_dec_access(struct rpc_rqst *rqstp, 
__be32 *p, struct nfs4_ac
        xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
        if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
                goto out;
-       if ((status = decode_putfh(&xdr)) == 0)
-               status = decode_access(&xdr, res);
+       status = decode_putfh(&xdr);
+       if (status != 0)
+               goto out;
+       status = decode_access(&xdr, res);
+       if (status != 0)
+               goto out;
+       decode_getfattr(&xdr, res->fattr, res->server);
 out:
        return status;
 }
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index cf74a4d..0303201 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -538,10 +538,13 @@ typedef u64 clientid4;
 
 struct nfs4_accessargs {
        const struct nfs_fh *           fh;
+       const u32 *                     bitmask;
        u32                             access;
 };
 
 struct nfs4_accessres {
+       const struct nfs_server *       server;
+       struct nfs_fattr *              fattr;
        u32                             supported;
        u32                             access;
 };
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to