fs/nfs/nfs4proc.c | 100 ++++++++++++++++++++++++++---------------------- fs/nfs/nfs4xdr.c | 62 ++++++++++++++++++++++++----- include/linux/nfs4.h | 1 include/linux/nfs_xdr.h | 9 +--- 4 files changed, 111 insertions(+), 61 deletions(-) diff -u --recursive --new-file --show-c-function linux-2.6.5-17-decompoundify_lookup/fs/nfs/nfs4proc.c linux-2.6.5-18-decompoundify_getroot/fs/nfs/nfs4proc.c --- linux-2.6.5-17-decompoundify_lookup/fs/nfs/nfs4proc.c 2004-03-24 00:47:54.000000000 -0500 +++ linux-2.6.5-18-decompoundify_getroot/fs/nfs/nfs4proc.c 2004-03-24 00:48:01.000000000 -0500 @@ -54,7 +54,7 @@ #define GET_OP(cp,name) &cp->ops[cp->req_nops].u.name #define OPNUM(cp) cp->ops[cp->req_nops].opnum -static int nfs4_proc_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); +static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); static int nfs4_async_handle_error(struct rpc_task *, struct nfs_server *); extern u32 *nfs4_decode_dirent(u32 *p, struct nfs_entry *entry, int plus); extern struct rpc_procinfo nfs4_procedures[]; @@ -253,17 +253,6 @@ nfs4_setup_link(struct nfs4_compound *cp } static void -nfs4_setup_lookup(struct nfs4_compound *cp, struct qstr *q) -{ - struct nfs4_lookup *lookup = GET_OP(cp, lookup); - - lookup->lo_name = q; - - OPNUM(cp) = OP_LOOKUP; - cp->req_nops++; -} - -static void nfs4_setup_putfh(struct nfs4_compound *cp, struct nfs_fh *fhandle) { struct nfs4_putfh *putfh = GET_OP(cp, putfh); @@ -275,13 +264,6 @@ nfs4_setup_putfh(struct nfs4_compound *c } static void -nfs4_setup_putrootfh(struct nfs4_compound *cp) -{ - OPNUM(cp) = OP_PUTROOTFH; - cp->req_nops++; -} - -static void nfs4_setup_readdir(struct nfs4_compound *cp, u64 cookie, u32 *verifier, struct page **pages, unsigned int bufsize, struct dentry *dentry) { @@ -821,30 +803,60 @@ nfs4_open_revalidate(struct inode *dir, return 0; } -static int -nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, - struct nfs_fsinfo *info) +static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle, + struct nfs_fsinfo *info) +{ + struct nfs_fattr * fattr = info->fattr; + struct nfs4_lookup_root_arg args = { + .bitmask = nfs4_fattr_bitmap, + }; + struct nfs4_lookup_res res = { + .server = server, + .fattr = fattr, + .fh = fhandle, + }; + struct rpc_message msg = { + .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOOKUP_ROOT], + .rpc_argp = &args, + .rpc_resp = &res, + }; + fattr->valid = 0; + return rpc_call_sync(server->client, &msg, 0); +} + +static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, + struct nfs_fsinfo *info) { - struct nfs4_compound compound; - struct nfs4_op ops[4]; struct nfs_fattr * fattr = info->fattr; unsigned char * p; struct qstr q; - int status; + struct nfs4_lookup_arg args = { + .dir_fh = fhandle, + .name = &q, + .bitmask = nfs4_fattr_bitmap, + }; + struct nfs4_lookup_res res = { + .server = server, + .fattr = fattr, + .fh = fhandle, + }; + struct rpc_message msg = { + .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOOKUP], + .rpc_argp = &args, + .rpc_resp = &res, + }; + int status; /* * Now we do a separate LOOKUP for each component of the mount path. * The LOOKUPs are done separately so that we can conveniently * catch an ERR_WRONGSEC if it occurs along the way... */ - p = server->mnt_path; - fattr->valid = 0; - nfs4_setup_compound(&compound, ops, server, "getrootfh"); - nfs4_setup_putrootfh(&compound); - nfs4_setup_getattr(&compound, fattr); - nfs4_setup_getfh(&compound, fhandle); - if ((status = nfs4_call_compound(&compound, NULL, 0))) + status = nfs4_lookup_root(server, fhandle, info); + if (status) goto out; + + p = server->mnt_path; for (;;) { while (*p == '/') p++; @@ -856,12 +868,7 @@ nfs4_proc_get_root(struct nfs_server *se q.len = p - q.name; fattr->valid = 0; - nfs4_setup_compound(&compound, ops, server, "mount"); - nfs4_setup_putfh(&compound, fhandle); - nfs4_setup_lookup(&compound, &q); - nfs4_setup_getattr(&compound, fattr); - nfs4_setup_getfh(&compound, fhandle); - status = nfs4_call_compound(&compound, NULL, 0); + status = rpc_call_sync(server->client, &msg, 0); if (!status) continue; if (status == -ENOENT) { @@ -870,10 +877,10 @@ nfs4_proc_get_root(struct nfs_server *se } break; } + if (status == 0) + status = nfs4_do_fsinfo(server, fhandle, info); out: - if (status) - return nfs4_map_errors(status); - return nfs4_proc_fsinfo(server, fhandle, info); + return nfs4_map_errors(status); } static int nfs4_proc_getattr(struct inode *inode, struct nfs_fattr *fattr) @@ -1468,9 +1475,8 @@ nfs4_proc_statfs(struct nfs_server *serv return nfs4_map_errors(nfs4_call_compound(&compound, NULL, 0)); } -static int -nfs4_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, - struct nfs_fsinfo *fsinfo) +static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, + struct nfs_fsinfo *fsinfo) { struct rpc_message msg = { .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FSINFO], @@ -1481,6 +1487,12 @@ nfs4_proc_fsinfo(struct nfs_server *serv return nfs4_map_errors(rpc_call_sync(server->client, &msg, 0)); } +static int nfs4_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo) +{ + fsinfo->fattr->valid = 0; + return nfs4_map_errors(nfs4_do_fsinfo(server, fhandle, fsinfo)); +} + static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_pathconf *pathconf) diff -u --recursive --new-file --show-c-function linux-2.6.5-17-decompoundify_lookup/fs/nfs/nfs4xdr.c linux-2.6.5-18-decompoundify_getroot/fs/nfs/nfs4xdr.c --- linux-2.6.5-17-decompoundify_lookup/fs/nfs/nfs4xdr.c 2004-03-24 00:47:54.000000000 -0500 +++ linux-2.6.5-18-decompoundify_getroot/fs/nfs/nfs4xdr.c 2004-03-24 00:48:01.000000000 -0500 @@ -262,6 +262,14 @@ static int nfs_stat_to_errno(int); op_decode_hdr_maxsz + \ decode_getattr_maxsz + \ decode_getfh_maxsz) +#define NFS4_enc_lookup_root_sz (compound_encode_hdr_maxsz + \ + encode_putrootfh_maxsz + \ + encode_getattr_maxsz + \ + encode_getfh_maxsz) +#define NFS4_dec_lookup_root_sz (compound_decode_hdr_maxsz + \ + decode_putrootfh_maxsz + \ + decode_getattr_maxsz + \ + decode_getfh_maxsz) @@ -1088,15 +1096,9 @@ encode_compound(struct xdr_stream *xdr, case OP_LINK: status = encode_link(xdr, &cp->ops[i].u.link); break; - case OP_LOOKUP: - status = encode_lookup(xdr, cp->ops[i].u.lookup.lo_name); - break; case OP_PUTFH: status = encode_putfh(xdr, cp->ops[i].u.putfh.pf_fhandle); break; - case OP_PUTROOTFH: - status = encode_putrootfh(xdr); - break; case OP_READDIR: status = encode_readdir(xdr, &cp->ops[i].u.readdir, req); break; @@ -1186,6 +1188,27 @@ out: } /* + * Encode LOOKUP_ROOT request + */ +static int nfs4_xdr_enc_lookup_root(struct rpc_rqst *req, uint32_t *p, const struct nfs4_lookup_root_arg *args) +{ + struct xdr_stream xdr; + struct compound_hdr hdr = { + .nops = 3, + }; + int status; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_compound_hdr(&xdr, &hdr); + if ((status = encode_putrootfh(&xdr)) != 0) + goto out; + if ((status = encode_getfh(&xdr)) == 0) + status = encode_getfattr(&xdr, args->bitmask); +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) @@ -2906,15 +2929,9 @@ decode_compound(struct xdr_stream *xdr, case OP_LINK: status = decode_link(xdr, &op->u.link); break; - case OP_LOOKUP: - status = decode_lookup(xdr); - break; case OP_PUTFH: status = decode_putfh(xdr); break; - case OP_PUTROOTFH: - status = decode_putrootfh(xdr); - break; case OP_READDIR: status = decode_readdir(xdr, req, &op->u.readdir); break; @@ -3033,6 +3050,26 @@ out: } /* + * Decode LOOKUP_ROOT response + */ +static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_lookup_res *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_putrootfh(&xdr)) != 0) + goto out; + if ((status = decode_getfh(&xdr, res->fh)) == 0) + status = decode_getfattr(&xdr, res->fattr, res->server); +out: + return status; +} + +/* * Decode GETATTR response */ static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_getattr_res *res) @@ -3542,6 +3579,7 @@ struct rpc_procinfo nfs4_procedures[] = PROC(ACCESS, enc_access, dec_access), PROC(GETATTR, enc_getattr, dec_getattr), PROC(LOOKUP, enc_lookup, dec_lookup), + PROC(LOOKUP_ROOT, enc_lookup_root, dec_lookup_root), }; struct rpc_version nfs_version4 = { diff -u --recursive --new-file --show-c-function linux-2.6.5-17-decompoundify_lookup/include/linux/nfs4.h linux-2.6.5-18-decompoundify_getroot/include/linux/nfs4.h --- linux-2.6.5-17-decompoundify_lookup/include/linux/nfs4.h 2004-03-24 00:47:54.000000000 -0500 +++ linux-2.6.5-18-decompoundify_getroot/include/linux/nfs4.h 2004-03-24 00:48:01.000000000 -0500 @@ -306,6 +306,7 @@ enum { NFSPROC4_CLNT_ACCESS, NFSPROC4_CLNT_GETATTR, NFSPROC4_CLNT_LOOKUP, + NFSPROC4_CLNT_LOOKUP_ROOT, }; #endif diff -u --recursive --new-file --show-c-function linux-2.6.5-17-decompoundify_lookup/include/linux/nfs_xdr.h linux-2.6.5-18-decompoundify_getroot/include/linux/nfs_xdr.h --- linux-2.6.5-17-decompoundify_lookup/include/linux/nfs_xdr.h 2004-03-24 00:47:54.000000000 -0500 +++ linux-2.6.5-18-decompoundify_getroot/include/linux/nfs_xdr.h 2004-03-24 00:48:01.000000000 -0500 @@ -550,10 +550,6 @@ struct nfs4_link { struct nfs4_change_info * ln_cinfo; /* response */ }; -struct nfs4_lookup { - struct qstr * lo_name; /* request */ -}; - struct nfs4_lookup_arg { const struct nfs_fh * dir_fh; const struct qstr * name; @@ -566,6 +562,10 @@ struct nfs4_lookup_res { struct nfs_fh * fh; }; +struct nfs4_lookup_root_arg { + const u32 * bitmask; +}; + struct nfs4_open { struct nfs4_client * op_client_state; /* request */ u32 op_share_access; /* request */ @@ -644,7 +644,6 @@ struct nfs4_op { struct nfs4_getattr getattr; struct nfs4_getfh getfh; struct nfs4_link link; - struct nfs4_lookup lookup; struct nfs4_open open; struct nfs4_open_confirm open_confirm; struct nfs4_putfh putfh;