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