fs/nfs/nfs4proc.c | 42 +++++++++++++++++--------------- fs/nfs/nfs4xdr.c | 63 ++++++++++++++++++++++++++++++++++++++++-------- include/linux/nfs4.h | 1 include/linux/nfs_xdr.h | 8 ++++-- 4 files changed, 83 insertions(+), 31 deletions(-) diff -u --recursive --new-file --show-c-function linux-2.6.5-18-decompoundify_getroot/fs/nfs/nfs4proc.c linux-2.6.5-19-decompoundify_remove/fs/nfs/nfs4proc.c --- linux-2.6.5-18-decompoundify_getroot/fs/nfs/nfs4proc.c 2004-03-24 00:48:01.000000000 -0500 +++ linux-2.6.5-19-decompoundify_remove/fs/nfs/nfs4proc.c 2004-03-24 00:48:10.000000000 -0500 @@ -340,8 +340,7 @@ nfs4_setup_remove(struct nfs4_compound * { struct nfs4_remove *remove = GET_OP(cp, remove); - remove->rm_namelen = name->len; - remove->rm_name = name->name; + remove->name = name; remove->rm_cinfo = cinfo; OPNUM(cp) = OP_REMOVE; @@ -443,6 +442,14 @@ process_cinfo(struct nfs4_change_info *i } } +static void update_changeattr(struct inode *inode, struct nfs4_change_info *cinfo) +{ + struct nfs_inode *nfsi = NFS_I(inode); + + if (cinfo->before == nfsi->change_attr && cinfo->atomic) + nfsi->change_attr = cinfo->after; +} + /* * OPEN_RECLAIM: * reclaim state on the server after a reboot. @@ -1218,26 +1225,23 @@ nfs4_proc_create(struct inode *dir, stru return inode; } -static int -nfs4_proc_remove(struct inode *dir, struct qstr *name) +static int nfs4_proc_remove(struct inode *dir, struct qstr *name) { - struct nfs4_compound compound; - struct nfs4_op ops[3]; - struct nfs4_change_info dir_cinfo; - struct nfs_fattr dir_attr; + struct nfs4_remove_arg args = { + .fh = NFS_FH(dir), + .name = name, + }; + struct nfs4_change_info res; + struct rpc_message msg = { + .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE], + .rpc_argp = &args, + .rpc_resp = &res, + }; int status; - dir_attr.valid = 0; - nfs4_setup_compound(&compound, ops, NFS_SERVER(dir), "remove"); - nfs4_setup_putfh(&compound, NFS_FH(dir)); - nfs4_setup_remove(&compound, name, &dir_cinfo); - nfs4_setup_getattr(&compound, &dir_attr); - status = nfs4_call_compound(&compound, NULL, 0); - - if (!status) { - process_cinfo(&dir_cinfo, &dir_attr); - nfs_refresh_inode(dir, &dir_attr); - } + status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); + if (status == 0) + update_changeattr(dir, &res); return nfs4_map_errors(status); } diff -u --recursive --new-file --show-c-function linux-2.6.5-18-decompoundify_getroot/fs/nfs/nfs4xdr.c linux-2.6.5-19-decompoundify_remove/fs/nfs/nfs4xdr.c --- linux-2.6.5-18-decompoundify_getroot/fs/nfs/nfs4xdr.c 2004-03-24 00:48:01.000000000 -0500 +++ linux-2.6.5-19-decompoundify_remove/fs/nfs/nfs4xdr.c 2004-03-24 00:48:10.000000000 -0500 @@ -111,6 +111,8 @@ static int nfs_stat_to_errno(int); (op_decode_hdr_maxsz) #define encode_lookup_maxsz (op_encode_hdr_maxsz + \ 1 + ((3 + NFS4_FHSIZE) >> 2)) +#define encode_remove_maxsz (op_encode_hdr_maxsz + \ + 1 + ((3 + NFS4_MAXNAMLEN) >> 2)) #define NFS4_enc_compound_sz (1024) /* XXX: large enough? */ #define NFS4_dec_compound_sz (1024) /* XXX: large enough? */ #define NFS4_enc_read_sz (compound_encode_hdr_maxsz + \ @@ -270,6 +272,12 @@ static int nfs_stat_to_errno(int); decode_putrootfh_maxsz + \ decode_getattr_maxsz + \ decode_getfh_maxsz) +#define NFS4_enc_remove_sz (compound_encode_hdr_maxsz + \ + encode_putfh_maxsz + \ + encode_remove_maxsz) +#define NFS4_dec_remove_sz (compound_decode_hdr_maxsz + \ + decode_putfh_maxsz + \ + op_decode_hdr_maxsz + 5) @@ -927,15 +935,14 @@ encode_readlink(struct xdr_stream *xdr, return 0; } -static int -encode_remove(struct xdr_stream *xdr, struct nfs4_remove *remove) +static int encode_remove(struct xdr_stream *xdr, const struct qstr *name) { uint32_t *p; - RESERVE_SPACE(8 + remove->rm_namelen); + RESERVE_SPACE(8 + name->len); WRITE32(OP_REMOVE); - WRITE32(remove->rm_namelen); - WRITEMEM(remove->rm_name, remove->rm_namelen); + WRITE32(name->len); + WRITEMEM(name->name, name->len); return 0; } @@ -1106,7 +1113,7 @@ encode_compound(struct xdr_stream *xdr, status = encode_readlink(xdr, &cp->ops[i].u.readlink, req); break; case OP_REMOVE: - status = encode_remove(xdr, &cp->ops[i].u.remove); + status = encode_remove(xdr, cp->ops[i].u.remove.name); break; case OP_RENAME: status = encode_rename(xdr, &cp->ops[i].u.rename); @@ -1209,6 +1216,24 @@ out: } /* + * Encode REMOVE request + */ +static int nfs4_xdr_enc_remove(struct rpc_rqst *req, uint32_t *p, const struct nfs4_remove_arg *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_remove(&xdr, args->name); + return status; +} + +/* * Encode GETATTR request */ static int nfs4_xdr_enc_getattr(struct rpc_rqst *req, uint32_t *p, const struct nfs4_getattr_arg *args) @@ -2767,15 +2792,14 @@ decode_restorefh(struct xdr_stream *xdr) return decode_op_hdr(xdr, OP_RESTOREFH); } -static int -decode_remove(struct xdr_stream *xdr, struct nfs4_remove *remove) +static int decode_remove(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) { int status; status = decode_op_hdr(xdr, OP_REMOVE); if (status) goto out; - status = decode_change_info(xdr, remove->rm_cinfo); + status = decode_change_info(xdr, cinfo); out: return status; } @@ -2942,7 +2966,7 @@ decode_compound(struct xdr_stream *xdr, status = decode_restorefh(xdr); break; case OP_REMOVE: - status = decode_remove(xdr, &op->u.remove); + status = decode_remove(xdr, op->u.remove.rm_cinfo); break; case OP_RENAME: status = decode_rename(xdr, &op->u.rename); @@ -3070,6 +3094,24 @@ out: } /* + * Decode REMOVE response + */ +static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_change_info *cinfo) +{ + 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_remove(&xdr, cinfo); +out: + return status; +} + +/* * Decode GETATTR response */ static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_getattr_res *res) @@ -3580,6 +3622,7 @@ struct rpc_procinfo nfs4_procedures[] = PROC(GETATTR, enc_getattr, dec_getattr), PROC(LOOKUP, enc_lookup, dec_lookup), PROC(LOOKUP_ROOT, enc_lookup_root, dec_lookup_root), + PROC(REMOVE, enc_remove, dec_remove), }; struct rpc_version nfs_version4 = { diff -u --recursive --new-file --show-c-function linux-2.6.5-18-decompoundify_getroot/include/linux/nfs4.h linux-2.6.5-19-decompoundify_remove/include/linux/nfs4.h --- linux-2.6.5-18-decompoundify_getroot/include/linux/nfs4.h 2004-03-24 00:48:01.000000000 -0500 +++ linux-2.6.5-19-decompoundify_remove/include/linux/nfs4.h 2004-03-24 00:48:10.000000000 -0500 @@ -307,6 +307,7 @@ enum { NFSPROC4_CLNT_GETATTR, NFSPROC4_CLNT_LOOKUP, NFSPROC4_CLNT_LOOKUP_ROOT, + NFSPROC4_CLNT_REMOVE, }; #endif diff -u --recursive --new-file --show-c-function linux-2.6.5-18-decompoundify_getroot/include/linux/nfs_xdr.h linux-2.6.5-19-decompoundify_remove/include/linux/nfs_xdr.h --- linux-2.6.5-18-decompoundify_getroot/include/linux/nfs_xdr.h 2004-03-24 00:48:01.000000000 -0500 +++ linux-2.6.5-19-decompoundify_remove/include/linux/nfs_xdr.h 2004-03-24 00:48:10.000000000 -0500 @@ -607,11 +607,15 @@ struct nfs4_readlink { }; struct nfs4_remove { - u32 rm_namelen; /* request */ - const char * rm_name; /* request */ + struct qstr * name; /* request */ struct nfs4_change_info * rm_cinfo; /* response */ }; +struct nfs4_remove_arg { + const struct nfs_fh * fh; + const struct qstr * name; +}; + struct nfs4_rename { u32 rn_oldnamelen; /* request */ const char * rn_oldname; /* request */