Commit fba5d3c4 authored by Trond Myklebust's avatar Trond Myklebust

NFSv4: use the (more efficient) NFSv2/v3-like XDR scheme for looking up the

mountpoint.
parent efec5fa4
...@@ -54,7 +54,7 @@ ...@@ -54,7 +54,7 @@
#define GET_OP(cp,name) &cp->ops[cp->req_nops].u.name #define GET_OP(cp,name) &cp->ops[cp->req_nops].u.name
#define OPNUM(cp) cp->ops[cp->req_nops].opnum #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 *); 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 u32 *nfs4_decode_dirent(u32 *p, struct nfs_entry *entry, int plus);
extern struct rpc_procinfo nfs4_procedures[]; extern struct rpc_procinfo nfs4_procedures[];
...@@ -252,17 +252,6 @@ nfs4_setup_link(struct nfs4_compound *cp, struct qstr *name, ...@@ -252,17 +252,6 @@ nfs4_setup_link(struct nfs4_compound *cp, struct qstr *name,
cp->req_nops++; cp->req_nops++;
} }
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 static void
nfs4_setup_putfh(struct nfs4_compound *cp, struct nfs_fh *fhandle) nfs4_setup_putfh(struct nfs4_compound *cp, struct nfs_fh *fhandle)
{ {
...@@ -274,13 +263,6 @@ nfs4_setup_putfh(struct nfs4_compound *cp, struct nfs_fh *fhandle) ...@@ -274,13 +263,6 @@ nfs4_setup_putfh(struct nfs4_compound *cp, struct nfs_fh *fhandle)
cp->req_nops++; cp->req_nops++;
} }
static void
nfs4_setup_putrootfh(struct nfs4_compound *cp)
{
OPNUM(cp) = OP_PUTROOTFH;
cp->req_nops++;
}
static void static void
nfs4_setup_readdir(struct nfs4_compound *cp, u64 cookie, u32 *verifier, nfs4_setup_readdir(struct nfs4_compound *cp, u64 cookie, u32 *verifier,
struct page **pages, unsigned int bufsize, struct dentry *dentry) struct page **pages, unsigned int bufsize, struct dentry *dentry)
...@@ -821,15 +803,48 @@ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags) ...@@ -821,15 +803,48 @@ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags)
return 0; return 0;
} }
static int static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
nfs4_proc_get_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 nfs_fsinfo *info)
{ {
struct nfs4_compound compound;
struct nfs4_op ops[4];
struct nfs_fattr * fattr = info->fattr; struct nfs_fattr * fattr = info->fattr;
unsigned char * p; unsigned char * p;
struct qstr q; struct qstr q;
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; int status;
/* /*
...@@ -837,14 +852,11 @@ nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, ...@@ -837,14 +852,11 @@ nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
* The LOOKUPs are done separately so that we can conveniently * The LOOKUPs are done separately so that we can conveniently
* catch an ERR_WRONGSEC if it occurs along the way... * catch an ERR_WRONGSEC if it occurs along the way...
*/ */
p = server->mnt_path; status = nfs4_lookup_root(server, fhandle, info);
fattr->valid = 0; if (status)
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)))
goto out; goto out;
p = server->mnt_path;
for (;;) { for (;;) {
while (*p == '/') while (*p == '/')
p++; p++;
...@@ -856,12 +868,7 @@ nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, ...@@ -856,12 +868,7 @@ nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
q.len = p - q.name; q.len = p - q.name;
fattr->valid = 0; fattr->valid = 0;
nfs4_setup_compound(&compound, ops, server, "mount"); status = rpc_call_sync(server->client, &msg, 0);
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);
if (!status) if (!status)
continue; continue;
if (status == -ENOENT) { if (status == -ENOENT) {
...@@ -870,10 +877,10 @@ nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, ...@@ -870,10 +877,10 @@ nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
} }
break; break;
} }
if (status == 0)
status = nfs4_do_fsinfo(server, fhandle, info);
out: out:
if (status)
return nfs4_map_errors(status); return nfs4_map_errors(status);
return nfs4_proc_fsinfo(server, fhandle, info);
} }
static int nfs4_proc_getattr(struct inode *inode, struct nfs_fattr *fattr) static int nfs4_proc_getattr(struct inode *inode, struct nfs_fattr *fattr)
...@@ -1468,8 +1475,7 @@ nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, ...@@ -1468,8 +1475,7 @@ nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
return nfs4_map_errors(nfs4_call_compound(&compound, NULL, 0)); return nfs4_map_errors(nfs4_call_compound(&compound, NULL, 0));
} }
static int static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
nfs4_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
struct nfs_fsinfo *fsinfo) struct nfs_fsinfo *fsinfo)
{ {
struct rpc_message msg = { struct rpc_message msg = {
...@@ -1481,6 +1487,12 @@ nfs4_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, ...@@ -1481,6 +1487,12 @@ nfs4_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
return nfs4_map_errors(rpc_call_sync(server->client, &msg, 0)); 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 static int
nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle, nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
struct nfs_pathconf *pathconf) struct nfs_pathconf *pathconf)
......
...@@ -262,6 +262,14 @@ static int nfs_stat_to_errno(int); ...@@ -262,6 +262,14 @@ static int nfs_stat_to_errno(int);
op_decode_hdr_maxsz + \ op_decode_hdr_maxsz + \
decode_getattr_maxsz + \ decode_getattr_maxsz + \
decode_getfh_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, struct nfs4_compound *cp, struct rpc_rqs ...@@ -1088,15 +1096,9 @@ encode_compound(struct xdr_stream *xdr, struct nfs4_compound *cp, struct rpc_rqs
case OP_LINK: case OP_LINK:
status = encode_link(xdr, &cp->ops[i].u.link); status = encode_link(xdr, &cp->ops[i].u.link);
break; break;
case OP_LOOKUP:
status = encode_lookup(xdr, cp->ops[i].u.lookup.lo_name);
break;
case OP_PUTFH: case OP_PUTFH:
status = encode_putfh(xdr, cp->ops[i].u.putfh.pf_fhandle); status = encode_putfh(xdr, cp->ops[i].u.putfh.pf_fhandle);
break; break;
case OP_PUTROOTFH:
status = encode_putrootfh(xdr);
break;
case OP_READDIR: case OP_READDIR:
status = encode_readdir(xdr, &cp->ops[i].u.readdir, req); status = encode_readdir(xdr, &cp->ops[i].u.readdir, req);
break; break;
...@@ -1185,6 +1187,27 @@ static int nfs4_xdr_enc_lookup(struct rpc_rqst *req, uint32_t *p, const struct n ...@@ -1185,6 +1187,27 @@ static int nfs4_xdr_enc_lookup(struct rpc_rqst *req, uint32_t *p, const struct n
return status; return status;
} }
/*
* 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 * Encode GETATTR request
*/ */
...@@ -2902,15 +2925,9 @@ decode_compound(struct xdr_stream *xdr, struct nfs4_compound *cp, struct rpc_rqs ...@@ -2902,15 +2925,9 @@ decode_compound(struct xdr_stream *xdr, struct nfs4_compound *cp, struct rpc_rqs
case OP_LINK: case OP_LINK:
status = decode_link(xdr, &op->u.link); status = decode_link(xdr, &op->u.link);
break; break;
case OP_LOOKUP:
status = decode_lookup(xdr);
break;
case OP_PUTFH: case OP_PUTFH:
status = decode_putfh(xdr); status = decode_putfh(xdr);
break; break;
case OP_PUTROOTFH:
status = decode_putrootfh(xdr);
break;
case OP_READDIR: case OP_READDIR:
status = decode_readdir(xdr, req, &op->u.readdir); status = decode_readdir(xdr, req, &op->u.readdir);
break; break;
...@@ -3028,6 +3045,26 @@ static int nfs4_xdr_dec_lookup(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_ ...@@ -3028,6 +3045,26 @@ static int nfs4_xdr_dec_lookup(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_
return status; return status;
} }
/*
* 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 * Decode GETATTR response
*/ */
...@@ -3538,6 +3575,7 @@ struct rpc_procinfo nfs4_procedures[] = { ...@@ -3538,6 +3575,7 @@ struct rpc_procinfo nfs4_procedures[] = {
PROC(ACCESS, enc_access, dec_access), PROC(ACCESS, enc_access, dec_access),
PROC(GETATTR, enc_getattr, dec_getattr), PROC(GETATTR, enc_getattr, dec_getattr),
PROC(LOOKUP, enc_lookup, dec_lookup), PROC(LOOKUP, enc_lookup, dec_lookup),
PROC(LOOKUP_ROOT, enc_lookup_root, dec_lookup_root),
}; };
struct rpc_version nfs_version4 = { struct rpc_version nfs_version4 = {
......
...@@ -306,6 +306,7 @@ enum { ...@@ -306,6 +306,7 @@ enum {
NFSPROC4_CLNT_ACCESS, NFSPROC4_CLNT_ACCESS,
NFSPROC4_CLNT_GETATTR, NFSPROC4_CLNT_GETATTR,
NFSPROC4_CLNT_LOOKUP, NFSPROC4_CLNT_LOOKUP,
NFSPROC4_CLNT_LOOKUP_ROOT,
}; };
#endif #endif
......
...@@ -550,10 +550,6 @@ struct nfs4_link { ...@@ -550,10 +550,6 @@ struct nfs4_link {
struct nfs4_change_info * ln_cinfo; /* response */ struct nfs4_change_info * ln_cinfo; /* response */
}; };
struct nfs4_lookup {
struct qstr * lo_name; /* request */
};
struct nfs4_lookup_arg { struct nfs4_lookup_arg {
const struct nfs_fh * dir_fh; const struct nfs_fh * dir_fh;
const struct qstr * name; const struct qstr * name;
...@@ -566,6 +562,10 @@ struct nfs4_lookup_res { ...@@ -566,6 +562,10 @@ struct nfs4_lookup_res {
struct nfs_fh * fh; struct nfs_fh * fh;
}; };
struct nfs4_lookup_root_arg {
const u32 * bitmask;
};
struct nfs4_open { struct nfs4_open {
struct nfs4_client * op_client_state; /* request */ struct nfs4_client * op_client_state; /* request */
u32 op_share_access; /* request */ u32 op_share_access; /* request */
...@@ -644,7 +644,6 @@ struct nfs4_op { ...@@ -644,7 +644,6 @@ struct nfs4_op {
struct nfs4_getattr getattr; struct nfs4_getattr getattr;
struct nfs4_getfh getfh; struct nfs4_getfh getfh;
struct nfs4_link link; struct nfs4_link link;
struct nfs4_lookup lookup;
struct nfs4_open open; struct nfs4_open open;
struct nfs4_open_confirm open_confirm; struct nfs4_open_confirm open_confirm;
struct nfs4_putfh putfh; struct nfs4_putfh putfh;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment