Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 38364
b: refs/heads/master
c: 4452435
h: refs/heads/master
v: v3
  • Loading branch information
NeilBrown authored and Linus Torvalds committed Oct 4, 2006
1 parent b518940 commit 18e22ca
Show file tree
Hide file tree
Showing 11 changed files with 78 additions and 142 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5680c44632053a6c9464bca43083f01776d318da
refs/heads/master: 4452435948424e5322c2a2fefbdc2cf3732cc45d
2 changes: 1 addition & 1 deletion trunk/fs/nfsd/nfs2acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, u32 *p,

rqstp->rq_res.page_len = w;
while (w > 0) {
if (!svc_take_res_page(rqstp))
if (!rqstp->rq_respages[rqstp->rq_resused++])
return 0;
w -= PAGE_SIZE;
}
Expand Down
2 changes: 1 addition & 1 deletion trunk/fs/nfsd/nfs3acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ static int nfs3svc_encode_getaclres(struct svc_rqst *rqstp, u32 *p,

rqstp->rq_res.page_len = w;
while (w > 0) {
if (!svc_take_res_page(rqstp))
if (!rqstp->rq_respages[rqstp->rq_resused++])
return 0;
w -= PAGE_SIZE;
}
Expand Down
23 changes: 9 additions & 14 deletions trunk/fs/nfsd/nfs3xdr.c
Original file line number Diff line number Diff line change
Expand Up @@ -343,8 +343,7 @@ nfs3svc_decode_readargs(struct svc_rqst *rqstp, u32 *p,
/* set up the kvec */
v=0;
while (len > 0) {
pn = rqstp->rq_resused;
svc_take_page(rqstp);
pn = rqstp->rq_resused++;
args->vec[v].iov_base = page_address(rqstp->rq_respages[pn]);
args->vec[v].iov_len = len < PAGE_SIZE? len : PAGE_SIZE;
len -= args->vec[v].iov_len;
Expand Down Expand Up @@ -382,7 +381,7 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, u32 *p,
while (len > args->vec[v].iov_len) {
len -= args->vec[v].iov_len;
v++;
args->vec[v].iov_base = page_address(rqstp->rq_argpages[v]);
args->vec[v].iov_base = page_address(rqstp->rq_pages[v]);
args->vec[v].iov_len = PAGE_SIZE;
}
args->vec[v].iov_len = len;
Expand Down Expand Up @@ -446,11 +445,11 @@ nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, u32 *p,
* This page appears in the rq_res.pages list, but as pages_len is always
* 0, it won't get in the way
*/
svc_take_page(rqstp);
len = ntohl(*p++);
if (len == 0 || len > NFS3_MAXPATHLEN || len >= PAGE_SIZE)
return 0;
args->tname = new = page_address(rqstp->rq_respages[rqstp->rq_resused-1]);
args->tname = new =
page_address(rqstp->rq_respages[rqstp->rq_resused++]);
args->tlen = len;
/* first copy and check from the first page */
old = (char*)p;
Expand Down Expand Up @@ -522,8 +521,8 @@ nfs3svc_decode_readlinkargs(struct svc_rqst *rqstp, u32 *p,
{
if (!(p = decode_fh(p, &args->fh)))
return 0;
svc_take_page(rqstp);
args->buffer = page_address(rqstp->rq_respages[rqstp->rq_resused-1]);
args->buffer =
page_address(rqstp->rq_respages[rqstp->rq_resused++]);

return xdr_argsize_check(rqstp, p);
}
Expand Down Expand Up @@ -554,8 +553,8 @@ nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, u32 *p,
if (args->count > PAGE_SIZE)
args->count = PAGE_SIZE;

svc_take_page(rqstp);
args->buffer = page_address(rqstp->rq_respages[rqstp->rq_resused-1]);
args->buffer =
page_address(rqstp->rq_respages[rqstp->rq_resused++]);

return xdr_argsize_check(rqstp, p);
}
Expand All @@ -578,8 +577,7 @@ nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, u32 *p,
args->count = len;

while (len > 0) {
pn = rqstp->rq_resused;
svc_take_page(rqstp);
pn = rqstp->rq_resused++;
if (!args->buffer)
args->buffer = page_address(rqstp->rq_respages[pn]);
len -= PAGE_SIZE;
Expand Down Expand Up @@ -668,7 +666,6 @@ nfs3svc_encode_readlinkres(struct svc_rqst *rqstp, u32 *p,
rqstp->rq_res.page_len = resp->len;
if (resp->len & 3) {
/* need to pad the tail */
rqstp->rq_restailpage = 0;
rqstp->rq_res.tail[0].iov_base = p;
*p = 0;
rqstp->rq_res.tail[0].iov_len = 4 - (resp->len&3);
Expand All @@ -693,7 +690,6 @@ nfs3svc_encode_readres(struct svc_rqst *rqstp, u32 *p,
rqstp->rq_res.page_len = resp->count;
if (resp->count & 3) {
/* need to pad the tail */
rqstp->rq_restailpage = 0;
rqstp->rq_res.tail[0].iov_base = p;
*p = 0;
rqstp->rq_res.tail[0].iov_len = 4 - (resp->count & 3);
Expand Down Expand Up @@ -768,7 +764,6 @@ nfs3svc_encode_readdirres(struct svc_rqst *rqstp, u32 *p,
rqstp->rq_res.page_len = (resp->count) << 2;

/* add the 'tail' to the end of the 'head' page - page 0. */
rqstp->rq_restailpage = 0;
rqstp->rq_res.tail[0].iov_base = p;
*p++ = 0; /* no more entries */
*p++ = htonl(resp->common.err == nfserr_eof);
Expand Down
27 changes: 13 additions & 14 deletions trunk/fs/nfsd/nfs4xdr.c
Original file line number Diff line number Diff line change
Expand Up @@ -2039,7 +2039,8 @@ nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, int nfserr, struct n
}

static int
nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_read *read)
nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr,
struct nfsd4_read *read)
{
u32 eof;
int v, pn;
Expand All @@ -2061,10 +2062,11 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_read
len = maxcount;
v = 0;
while (len > 0) {
pn = resp->rqstp->rq_resused;
svc_take_page(resp->rqstp);
read->rd_iov[v].iov_base = page_address(resp->rqstp->rq_respages[pn]);
read->rd_iov[v].iov_len = len < PAGE_SIZE ? len : PAGE_SIZE;
pn = resp->rqstp->rq_resused++;
read->rd_iov[v].iov_base =
page_address(resp->rqstp->rq_respages[pn]);
read->rd_iov[v].iov_len =
len < PAGE_SIZE ? len : PAGE_SIZE;
v++;
len -= PAGE_SIZE;
}
Expand All @@ -2078,7 +2080,8 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_read
nfserr = nfserr_inval;
if (nfserr)
return nfserr;
eof = (read->rd_offset + maxcount >= read->rd_fhp->fh_dentry->d_inode->i_size);
eof = (read->rd_offset + maxcount >=
read->rd_fhp->fh_dentry->d_inode->i_size);

WRITE32(eof);
WRITE32(maxcount);
Expand All @@ -2088,7 +2091,6 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_read
resp->xbuf->page_len = maxcount;

/* Use rest of head for padding and remaining ops: */
resp->rqstp->rq_restailpage = 0;
resp->xbuf->tail[0].iov_base = p;
resp->xbuf->tail[0].iov_len = 0;
if (maxcount&3) {
Expand All @@ -2113,8 +2115,7 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_r
if (resp->xbuf->page_len)
return nfserr_resource;

svc_take_page(resp->rqstp);
page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]);
page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused++]);

maxcount = PAGE_SIZE;
RESERVE_SPACE(4);
Expand All @@ -2138,7 +2139,6 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_r
resp->xbuf->page_len = maxcount;

/* Use rest of head for padding and remaining ops: */
resp->rqstp->rq_restailpage = 0;
resp->xbuf->tail[0].iov_base = p;
resp->xbuf->tail[0].iov_len = 0;
if (maxcount&3) {
Expand Down Expand Up @@ -2189,8 +2189,7 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_re
goto err_no_verf;
}

svc_take_page(resp->rqstp);
page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]);
page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused++]);
readdir->common.err = 0;
readdir->buflen = maxcount;
readdir->buffer = page;
Expand All @@ -2215,10 +2214,10 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_re
p = readdir->buffer;
*p++ = 0; /* no more entries */
*p++ = htonl(readdir->common.err == nfserr_eof);
resp->xbuf->page_len = ((char*)p) - (char*)page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]);
resp->xbuf->page_len = ((char*)p) - (char*)page_address(
resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]);

