mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 06:02:05 +00:00
NFSD: Have legacy NFSD WRITE decoders use xdr_stream_subsegment()
Refactor. Now that the NFSv2 and NFSv3 XDR decoders have been converted to use xdr_streams, the WRITE decoder functions can use xdr_stream_subsegment() to extract the WRITE payload into its own xdr_buf, just as the NFSv4 WRITE XDR decoder currently does. That makes it possible to pass the first kvec, pages array + length, page_base, and total payload length via a single function parameter. The payload's page_base is not yet assigned or used, but will be in subsequent patches. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
This commit is contained in:
parent
f49b68ddc9
commit
dae9a6cab8
@ -201,8 +201,7 @@ nfsd3_proc_write(struct svc_rqst *rqstp)
|
||||
|
||||
fh_copy(&resp->fh, &argp->fh);
|
||||
resp->committed = argp->stable;
|
||||
nvecs = svc_fill_write_vector(rqstp, rqstp->rq_arg.pages,
|
||||
&argp->first, cnt);
|
||||
nvecs = svc_fill_write_vector(rqstp, &argp->payload);
|
||||
if (!nvecs) {
|
||||
resp->status = nfserr_io;
|
||||
goto out;
|
||||
|
@ -621,9 +621,6 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p)
|
||||
struct xdr_stream *xdr = &rqstp->rq_arg_stream;
|
||||
struct nfsd3_writeargs *args = rqstp->rq_argp;
|
||||
u32 max_blocksize = svc_max_payload(rqstp);
|
||||
struct kvec *head = rqstp->rq_arg.head;
|
||||
struct kvec *tail = rqstp->rq_arg.tail;
|
||||
size_t remaining;
|
||||
|
||||
if (!svcxdr_decode_nfs_fh3(xdr, &args->fh))
|
||||
return 0;
|
||||
@ -641,17 +638,12 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p)
|
||||
/* request sanity */
|
||||
if (args->count != args->len)
|
||||
return 0;
|
||||
remaining = head->iov_len + rqstp->rq_arg.page_len + tail->iov_len;
|
||||
remaining -= xdr_stream_pos(xdr);
|
||||
if (remaining < xdr_align_size(args->len))
|
||||
return 0;
|
||||
if (args->count > max_blocksize) {
|
||||
args->count = max_blocksize;
|
||||
args->len = max_blocksize;
|
||||
}
|
||||
|
||||
args->first.iov_base = xdr->p;
|
||||
args->first.iov_len = head->iov_len - xdr_stream_pos(xdr);
|
||||
if (!xdr_stream_subsegment(xdr, &args->payload, args->count))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -1033,8 +1033,7 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
|
||||
|
||||
write->wr_how_written = write->wr_stable_how;
|
||||
|
||||
nvecs = svc_fill_write_vector(rqstp, write->wr_payload.pages,
|
||||
write->wr_payload.head, write->wr_buflen);
|
||||
nvecs = svc_fill_write_vector(rqstp, &write->wr_payload);
|
||||
WARN_ON_ONCE(nvecs > ARRAY_SIZE(rqstp->rq_vec));
|
||||
|
||||
status = nfsd_vfs_write(rqstp, &cstate->current_fh, nf,
|
||||
|
@ -234,8 +234,7 @@ nfsd_proc_write(struct svc_rqst *rqstp)
|
||||
SVCFH_fmt(&argp->fh),
|
||||
argp->len, argp->offset);
|
||||
|
||||
nvecs = svc_fill_write_vector(rqstp, rqstp->rq_arg.pages,
|
||||
&argp->first, cnt);
|
||||
nvecs = svc_fill_write_vector(rqstp, &argp->payload);
|
||||
if (!nvecs) {
|
||||
resp->status = nfserr_io;
|
||||
goto out;
|
||||
|
@ -325,10 +325,7 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p)
|
||||
{
|
||||
struct xdr_stream *xdr = &rqstp->rq_arg_stream;
|
||||
struct nfsd_writeargs *args = rqstp->rq_argp;
|
||||
struct kvec *head = rqstp->rq_arg.head;
|
||||
struct kvec *tail = rqstp->rq_arg.tail;
|
||||
u32 beginoffset, totalcount;
|
||||
size_t remaining;
|
||||
|
||||
if (!svcxdr_decode_fhandle(xdr, &args->fh))
|
||||
return 0;
|
||||
@ -346,12 +343,8 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p)
|
||||
return 0;
|
||||
if (args->len > NFSSVC_MAXBLKSIZE_V2)
|
||||
return 0;
|
||||
remaining = head->iov_len + rqstp->rq_arg.page_len + tail->iov_len;
|
||||
remaining -= xdr_stream_pos(xdr);
|
||||
if (remaining < xdr_align_size(args->len))
|
||||
if (!xdr_stream_subsegment(xdr, &args->payload, args->len))
|
||||
return 0;
|
||||
args->first.iov_base = xdr->p;
|
||||
args->first.iov_len = head->iov_len - xdr_stream_pos(xdr);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ struct nfsd_writeargs {
|
||||
svc_fh fh;
|
||||
__u32 offset;
|
||||
int len;
|
||||
struct kvec first;
|
||||
struct xdr_buf payload;
|
||||
};
|
||||
|
||||
struct nfsd_createargs {
|
||||
|
@ -40,7 +40,7 @@ struct nfsd3_writeargs {
|
||||
__u32 count;
|
||||
int stable;
|
||||
__u32 len;
|
||||
struct kvec first;
|
||||
struct xdr_buf payload;
|
||||
};
|
||||
|
||||
struct nfsd3_createargs {
|
||||
|
@ -532,8 +532,7 @@ int svc_encode_result_payload(struct svc_rqst *rqstp,
|
||||
unsigned int offset,
|
||||
unsigned int length);
|
||||
unsigned int svc_fill_write_vector(struct svc_rqst *rqstp,
|
||||
struct page **pages,
|
||||
struct kvec *first, size_t total);
|
||||
struct xdr_buf *payload);
|
||||
char *svc_fill_symlink_pathname(struct svc_rqst *rqstp,
|
||||
struct kvec *first, void *p,
|
||||
size_t total);
|
||||
|
@ -1676,16 +1676,17 @@ EXPORT_SYMBOL_GPL(svc_encode_result_payload);
|
||||
/**
|
||||
* svc_fill_write_vector - Construct data argument for VFS write call
|
||||
* @rqstp: svc_rqst to operate on
|
||||
* @pages: list of pages containing data payload
|
||||
* @first: buffer containing first section of write payload
|
||||
* @total: total number of bytes of write payload
|
||||
* @payload: xdr_buf containing only the write data payload
|
||||
*
|
||||
* Fills in rqstp::rq_vec, and returns the number of elements.
|
||||
*/
|
||||
unsigned int svc_fill_write_vector(struct svc_rqst *rqstp, struct page **pages,
|
||||
struct kvec *first, size_t total)
|
||||
unsigned int svc_fill_write_vector(struct svc_rqst *rqstp,
|
||||
struct xdr_buf *payload)
|
||||
{
|
||||
struct page **pages = payload->pages;
|
||||
struct kvec *first = payload->head;
|
||||
struct kvec *vec = rqstp->rq_vec;
|
||||
size_t total = payload->len;
|
||||
unsigned int i;
|
||||
|
||||
/* Some types of transport can present the write payload
|
||||
|
Loading…
Reference in New Issue
Block a user