diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-08-10 17:45:11 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-10-09 17:18:38 -0400 |
commit | 76b32999dfff6e59252a8af17a5671a4cf3bcf9b (patch) | |
tree | 6494e3a368e120668052e469c08c69a5d8d0b3f4 | |
parent | af22f94ae02ab9dd4fd7fe628c8434a59cc293be (diff) |
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 <Trond.Myklebust@netapp.com>
-rw-r--r-- | fs/nfs/nfs4proc.c | 11 | ||||
-rw-r--r-- | fs/nfs/nfs4xdr.c | 27 | ||||
-rw-r--r-- | 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 5aa0dd1e1bdf..0e366a31f63b 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -62,7 +62,6 @@ struct nfs4_opendata; | |||
62 | static int _nfs4_proc_open(struct nfs4_opendata *data); | 62 | static int _nfs4_proc_open(struct nfs4_opendata *data); |
63 | static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); | 63 | static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); |
64 | static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *); | 64 | static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *); |
65 | static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry); | ||
66 | static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception); | 65 | static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception); |
67 | static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs_client *clp); | 66 | static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs_client *clp); |
68 | static int _nfs4_proc_lookup(struct inode *dir, const struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr); | 67 | 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 | |||
1726 | 1725 | ||
1727 | static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry) | 1726 | static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry) |
1728 | { | 1727 | { |
1728 | struct nfs_server *server = NFS_SERVER(inode); | ||
1729 | struct nfs_fattr fattr; | ||
1729 | struct nfs4_accessargs args = { | 1730 | struct nfs4_accessargs args = { |
1730 | .fh = NFS_FH(inode), | 1731 | .fh = NFS_FH(inode), |
1732 | .bitmask = server->attr_bitmask, | ||
1733 | }; | ||
1734 | struct nfs4_accessres res = { | ||
1735 | .server = server, | ||
1736 | .fattr = &fattr, | ||
1731 | }; | 1737 | }; |
1732 | struct nfs4_accessres res = { 0 }; | ||
1733 | struct rpc_message msg = { | 1738 | struct rpc_message msg = { |
1734 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_ACCESS], | 1739 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_ACCESS], |
1735 | .rpc_argp = &args, | 1740 | .rpc_argp = &args, |
@@ -1755,6 +1760,7 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry | |||
1755 | if (mode & MAY_EXEC) | 1760 | if (mode & MAY_EXEC) |
1756 | args.access |= NFS4_ACCESS_EXECUTE; | 1761 | args.access |= NFS4_ACCESS_EXECUTE; |
1757 | } | 1762 | } |
1763 | nfs_fattr_init(&fattr); | ||
1758 | status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); | 1764 | status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); |
1759 | if (!status) { | 1765 | if (!status) { |
1760 | entry->mask = 0; | 1766 | entry->mask = 0; |
@@ -1764,6 +1770,7 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry | |||
1764 | entry->mask |= MAY_WRITE; | 1770 | entry->mask |= MAY_WRITE; |
1765 | if (res.access & (NFS4_ACCESS_LOOKUP|NFS4_ACCESS_EXECUTE)) | 1771 | if (res.access & (NFS4_ACCESS_LOOKUP|NFS4_ACCESS_EXECUTE)) |
1766 | entry->mask |= MAY_EXEC; | 1772 | entry->mask |= MAY_EXEC; |
1773 | nfs_refresh_inode(inode, &fattr); | ||
1767 | } | 1774 | } |
1768 | return status; | 1775 | return status; |
1769 | } | 1776 | } |
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 5f353d4686b6..51dd3804866f 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -376,10 +376,12 @@ static int nfs4_stat_to_errno(int); | |||
376 | decode_locku_maxsz) | 376 | decode_locku_maxsz) |
377 | #define NFS4_enc_access_sz (compound_encode_hdr_maxsz + \ | 377 | #define NFS4_enc_access_sz (compound_encode_hdr_maxsz + \ |
378 | encode_putfh_maxsz + \ | 378 | encode_putfh_maxsz + \ |
379 | encode_access_maxsz) | 379 | encode_access_maxsz + \ |
380 | encode_getattr_maxsz) | ||
380 | #define NFS4_dec_access_sz (compound_decode_hdr_maxsz + \ | 381 | #define NFS4_dec_access_sz (compound_decode_hdr_maxsz + \ |
381 | decode_putfh_maxsz + \ | 382 | decode_putfh_maxsz + \ |
382 | decode_access_maxsz) | 383 | decode_access_maxsz + \ |
384 | decode_getattr_maxsz) | ||
383 | #define NFS4_enc_getattr_sz (compound_encode_hdr_maxsz + \ | 385 | #define NFS4_enc_getattr_sz (compound_encode_hdr_maxsz + \ |
384 | encode_putfh_maxsz + \ | 386 | encode_putfh_maxsz + \ |
385 | encode_getattr_maxsz) | 387 | encode_getattr_maxsz) |
@@ -1375,14 +1377,20 @@ static int nfs4_xdr_enc_access(struct rpc_rqst *req, __be32 *p, const struct nfs | |||
1375 | { | 1377 | { |
1376 | struct xdr_stream xdr; | 1378 | struct xdr_stream xdr; |
1377 | struct compound_hdr hdr = { | 1379 | struct compound_hdr hdr = { |
1378 | .nops = 2, | 1380 | .nops = 3, |
1379 | }; | 1381 | }; |
1380 | int status; | 1382 | int status; |
1381 | 1383 | ||
1382 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); | 1384 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); |
1383 | encode_compound_hdr(&xdr, &hdr); | 1385 | encode_compound_hdr(&xdr, &hdr); |
1384 | if ((status = encode_putfh(&xdr, args->fh)) == 0) | 1386 | status = encode_putfh(&xdr, args->fh); |
1385 | status = encode_access(&xdr, args->access); | 1387 | if (status != 0) |
1388 | goto out; | ||
1389 | status = encode_access(&xdr, args->access); | ||
1390 | if (status != 0) | ||
1391 | goto out; | ||
1392 | status = encode_getfattr(&xdr, args->bitmask); | ||
1393 | out: | ||
1386 | return status; | 1394 | return status; |
1387 | } | 1395 | } |
1388 | 1396 | ||
@@ -3784,8 +3792,13 @@ static int nfs4_xdr_dec_access(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_ac | |||
3784 | xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); | 3792 | xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); |
3785 | if ((status = decode_compound_hdr(&xdr, &hdr)) != 0) | 3793 | if ((status = decode_compound_hdr(&xdr, &hdr)) != 0) |
3786 | goto out; | 3794 | goto out; |
3787 | if ((status = decode_putfh(&xdr)) == 0) | 3795 | status = decode_putfh(&xdr); |
3788 | status = decode_access(&xdr, res); | 3796 | if (status != 0) |
3797 | goto out; | ||
3798 | status = decode_access(&xdr, res); | ||
3799 | if (status != 0) | ||
3800 | goto out; | ||
3801 | decode_getfattr(&xdr, res->fattr, res->server); | ||
3789 | out: | 3802 | out: |
3790 | return status; | 3803 | return status; |
3791 | } | 3804 | } |
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index cf74a4db84a5..03032017ffaa 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h | |||
@@ -538,10 +538,13 @@ typedef u64 clientid4; | |||
538 | 538 | ||
539 | struct nfs4_accessargs { | 539 | struct nfs4_accessargs { |
540 | const struct nfs_fh * fh; | 540 | const struct nfs_fh * fh; |
541 | const u32 * bitmask; | ||
541 | u32 access; | 542 | u32 access; |
542 | }; | 543 | }; |
543 | 544 | ||
544 | struct nfs4_accessres { | 545 | struct nfs4_accessres { |
546 | const struct nfs_server * server; | ||
547 | struct nfs_fattr * fattr; | ||
545 | u32 supported; | 548 | u32 supported; |
546 | u32 access; | 549 | u32 access; |
547 | }; | 550 | }; |