fs/nfs/nfs4proc.c | 56 ++++++++++++------------------------ fs/nfs/nfs4xdr.c | 74 +++++++++++++++++++++++++++++++++--------------- include/linux/nfs4.h | 1 include/linux/nfs_xdr.h | 13 +++++--- 4 files changed, 80 insertions(+), 64 deletions(-) diff -u --recursive --new-file --show-c-function linux-2.6.5-13-fix_bitmap/fs/nfs/nfs4proc.c linux-2.6.5-14-decompoundify_access/fs/nfs/nfs4proc.c --- linux-2.6.5-13-fix_bitmap/fs/nfs/nfs4proc.c 2004-03-24 00:46:06.000000000 -0500 +++ linux-2.6.5-14-decompoundify_access/fs/nfs/nfs4proc.c 2004-03-24 00:47:11.000000000 -0500 @@ -82,19 +82,6 @@ nfs4_setup_compound(struct nfs4_compound } static void -nfs4_setup_access(struct nfs4_compound *cp, u32 req_access, u32 *resp_supported, u32 *resp_access) -{ - struct nfs4_access *access = GET_OP(cp, access); - - access->ac_req_access = req_access; - access->ac_resp_supported = resp_supported; - access->ac_resp_access = resp_access; - - OPNUM(cp) = OP_ACCESS; - cp->req_nops++; -} - -static void nfs4_setup_create_dir(struct nfs4_compound *cp, struct qstr *name, struct iattr *sattr, struct nfs4_change_info *info) { @@ -989,48 +976,43 @@ nfs4_proc_lookup(struct inode *dir, stru return nfs4_map_errors(status); } -static int -nfs4_proc_access(struct inode *inode, struct rpc_cred *cred, int mode) +static int nfs4_proc_access(struct inode *inode, struct rpc_cred *cred, int mode) { - struct nfs4_compound compound; - struct nfs4_op ops[3]; - struct nfs_fattr fattr; - u32 req_access = 0, resp_supported, resp_access; int status; - - fattr.valid = 0; + struct nfs4_accessargs args = { + .fh = NFS_FH(inode), + }; + struct nfs4_accessres res = { 0 }; + struct rpc_message msg = { + .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_ACCESS], + .rpc_argp = &args, + .rpc_resp = &res, + .rpc_cred = cred, + }; /* * Determine which access bits we want to ask for... */ if (mode & MAY_READ) - req_access |= NFS4_ACCESS_READ; + args.access |= NFS4_ACCESS_READ; if (S_ISDIR(inode->i_mode)) { if (mode & MAY_WRITE) - req_access |= NFS4_ACCESS_MODIFY | NFS4_ACCESS_EXTEND | NFS4_ACCESS_DELETE; + args.access |= NFS4_ACCESS_MODIFY | NFS4_ACCESS_EXTEND | NFS4_ACCESS_DELETE; if (mode & MAY_EXEC) - req_access |= NFS4_ACCESS_LOOKUP; + args.access |= NFS4_ACCESS_LOOKUP; } else { if (mode & MAY_WRITE) - req_access |= NFS4_ACCESS_MODIFY | NFS4_ACCESS_EXTEND; + args.access |= NFS4_ACCESS_MODIFY | NFS4_ACCESS_EXTEND; if (mode & MAY_EXEC) - req_access |= NFS4_ACCESS_EXECUTE; + args.access |= NFS4_ACCESS_EXECUTE; } - - nfs4_setup_compound(&compound, ops, NFS_SERVER(inode), "access"); - nfs4_setup_putfh(&compound, NFS_FH(inode)); - nfs4_setup_getattr(&compound, &fattr); - nfs4_setup_access(&compound, req_access, &resp_supported, &resp_access); - status = nfs4_call_compound(&compound, cred, 0); - nfs_refresh_inode(inode, &fattr); - + status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); if (!status) { - if (req_access != resp_supported) { + if (args.access != res.supported) { printk(KERN_NOTICE "NFS: server didn't support all access bits!\n"); status = -ENOTSUPP; - } - else if (req_access != resp_access) + } else if ((args.access & res.access) != args.access) status = -EACCES; } return nfs4_map_errors(status); diff -u --recursive --new-file --show-c-function linux-2.6.5-13-fix_bitmap/fs/nfs/nfs4xdr.c linux-2.6.5-14-decompoundify_access/fs/nfs/nfs4xdr.c --- linux-2.6.5-13-fix_bitmap/fs/nfs/nfs4xdr.c 2004-03-24 00:47:00.000000000 -0500 +++ linux-2.6.5-14-decompoundify_access/fs/nfs/nfs4xdr.c 2004-03-24 00:47:11.000000000 -0500 @@ -255,7 +255,13 @@ static int nfs_stat_to_errno(int); decode_putfh_maxsz + \ decode_getattr_maxsz + \ op_decode_hdr_maxsz + 4) - +#define NFS4_enc_access_sz (compound_encode_hdr_maxsz + \ + encode_putfh_maxsz + \ + op_encode_hdr_maxsz + 1) +#define NFS4_dec_access_sz (compound_decode_hdr_maxsz + \ + decode_putfh_maxsz + \ + op_decode_hdr_maxsz + 2) + static struct { @@ -450,14 +456,13 @@ encode_attrs(struct xdr_stream *xdr, str return status; } -static int -encode_access(struct xdr_stream *xdr, struct nfs4_access *access) +static int encode_access(struct xdr_stream *xdr, u32 access) { uint32_t *p; RESERVE_SPACE(8); WRITE32(OP_ACCESS); - WRITE32(access->ac_req_access); + WRITE32(access); return 0; } @@ -832,8 +837,7 @@ encode_open_downgrade(struct xdr_stream return 0; } -static int -encode_putfh(struct xdr_stream *xdr, struct nfs_fh *fh) +static int encode_putfh(struct xdr_stream *xdr, const struct nfs_fh *fh) { int len = fh->size; uint32_t *p; @@ -1094,9 +1098,6 @@ encode_compound(struct xdr_stream *xdr, for (i = 0; i < cp->req_nops; i++) { switch (cp->ops[i].opnum) { - case OP_ACCESS: - status = encode_access(xdr, &cp->ops[i].u.access); - break; case OP_CREATE: status = encode_create(xdr, &cp->ops[i].u.create, cp->server); break; @@ -1149,7 +1150,6 @@ encode_compound(struct xdr_stream *xdr, * END OF "GENERIC" ENCODE ROUTINES. */ - /* * Encode COMPOUND argument */ @@ -1164,6 +1164,26 @@ nfs4_xdr_enc_compound(struct rpc_rqst *r cp->timestamp = jiffies; return status; } + +/* + * Encode an ACCESS request + */ +static int nfs4_xdr_enc_access(struct rpc_rqst *req, uint32_t *p, const struct nfs4_accessargs *args) +{ + struct xdr_stream xdr; + struct compound_hdr hdr = { + .nops = 2, + }; + 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); + return status; +} + + /* * Encode a CLOSE request */ @@ -1645,8 +1665,7 @@ decode_change_info(struct xdr_stream *xd return 0; } -static int -decode_access(struct xdr_stream *xdr, struct nfs4_access *access) +static int decode_access(struct xdr_stream *xdr, struct nfs4_accessres *access) { uint32_t *p; uint32_t supp, acc; @@ -1658,12 +1677,8 @@ decode_access(struct xdr_stream *xdr, st READ_BUF(8); READ32(supp); READ32(acc); - if ((supp & ~access->ac_req_access) || (acc & ~supp)) { - printk(KERN_NOTICE "NFS: server returned bad bits in access call!\n"); - return -EIO; - } - *access->ac_resp_supported = supp; - *access->ac_resp_access = acc; + access->supported = supp; + access->access = acc; return 0; } @@ -2077,7 +2092,6 @@ out_bad_bitmap: return -EIO; } - static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo) { @@ -2628,9 +2642,6 @@ decode_compound(struct xdr_stream *xdr, op = &cp->ops[0]; for (cp->nops = 0; cp->nops < cp->resp_nops; cp->nops++, op++) { switch (op->opnum) { - case OP_ACCESS: - status = decode_access(xdr, &op->u.access); - break; case OP_CREATE: status = decode_create(xdr, &op->u.create); break; @@ -2729,6 +2740,24 @@ out: } /* + * Decode ACCESS response + */ +static int nfs4_xdr_dec_access(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_accessres *res) +{ + struct xdr_stream xdr; + struct compound_hdr hdr; + int status; + + 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); +out: + return status; +} + +/* * Decode CLOSE response */ static int @@ -3236,6 +3265,7 @@ struct rpc_procinfo nfs4_procedures[] = PROC(LOCK, enc_lock, dec_lock), PROC(LOCKT, enc_lockt, dec_lockt), PROC(LOCKU, enc_locku, dec_locku), + PROC(ACCESS, enc_access, dec_access), }; struct rpc_version nfs_version4 = { diff -u --recursive --new-file --show-c-function linux-2.6.5-13-fix_bitmap/include/linux/nfs4.h linux-2.6.5-14-decompoundify_access/include/linux/nfs4.h --- linux-2.6.5-13-fix_bitmap/include/linux/nfs4.h 2004-03-24 00:47:05.000000000 -0500 +++ linux-2.6.5-14-decompoundify_access/include/linux/nfs4.h 2004-03-24 00:47:11.000000000 -0500 @@ -303,6 +303,7 @@ enum { NFSPROC4_CLNT_LOCK, NFSPROC4_CLNT_LOCKT, NFSPROC4_CLNT_LOCKU, + NFSPROC4_CLNT_ACCESS, }; #endif diff -u --recursive --new-file --show-c-function linux-2.6.5-13-fix_bitmap/include/linux/nfs_xdr.h linux-2.6.5-14-decompoundify_access/include/linux/nfs_xdr.h --- linux-2.6.5-13-fix_bitmap/include/linux/nfs_xdr.h 2004-03-24 00:46:06.000000000 -0500 +++ linux-2.6.5-14-decompoundify_access/include/linux/nfs_xdr.h 2004-03-24 00:47:11.000000000 -0500 @@ -484,10 +484,14 @@ struct nfs4_change_info { u64 after; }; -struct nfs4_access { - u32 ac_req_access; /* request */ - u32 * ac_resp_supported; /* response */ - u32 * ac_resp_access; /* response */ +struct nfs4_accessargs { + const struct nfs_fh * fh; + u32 access; +}; + +struct nfs4_accessres { + u32 supported; + u32 access; }; struct nfs4_close { @@ -611,7 +615,6 @@ struct nfs4_setclientid { struct nfs4_op { u32 opnum; union { - struct nfs4_access access; struct nfs4_close close; struct nfs4_create create; struct nfs4_getattr getattr;