fs/nfs/nfs4proc.c | 54 +++++++++----------------------- fs/nfs/nfs4xdr.c | 81 +++++++++++++++++++++++++++++++++++++++--------- include/linux/nfs4.h | 1 include/linux/nfs_xdr.h | 9 ++--- 4 files changed, 88 insertions(+), 57 deletions(-) diff -u --recursive --new-file --show-c-function linux-2.6.5-20-decompoundify_rename/fs/nfs/nfs4proc.c linux-2.6.5-21-decompoundify_link/fs/nfs/nfs4proc.c --- linux-2.6.5-20-decompoundify_rename/fs/nfs/nfs4proc.c 2004-03-24 00:48:16.000000000 -0500 +++ linux-2.6.5-21-decompoundify_link/fs/nfs/nfs4proc.c 2004-03-24 00:48:24.000000000 -0500 @@ -239,20 +239,6 @@ nfs4_setup_getfh(struct nfs4_compound *c } static void -nfs4_setup_link(struct nfs4_compound *cp, struct qstr *name, - struct nfs4_change_info *info) -{ - struct nfs4_link *link = GET_OP(cp, link); - - link->ln_namelen = name->len; - link->ln_name = name->name; - link->ln_cinfo = info; - - OPNUM(cp) = OP_LINK; - cp->req_nops++; -} - -static void nfs4_setup_putfh(struct nfs4_compound *cp, struct nfs_fh *fhandle) { struct nfs4_putfh *putfh = GET_OP(cp, putfh); @@ -1300,33 +1286,25 @@ static int nfs4_proc_rename(struct inode return nfs4_map_errors(status); } -static int -nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name) +static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name) { - struct nfs4_compound compound; - struct nfs4_op ops[7]; - struct nfs4_change_info dir_cinfo; - struct nfs_fattr dir_attr, fattr; + struct nfs4_link_arg arg = { + .fh = NFS_FH(inode), + .dir_fh = NFS_FH(dir), + .name = name, + }; + struct nfs4_change_info cinfo = { }; + struct rpc_message msg = { + .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LINK], + .rpc_argp = &arg, + .rpc_resp = &cinfo, + }; int status; - - dir_attr.valid = 0; - fattr.valid = 0; - - nfs4_setup_compound(&compound, ops, NFS_SERVER(inode), "link"); - nfs4_setup_putfh(&compound, NFS_FH(inode)); - nfs4_setup_savefh(&compound); - nfs4_setup_putfh(&compound, NFS_FH(dir)); - nfs4_setup_link(&compound, name, &dir_cinfo); - nfs4_setup_getattr(&compound, &dir_attr); - nfs4_setup_restorefh(&compound); - nfs4_setup_getattr(&compound, &fattr); - status = nfs4_call_compound(&compound, NULL, 0); - if (!status) { - process_cinfo(&dir_cinfo, &dir_attr); - nfs_refresh_inode(dir, &dir_attr); - nfs_refresh_inode(inode, &fattr); - } + status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); + if (!status) + update_changeattr(dir, &cinfo); + return nfs4_map_errors(status); } diff -u --recursive --new-file --show-c-function linux-2.6.5-20-decompoundify_rename/fs/nfs/nfs4xdr.c linux-2.6.5-21-decompoundify_link/fs/nfs/nfs4xdr.c --- linux-2.6.5-20-decompoundify_rename/fs/nfs/nfs4xdr.c 2004-03-24 00:48:16.000000000 -0500 +++ linux-2.6.5-21-decompoundify_link/fs/nfs/nfs4xdr.c 2004-03-24 00:48:24.000000000 -0500 @@ -116,6 +116,9 @@ static int nfs_stat_to_errno(int); #define encode_rename_maxsz (op_encode_hdr_maxsz + \ 2 * (1 + ((3 + NFS4_MAXNAMLEN) >> 2))) #define decode_rename_maxsz (op_decode_hdr_maxsz + 5 + 5) +#define encode_link_maxsz (op_encode_hdr_maxsz + \ + 1 + ((3 + NFS4_MAXNAMLEN) >> 2)) +#define decode_link_maxsz (op_decode_hdr_maxsz + 5) #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 + \ @@ -291,6 +294,16 @@ static int nfs_stat_to_errno(int); decode_savefh_maxsz + \ decode_putfh_maxsz + \ decode_rename_maxsz) +#define NFS4_enc_link_sz (compound_encode_hdr_maxsz + \ + encode_putfh_maxsz + \ + encode_savefh_maxsz + \ + encode_putfh_maxsz + \ + encode_link_maxsz) +#define NFS4_dec_link_sz (compound_decode_hdr_maxsz + \ + decode_putfh_maxsz + \ + decode_savefh_maxsz + \ + decode_putfh_maxsz + \ + decode_link_maxsz) @@ -618,15 +631,14 @@ encode_getfh(struct xdr_stream *xdr) return 0; } -static int -encode_link(struct xdr_stream *xdr, struct nfs4_link *link) +static int encode_link(struct xdr_stream *xdr, const struct qstr *name) { uint32_t *p; - RESERVE_SPACE(8 + link->ln_namelen); + RESERVE_SPACE(8 + name->len); WRITE32(OP_LINK); - WRITE32(link->ln_namelen); - WRITEMEM(link->ln_name, link->ln_namelen); + WRITE32(name->len); + WRITEMEM(name->name, name->len); return 0; } @@ -1112,9 +1124,6 @@ encode_compound(struct xdr_stream *xdr, case OP_GETFH: status = encode_getfh(xdr); break; - case OP_LINK: - status = encode_link(xdr, &cp->ops[i].u.link); - break; case OP_PUTFH: status = encode_putfh(xdr, cp->ops[i].u.putfh.pf_fhandle); break; @@ -1267,6 +1276,30 @@ out: } /* + * Encode LINK request + */ +static int nfs4_xdr_enc_link(struct rpc_rqst *req, uint32_t *p, const struct nfs4_link_arg *args) +{ + struct xdr_stream xdr; + struct compound_hdr hdr = { + .nops = 4, + }; + int status; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_compound_hdr(&xdr, &hdr); + if ((status = encode_putfh(&xdr, args->fh)) != 0) + goto out; + if ((status = encode_savefh(&xdr)) != 0) + goto out; + if ((status = encode_putfh(&xdr, args->dir_fh)) != 0) + goto out; + status = encode_link(&xdr, args->name); +out: + return status; +} + +/* * Encode GETATTR request */ static int nfs4_xdr_enc_getattr(struct rpc_rqst *req, uint32_t *p, const struct nfs4_getattr_arg *args) @@ -2516,15 +2549,14 @@ static int decode_getfh(struct xdr_strea return 0; } -static int -decode_link(struct xdr_stream *xdr, struct nfs4_link *link) +static int decode_link(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) { int status; status = decode_op_hdr(xdr, OP_LINK); if (status) return status; - return decode_change_info(xdr, link->ln_cinfo); + return decode_change_info(xdr, cinfo); } /* @@ -2981,9 +3013,6 @@ decode_compound(struct xdr_stream *xdr, case OP_GETFH: status = decode_getfh(xdr, op->u.getfh.gf_fhandle); break; - case OP_LINK: - status = decode_link(xdr, &op->u.link); - break; case OP_PUTFH: status = decode_putfh(xdr); break; @@ -3163,6 +3192,29 @@ out: } /* + * Decode LINK response + */ +static int nfs4_xdr_dec_link(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) + goto out; + if ((status = decode_savefh(&xdr)) != 0) + goto out; + if ((status = decode_putfh(&xdr)) != 0) + goto out; + status = decode_link(&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) @@ -3675,6 +3727,7 @@ struct rpc_procinfo nfs4_procedures[] = PROC(LOOKUP_ROOT, enc_lookup_root, dec_lookup_root), PROC(REMOVE, enc_remove, dec_remove), PROC(RENAME, enc_rename, dec_rename), + PROC(LINK, enc_link, dec_link), }; struct rpc_version nfs_version4 = { diff -u --recursive --new-file --show-c-function linux-2.6.5-20-decompoundify_rename/include/linux/nfs4.h linux-2.6.5-21-decompoundify_link/include/linux/nfs4.h --- linux-2.6.5-20-decompoundify_rename/include/linux/nfs4.h 2004-03-24 00:48:16.000000000 -0500 +++ linux-2.6.5-21-decompoundify_link/include/linux/nfs4.h 2004-03-24 00:48:24.000000000 -0500 @@ -309,6 +309,7 @@ enum { NFSPROC4_CLNT_LOOKUP_ROOT, NFSPROC4_CLNT_REMOVE, NFSPROC4_CLNT_RENAME, + NFSPROC4_CLNT_LINK, }; #endif diff -u --recursive --new-file --show-c-function linux-2.6.5-20-decompoundify_rename/include/linux/nfs_xdr.h linux-2.6.5-21-decompoundify_link/include/linux/nfs_xdr.h --- linux-2.6.5-20-decompoundify_rename/include/linux/nfs_xdr.h 2004-03-24 00:48:16.000000000 -0500 +++ linux-2.6.5-21-decompoundify_link/include/linux/nfs_xdr.h 2004-03-24 00:48:24.000000000 -0500 @@ -544,10 +544,10 @@ struct nfs4_getfh { struct nfs_fh * gf_fhandle; /* response */ }; -struct nfs4_link { - u32 ln_namelen; /* request */ - const char * ln_name; /* request */ - struct nfs4_change_info * ln_cinfo; /* response */ +struct nfs4_link_arg { + const struct nfs_fh * fh; + const struct nfs_fh * dir_fh; + const struct qstr * name; }; struct nfs4_lookup_arg { @@ -650,7 +650,6 @@ struct nfs4_op { struct nfs4_create create; struct nfs4_getattr getattr; struct nfs4_getfh getfh; - struct nfs4_link link; struct nfs4_open open; struct nfs4_open_confirm open_confirm; struct nfs4_putfh putfh;