Commit 1513be7e authored by Trond Myklebust's avatar Trond Myklebust

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

READLINK RPC calls.
parent 15c5fef5
......@@ -187,18 +187,6 @@ nfs4_setup_readdir(struct nfs4_compound *cp, u64 cookie, u32 *verifier,
kunmap_atomic(start, KM_USER0);
}
static void
nfs4_setup_readlink(struct nfs4_compound *cp, int count, struct page **pages)
{
struct nfs4_readlink *readlink = GET_OP(cp, readlink);
readlink->rl_count = count;
readlink->rl_pages = pages;
OPNUM(cp) = OP_READLINK;
cp->req_nops++;
}
static void
renew_lease(struct nfs_server *server, unsigned long timestamp)
{
......@@ -885,16 +873,20 @@ static int nfs4_proc_access(struct inode *inode, struct rpc_cred *cred, int mode
* Both of these changes to the XDR layer would in fact be quite
* minor, but I decided to leave them for a subsequent patch.
*/
static int
nfs4_proc_readlink(struct inode *inode, struct page *page)
static int nfs4_proc_readlink(struct inode *inode, struct page *page)
{
struct nfs4_compound compound;
struct nfs4_op ops[2];
struct nfs4_readlink args = {
.fh = NFS_FH(inode),
.count = PAGE_CACHE_SIZE,
.pages = &page,
};
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READLINK],
.rpc_argp = &args,
.rpc_resp = NULL,
};
nfs4_setup_compound(&compound, ops, NFS_SERVER(inode), "readlink");
nfs4_setup_putfh(&compound, NFS_FH(inode));
nfs4_setup_readlink(&compound, PAGE_CACHE_SIZE, &page);
return nfs4_map_errors(nfs4_call_compound(&compound, NULL, 0));
return nfs4_map_errors(rpc_call_sync(NFS_CLIENT(inode), &msg, 0));
}
static int
......
......@@ -132,6 +132,12 @@ static int nfs_stat_to_errno(int);
#define NFS4_dec_read_sz (compound_decode_hdr_maxsz + \
decode_putfh_maxsz + \
op_decode_hdr_maxsz + 2)
#define NFS4_enc_readlink_sz (compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
op_encode_hdr_maxsz)
#define NFS4_dec_readlink_sz (compound_decode_hdr_maxsz + \
decode_putfh_maxsz + \
op_decode_hdr_maxsz)
#define NFS4_enc_write_sz (compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
op_encode_hdr_maxsz + 8)
......@@ -963,8 +969,7 @@ encode_readdir(struct xdr_stream *xdr, struct nfs4_readdir *readdir, struct rpc_
return 0;
}
static int
encode_readlink(struct xdr_stream *xdr, struct nfs4_readlink *readlink, struct rpc_rqst *req)
static int encode_readlink(struct xdr_stream *xdr, const struct nfs4_readlink *readlink, struct rpc_rqst *req)
{
struct rpc_auth *auth = req->rq_task->tk_auth;
int replen;
......@@ -978,7 +983,7 @@ encode_readlink(struct xdr_stream *xdr, struct nfs4_readlink *readlink, struct r
* + OP_READLINK + status = 7
*/
replen = (RPC_REPHDRSIZE + auth->au_rslack + 7) << 2;
xdr_inline_pages(&req->rq_rcv_buf, replen, readlink->rl_pages, 0, readlink->rl_count);
xdr_inline_pages(&req->rq_rcv_buf, replen, readlink->pages, 0, readlink->count);
return 0;
}
......@@ -1144,9 +1149,6 @@ encode_compound(struct xdr_stream *xdr, struct nfs4_compound *cp, struct rpc_rqs
case OP_READDIR:
status = encode_readdir(xdr, &cp->ops[i].u.readdir, req);
break;
case OP_READLINK:
status = encode_readlink(xdr, &cp->ops[i].u.readlink, req);
break;
default:
BUG();
}
......@@ -1541,6 +1543,27 @@ nfs4_xdr_enc_locku(struct rpc_rqst *req, uint32_t *p, struct nfs_lockargs *args)
return status;
}
/*
* Encode a READLINK request
*/
static int nfs4_xdr_enc_readlink(struct rpc_rqst *req, uint32_t *p, const struct nfs4_readlink *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);
status = encode_putfh(&xdr, args->fh);
if(status)
goto out;
status = encode_readlink(&xdr, args, req);
out:
return status;
}
/*
* Encode a READ request
*/
......@@ -3018,8 +3041,7 @@ decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs4_readdir
return -errno_NFSERR_IO;
}
static int
decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs4_readlink *readlink)
static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req)
{
struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
struct iovec *iov = rcvbuf->head;
......@@ -3220,9 +3242,6 @@ decode_compound(struct xdr_stream *xdr, struct nfs4_compound *cp, struct rpc_rqs
case OP_READDIR:
status = decode_readdir(xdr, req, &op->u.readdir);
break;
case OP_READLINK:
status = decode_readlink(xdr, req, &op->u.readlink);
break;
default:
BUG();
return -EIO;
......@@ -3651,6 +3670,27 @@ nfs4_xdr_dec_locku(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_lockres *res)
return status;
}
/*
* Decode READLINK response
*/
static int nfs4_xdr_dec_readlink(struct rpc_rqst *rqstp, uint32_t *p, void *res)
{
struct xdr_stream xdr;
struct compound_hdr hdr;
int status;
xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
status = decode_compound_hdr(&xdr, &hdr);
if (status)
goto out;
status = decode_putfh(&xdr);
if (status)
goto out;
status = decode_readlink(&xdr, rqstp);
out:
return status;
}
/*
* Decode Read response
*/
......@@ -3982,6 +4022,7 @@ struct rpc_procinfo nfs4_procedures[] = {
PROC(CREATE, enc_create, dec_create),
PROC(PATHCONF, enc_pathconf, dec_pathconf),
PROC(STATFS, enc_statfs, dec_statfs),
PROC(READLINK, enc_readlink, dec_readlink),
};
struct rpc_version nfs_version4 = {
......
......@@ -313,6 +313,7 @@ enum {
NFSPROC4_CLNT_CREATE,
NFSPROC4_CLNT_PATHCONF,
NFSPROC4_CLNT_STATFS,
NFSPROC4_CLNT_READLINK,
};
#endif
......
......@@ -609,8 +609,9 @@ struct nfs4_readdir {
};
struct nfs4_readlink {
u32 rl_count; /* zero-copy data */
struct page ** rl_pages; /* zero-copy data */
const struct nfs_fh * fh;
u32 count; /* zero-copy data */
struct page ** pages; /* zero-copy data */
};
struct nfs4_remove_arg {
......
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