From 4a5d509fbe501d42bd9046eaddc8bb663b758c50 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Thu, 15 Nov 2012 14:52:19 -0500 Subject: [PATCH] --- yaml --- r: 347675 b: refs/heads/master c: ffe1137ba743cdf1c2414d5a89690aec1daa6bba h: refs/heads/master i: 347673: 38c5b211709b2abf5b2a77fd9af137bddb7d03ba 347671: 69c0d930d673f3595e6092d676cbb7a0c461d18f v: v3 --- [refs] | 2 +- .../filesystems/nfs/nfs41-server.txt | 4 ++-- trunk/fs/nfsd/nfs4proc.c | 24 ++++++++++++++++++- trunk/fs/nfsd/nfs4xdr.c | 20 ---------------- trunk/fs/nfsd/xdr4.h | 1 - 5 files changed, 26 insertions(+), 25 deletions(-) diff --git a/[refs] b/[refs] index b5e5fdc3b9c8..42cb4a1ede1d 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 70cc7f75b1ee4161dfdea1012223db25712ab1a5 +refs/heads/master: ffe1137ba743cdf1c2414d5a89690aec1daa6bba diff --git a/trunk/Documentation/filesystems/nfs/nfs41-server.txt b/trunk/Documentation/filesystems/nfs/nfs41-server.txt index 392ef637e101..01c2db769791 100644 --- a/trunk/Documentation/filesystems/nfs/nfs41-server.txt +++ b/trunk/Documentation/filesystems/nfs/nfs41-server.txt @@ -190,7 +190,7 @@ Nonstandard compound limitations: ca_maxrequestsize request and a ca_maxresponsesize reply, so we may fail to live up to the promise we made in CREATE_SESSION fore channel negotiation. -* No more than one IO operation (read, write, readdir) allowed per - compound. +* No more than one read-like operation allowed per compound; encoding + replies that cross page boundaries (except for read data) not handled. See also http://wiki.linux-nfs.org/wiki/index.php/Server_4.0_and_4.1_issues. diff --git a/trunk/fs/nfsd/nfs4proc.c b/trunk/fs/nfsd/nfs4proc.c index 1d2396b79574..87d24e5f3ca4 100644 --- a/trunk/fs/nfsd/nfs4proc.c +++ b/trunk/fs/nfsd/nfs4proc.c @@ -881,6 +881,24 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, return status; } +static int fill_in_write_vector(struct kvec *vec, struct nfsd4_write *write) +{ + int i = 1; + int buflen = write->wr_buflen; + + vec[0].iov_base = write->wr_head.iov_base; + vec[0].iov_len = min_t(int, buflen, write->wr_head.iov_len); + buflen -= vec[0].iov_len; + + while (buflen) { + vec[i].iov_base = page_address(write->wr_pagelist[i - 1]); + vec[i].iov_len = min_t(int, PAGE_SIZE, buflen); + buflen -= vec[i].iov_len; + i++; + } + return i; +} + static __be32 nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_write *write) @@ -889,6 +907,7 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct file *filp = NULL; __be32 status = nfs_ok; unsigned long cnt; + int nvecs; /* no need to check permission - this will be done in nfsd_write() */ @@ -911,8 +930,11 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, write->wr_how_written = write->wr_stable_how; gen_boot_verifier(&write->wr_verifier); + nvecs = fill_in_write_vector(rqstp->rq_vec, write); + WARN_ON_ONCE(nvecs > ARRAY_SIZE(rqstp->rq_vec)); + status = nfsd_write(rqstp, &cstate->current_fh, filp, - write->wr_offset, rqstp->rq_vec, write->wr_vlen, + write->wr_offset, rqstp->rq_vec, nvecs, &cnt, &write->wr_how_written); if (filp) fput(filp); diff --git a/trunk/fs/nfsd/nfs4xdr.c b/trunk/fs/nfsd/nfs4xdr.c index cb9f9017af8f..09204f590355 100644 --- a/trunk/fs/nfsd/nfs4xdr.c +++ b/trunk/fs/nfsd/nfs4xdr.c @@ -1139,24 +1139,6 @@ nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify DECODE_TAIL; } -static int fill_in_write_vector(struct kvec *vec, struct nfsd4_write *write) -{ - int i = 1; - int buflen = write->wr_buflen; - - vec[0].iov_base = write->wr_head.iov_base; - vec[0].iov_len = min_t(int, buflen, write->wr_head.iov_len); - buflen -= vec[0].iov_len; - - while (buflen) { - vec[i].iov_base = page_address(write->wr_pagelist[i - 1]); - vec[i].iov_len = min_t(int, PAGE_SIZE, buflen); - buflen -= vec[i].iov_len; - i++; - } - return i; -} - static __be32 nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write) { @@ -1204,8 +1186,6 @@ nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write) argp->end = argp->p + XDR_QUADLEN(PAGE_SIZE); } argp->p += XDR_QUADLEN(len); - write->wr_vlen = fill_in_write_vector(argp->rqstp->rq_vec, write); - WARN_ON_ONCE(write->wr_vlen > ARRAY_SIZE(argp->rqstp->rq_vec)); DECODE_TAIL; } diff --git a/trunk/fs/nfsd/xdr4.h b/trunk/fs/nfsd/xdr4.h index 152867b8125d..331f8a3277ab 100644 --- a/trunk/fs/nfsd/xdr4.h +++ b/trunk/fs/nfsd/xdr4.h @@ -385,7 +385,6 @@ struct nfsd4_write { u64 wr_offset; /* request */ u32 wr_stable_how; /* request */ u32 wr_buflen; /* request */ - int wr_vlen; struct kvec wr_head; struct page ** wr_pagelist; /* request */