/* Use rest of head for padding and remaining ops: */
resp->rqstp->rq_restailpage = 0;
resp->xbuf->tail[0].iov_base = tailbase;
resp->xbuf->tail[0].iov_len = 0;
resp->p = resp->xbuf->tail[0].iov_base;
Expand Down
13 changes: 4 additions & 9 deletions trunk/fs/nfsd/nfsxdr.c
Original file line number Diff line number Diff line change
Expand Up @@ -262,8 +262,7 @@ nfssvc_decode_readargs(struct svc_rqst *rqstp, u32 *p,
*/
v=0;
while (len > 0) {
pn=rqstp->rq_resused;
svc_take_page(rqstp);
pn = rqstp->rq_resused++;
args->vec[v].iov_base = page_address(rqstp->rq_respages[pn]);
args->vec[v].iov_len = len < PAGE_SIZE?len:PAGE_SIZE;
len -= args->vec[v].iov_len;
Expand Down Expand Up @@ -295,7 +294,7 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, u32 *p,
while (len > args->vec[v].iov_len) {
len -= args->vec[v].iov_len;
v++;
args->vec[v].iov_base = page_address(rqstp->rq_argpages[v]);
args->vec[v].iov_base = page_address(rqstp->rq_pages[v]);
args->vec[v].iov_len = PAGE_SIZE;
}
args->vec[v].iov_len = len;
Expand Down Expand Up @@ -333,8 +332,7 @@ nfssvc_decode_readlinkargs(struct svc_rqst *rqstp, u32 *p, struct nfsd_readlinka
{
if (!(p = decode_fh(p, &args->fh)))
return 0;
svc_take_page(rqstp);
args->buffer = page_address(rqstp->rq_respages[rqstp->rq_resused-1]);
args->buffer = page_address(rqstp->rq_respages[rqstp->rq_resused++]);

return xdr_argsize_check(rqstp, p);
}
Expand Down Expand Up @@ -375,8 +373,7 @@ nfssvc_decode_readdirargs(struct svc_rqst *rqstp, u32 *p,
if (args->count > PAGE_SIZE)
args->count = PAGE_SIZE;

svc_take_page(rqstp);
args->buffer = page_address(rqstp->rq_respages[rqstp->rq_resused-1]);
args->buffer = page_address(rqstp->rq_respages[rqstp->rq_resused++]);

return xdr_argsize_check(rqstp, p);
}
Expand Down Expand Up @@ -416,7 +413,6 @@ nfssvc_encode_readlinkres(struct svc_rqst *rqstp, u32 *p,
rqstp->rq_res.page_len = resp->len;
if (resp->len & 3) {
/* need to pad the tail */
rqstp->rq_restailpage = 0;
rqstp->rq_res.tail[0].iov_base = p;
*p = 0;
rqstp->rq_res.tail[0].iov_len = 4 - (resp->len&3);
Expand All @@ -436,7 +432,6 @@ nfssvc_encode_readres(struct svc_rqst *rqstp, u32 *p,
rqstp->rq_res.page_len = resp->count;
if (resp->count & 3) {
/* need to pad the tail */
rqstp->rq_restailpage = 0;
rqstp->rq_res.tail[0].iov_base = p;
*p = 0;
rqstp->rq_res.tail[0].iov_len = 4 - (resp->count&3);
Expand Down
16 changes: 10 additions & 6 deletions trunk/fs/nfsd/vfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -791,22 +791,26 @@ nfsd_read_actor(read_descriptor_t *desc, struct page *page, unsigned long offset
{
unsigned long count = desc->count;
struct svc_rqst *rqstp = desc->arg.data;
struct page **pp = rqstp->rq_respages + rqstp->rq_resused;

if (size > count)
size = count;

if (rqstp->rq_res.page_len == 0) {
get_page(page);
rqstp->rq_respages[rqstp->rq_resused++] = page;
put_page(*pp);
*pp = page;
rqstp->rq_resused++;
rqstp->rq_res.page_base = offset;
rqstp->rq_res.page_len = size;
} else if (page != rqstp->rq_respages[rqstp->rq_resused-1]) {
} else if (page != pp[-1]) {
get_page(page);
rqstp->rq_respages[rqstp->rq_resused++] = page;
put_page(*pp);
*pp = page;
rqstp->rq_resused++;
rqstp->rq_res.page_len += size;
} else {
} else
rqstp->rq_res.page_len += size;
}

desc->count = count - size;
desc->written += size;
Expand Down Expand Up @@ -837,7 +841,7 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
file->f_ra = ra->p_ra;

if (file->f_op->sendfile && rqstp->rq_sendfile_ok) {
svc_pushback_unused_pages(rqstp);
rqstp->rq_resused = 1;
err = file->f_op->sendfile(file, &offset, *count,
nfsd_read_actor, rqstp);
} else {
Expand Down
69 changes: 10 additions & 59 deletions trunk/include/linux/sunrpc/svc.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,6 @@ static inline void svc_putu32(struct kvec *iov, __be32 val)
/*
* The context of a single thread, including the request currently being
* processed.
* NOTE: First two items must be prev/next.
*/
struct svc_rqst {
struct list_head rq_list; /* idle list */
Expand All @@ -189,12 +188,9 @@ struct svc_rqst {

struct xdr_buf rq_arg;
struct xdr_buf rq_res;
struct page * rq_argpages[RPCSVC_MAXPAGES];
struct page * rq_respages[RPCSVC_MAXPAGES];
int rq_restailpage;
short rq_argused; /* pages used for argument */
short rq_arghi; /* pages available in argument page list */
short rq_resused; /* pages used for result */
struct page * rq_pages[RPCSVC_MAXPAGES];
struct page * *rq_respages; /* points into rq_pages */
int rq_resused; /* number of pages used for result */

__be32 rq_xid; /* transmission id */
u32 rq_prog; /* program number */
Expand Down Expand Up @@ -255,63 +251,18 @@ xdr_ressize_check(struct svc_rqst *rqstp, __be32 *p)
return vec->iov_len <= PAGE_SIZE;
}

static inline struct page *
svc_take_res_page(struct svc_rqst *rqstp)
static inline void svc_free_res_pages(struct svc_rqst *rqstp)
{
if (rqstp->rq_arghi <= rqstp->rq_argused)
return NULL;
rqstp->rq_arghi--;
rqstp->rq_respages[rqstp->rq_resused] =
rqstp->rq_argpages[rqstp->rq_arghi];
return rqstp->rq_respages[rqstp->rq_resused++];
}

static inline void svc_take_page(struct svc_rqst *rqstp)
{
if (rqstp->rq_arghi <= rqstp->rq_argused) {
WARN_ON(1);
return;
}
rqstp->rq_arghi--;
rqstp->rq_respages[rqstp->rq_resused] =
rqstp->rq_argpages[rqstp->rq_arghi];
rqstp->rq_resused++;
}

static inline void svc_pushback_allpages(struct svc_rqst *rqstp)
{
while (rqstp->rq_resused) {
if (rqstp->rq_respages[--rqstp->rq_resused] == NULL)
continue;
rqstp->rq_argpages[rqstp->rq_arghi++] =
rqstp->rq_respages[rqstp->rq_resused];
rqstp->rq_respages[rqstp->rq_resused] = NULL;
}
}

static inline void svc_pushback_unused_pages(struct svc_rqst *rqstp)
{
while (rqstp->rq_resused &&
rqstp->rq_res.pages != &rqstp->rq_respages[rqstp->rq_resused]) {

if (rqstp->rq_respages[--rqstp->rq_resused] != NULL) {
rqstp->rq_argpages[rqstp->rq_arghi++] =
rqstp->rq_respages[rqstp->rq_resused];
rqstp->rq_respages[rqstp->rq_resused] = NULL;
while (rqstp->rq_resused) {
struct page **pp = (rqstp->rq_respages +
--rqstp->rq_resused);
if (*pp) {
put_page(*pp);
*pp = NULL;
}
}
}

static inline void svc_free_allpages(struct svc_rqst *rqstp)
{
while (rqstp->rq_resused) {
if (rqstp->rq_respages[--rqstp->rq_resused] == NULL)
continue;
put_page(rqstp->rq_respages[rqstp->rq_resused]);
rqstp->rq_respages[rqstp->rq_resused] = NULL;
}
}

struct svc_deferred_req {
u32 prot; /* protocol (UDP or TCP) */
struct sockaddr_in addr;
Expand Down
Loading

0 comments on commit 18e22ca

Please sign in to comment.