aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4xdr.c
diff options
context:
space:
mode:
authorWeston Andros Adamson <dros@netapp.com>2012-09-10 14:00:46 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-10-01 18:20:11 -0400
commit6168f62cbde8dcf4f58255794efbcdb8df603959 (patch)
tree897bac0b7539172aa171365337d964f7984b1a80 /fs/nfs/nfs4xdr.c
parent57a51048da742c764b6ce5d028c7f334ae04d363 (diff)
NFSv4: Add ACCESS operation to OPEN compound
The OPEN operation has no way to differentiate an open for read and an open for execution - both look like read to the server. This allowed users to read files that didn't have READ access but did have EXEC access, which is obviously wrong. This patch adds an ACCESS call to the OPEN compound to handle the difference between OPENs for reading and execution. Since we're going through the trouble of calling ACCESS, we check all possible access bits and cache the results hopefully avoiding an ACCESS call in the future. Signed-off-by: Weston Andros Adamson <dros@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
-rw-r--r--fs/nfs/nfs4xdr.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 7ab29abb3160..657483c34e28 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -447,12 +447,14 @@ static int nfs4_stat_to_errno(int);
447 encode_sequence_maxsz + \ 447 encode_sequence_maxsz + \
448 encode_putfh_maxsz + \ 448 encode_putfh_maxsz + \
449 encode_open_maxsz + \ 449 encode_open_maxsz + \
450 encode_access_maxsz + \
450 encode_getfh_maxsz + \ 451 encode_getfh_maxsz + \
451 encode_getattr_maxsz) 452 encode_getattr_maxsz)
452#define NFS4_dec_open_sz (compound_decode_hdr_maxsz + \ 453#define NFS4_dec_open_sz (compound_decode_hdr_maxsz + \
453 decode_sequence_maxsz + \ 454 decode_sequence_maxsz + \
454 decode_putfh_maxsz + \ 455 decode_putfh_maxsz + \
455 decode_open_maxsz + \ 456 decode_open_maxsz + \
457 decode_access_maxsz + \
456 decode_getfh_maxsz + \ 458 decode_getfh_maxsz + \
457 decode_getattr_maxsz) 459 decode_getattr_maxsz)
458#define NFS4_enc_open_confirm_sz \ 460#define NFS4_enc_open_confirm_sz \
@@ -467,11 +469,13 @@ static int nfs4_stat_to_errno(int);
467 encode_sequence_maxsz + \ 469 encode_sequence_maxsz + \
468 encode_putfh_maxsz + \ 470 encode_putfh_maxsz + \
469 encode_open_maxsz + \ 471 encode_open_maxsz + \
472 encode_access_maxsz + \
470 encode_getattr_maxsz) 473 encode_getattr_maxsz)
471#define NFS4_dec_open_noattr_sz (compound_decode_hdr_maxsz + \ 474#define NFS4_dec_open_noattr_sz (compound_decode_hdr_maxsz + \
472 decode_sequence_maxsz + \ 475 decode_sequence_maxsz + \
473 decode_putfh_maxsz + \ 476 decode_putfh_maxsz + \
474 decode_open_maxsz + \ 477 decode_open_maxsz + \
478 decode_access_maxsz + \
475 decode_getattr_maxsz) 479 decode_getattr_maxsz)
476#define NFS4_enc_open_downgrade_sz \ 480#define NFS4_enc_open_downgrade_sz \
477 (compound_encode_hdr_maxsz + \ 481 (compound_encode_hdr_maxsz + \
@@ -2220,6 +2224,7 @@ static void nfs4_xdr_enc_open(struct rpc_rqst *req, struct xdr_stream *xdr,
2220 encode_putfh(xdr, args->fh, &hdr); 2224 encode_putfh(xdr, args->fh, &hdr);
2221 encode_open(xdr, args, &hdr); 2225 encode_open(xdr, args, &hdr);
2222 encode_getfh(xdr, &hdr); 2226 encode_getfh(xdr, &hdr);
2227 encode_access(xdr, args->access, &hdr);
2223 encode_getfattr_open(xdr, args->bitmask, args->open_bitmap, &hdr); 2228 encode_getfattr_open(xdr, args->bitmask, args->open_bitmap, &hdr);
2224 encode_nops(&hdr); 2229 encode_nops(&hdr);
2225} 2230}
@@ -2256,6 +2261,7 @@ static void nfs4_xdr_enc_open_noattr(struct rpc_rqst *req,
2256 encode_sequence(xdr, &args->seq_args, &hdr); 2261 encode_sequence(xdr, &args->seq_args, &hdr);
2257 encode_putfh(xdr, args->fh, &hdr); 2262 encode_putfh(xdr, args->fh, &hdr);
2258 encode_open(xdr, args, &hdr); 2263 encode_open(xdr, args, &hdr);
2264 encode_access(xdr, args->access, &hdr);
2259 encode_getfattr(xdr, args->bitmask, &hdr); 2265 encode_getfattr(xdr, args->bitmask, &hdr);
2260 encode_nops(&hdr); 2266 encode_nops(&hdr);
2261} 2267}
@@ -4099,7 +4105,7 @@ out_overflow:
4099 return -EIO; 4105 return -EIO;
4100} 4106}
4101 4107
4102static int decode_access(struct xdr_stream *xdr, struct nfs4_accessres *access) 4108static int decode_access(struct xdr_stream *xdr, u32 *supported, u32 *access)
4103{ 4109{
4104 __be32 *p; 4110 __be32 *p;
4105 uint32_t supp, acc; 4111 uint32_t supp, acc;
@@ -4113,8 +4119,8 @@ static int decode_access(struct xdr_stream *xdr, struct nfs4_accessres *access)
4113 goto out_overflow; 4119 goto out_overflow;
4114 supp = be32_to_cpup(p++); 4120 supp = be32_to_cpup(p++);
4115 acc = be32_to_cpup(p); 4121 acc = be32_to_cpup(p);
4116 access->supported = supp; 4122 *supported = supp;
4117 access->access = acc; 4123 *access = acc;
4118 return 0; 4124 return 0;
4119out_overflow: 4125out_overflow:
4120 print_overflow_msg(__func__, xdr); 4126 print_overflow_msg(__func__, xdr);
@@ -5892,7 +5898,7 @@ static int nfs4_xdr_dec_access(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
5892 status = decode_putfh(xdr); 5898 status = decode_putfh(xdr);
5893 if (status != 0) 5899 if (status != 0)
5894 goto out; 5900 goto out;
5895 status = decode_access(xdr, res); 5901 status = decode_access(xdr, &res->supported, &res->access);
5896 if (status != 0) 5902 if (status != 0)
5897 goto out; 5903 goto out;
5898 decode_getfattr(xdr, res->fattr, res->server); 5904 decode_getfattr(xdr, res->fattr, res->server);
@@ -6233,6 +6239,7 @@ static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
6233 status = decode_getfh(xdr, &res->fh); 6239 status = decode_getfh(xdr, &res->fh);
6234 if (status) 6240 if (status)
6235 goto out; 6241 goto out;
6242 decode_access(xdr, &res->access_supported, &res->access_result);
6236 decode_getfattr(xdr, res->f_attr, res->server); 6243 decode_getfattr(xdr, res->f_attr, res->server);
6237out: 6244out:
6238 return status; 6245 return status;
@@ -6281,6 +6288,7 @@ static int nfs4_xdr_dec_open_noattr(struct rpc_rqst *rqstp,
6281 status = decode_open(xdr, res); 6288 status = decode_open(xdr, res);
6282 if (status) 6289 if (status)
6283 goto out; 6290 goto out;
6291 decode_access(xdr, &res->access_supported, &res->access_result);
6284 decode_getfattr(xdr, res->f_attr, res->server); 6292 decode_getfattr(xdr, res->f_attr, res->server);
6285out: 6293out:
6286 return status; 6294 return status;