fs/nfs/nfs3proc.c | 30 +++++++++--------------------- fs/nfs/nfs4proc.c | 40 +++++++++++++++------------------------- fs/nfs/proc.c | 38 +++++++++++++++----------------------- fs/nfs/read.c | 40 ++++++++++++++++++++++++++-------------- include/linux/nfs_xdr.h | 6 ++---- 5 files changed, 67 insertions(+), 87 deletions(-) diff -puN fs/nfs/nfs3proc.c~22-read_proc fs/nfs/nfs3proc.c --- 25/fs/nfs/nfs3proc.c~22-read_proc 2003-06-26 18:38:23.000000000 -0700 +++ 25-akpm/fs/nfs/nfs3proc.c 2003-06-26 18:38:23.000000000 -0700 @@ -225,38 +225,26 @@ nfs3_proc_readlink(struct inode *inode, } static int -nfs3_proc_read(struct inode *inode, struct rpc_cred *cred, - struct nfs_fattr *fattr, int flags, - unsigned int base, unsigned int count, struct page *page, - int *eofp) +nfs3_proc_read(struct nfs_read_data *rdata) { - u64 offset = page_offset(page) + base; - struct nfs_readargs arg = { - .fh = NFS_FH(inode), - .offset = offset, - .count = count, - .pgbase = base, - .pages = &page - }; - struct nfs_readres res = { - .fattr = fattr, - .count = count, - }; + int flags = rdata->flags; + struct inode * inode = rdata->inode; + struct nfs_fattr * fattr = rdata->res.fattr; struct rpc_message msg = { .rpc_proc = &nfs3_procedures[NFS3PROC_READ], - .rpc_argp = &arg, - .rpc_resp = &res, - .rpc_cred = cred + .rpc_argp = &rdata->args, + .rpc_resp = &rdata->res, + .rpc_cred = rdata->cred, }; int status; - dprintk("NFS call read %d @ %Ld\n", count, (long long)offset); + dprintk("NFS call read %d @ %Ld\n", rdata->args.count, + (long long) rdata->args.offset); fattr->valid = 0; status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags); if (status >= 0) nfs_refresh_inode(inode, fattr); dprintk("NFS reply read: %d\n", status); - *eofp = res.eof; return status; } diff -puN fs/nfs/nfs4proc.c~22-read_proc fs/nfs/nfs4proc.c --- 25/fs/nfs/nfs4proc.c~22-read_proc 2003-06-26 18:38:23.000000000 -0700 +++ 25-akpm/fs/nfs/nfs4proc.c 2003-06-26 18:38:23.000000000 -0700 @@ -1012,45 +1012,36 @@ nfs4_proc_readlink(struct inode *inode, } static int -nfs4_proc_read(struct inode *inode, struct rpc_cred *cred, - struct nfs_fattr *fattr, int flags, - unsigned int base, unsigned int count, - struct page *page, int *eofp) +nfs4_proc_read(struct nfs_read_data *rdata) { + int flags = rdata->flags; + struct inode *inode = rdata->inode; + struct nfs_fattr *fattr = rdata->res.fattr; + nfs4_stateid *stateid = &rdata->args.stateid; struct nfs_server *server = NFS_SERVER(inode); struct nfs4_shareowner *sp; - uint64_t offset = page_offset(page) + base; - struct nfs_readargs arg = { - .fh = NFS_FH(inode), - .offset = offset, - .count = count, - .pgbase = base, - .pages = &page, - }; - struct nfs_readres res = { - .fattr = fattr, - .count = count, - }; struct rpc_message msg = { .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ], - .rpc_argp = &arg, - .rpc_resp = &res, - .rpc_cred = cred, + .rpc_argp = &rdata->args, + .rpc_resp = &rdata->res, + .rpc_cred = rdata->cred, }; unsigned long timestamp = jiffies; int status; - dprintk("NFS call read %d @ %Ld\n", count, (long long)offset); + dprintk("NFS call read %d @ %Ld\n", rdata->args.count, + (long long) rdata->args.offset); + /* - * Try first to use O_RDONLY, then O_RDWR stateid. - */ + * Try first to use O_RDONLY, then O_RDWR stateid. + */ sp = nfs4_get_inode_share(inode, O_RDONLY); if (!sp) sp = nfs4_get_inode_share(inode, O_RDWR); if (sp) - memcpy(arg.stateid,sp->so_stateid, sizeof(nfs4_stateid)); + memcpy(stateid, sp->so_stateid, sizeof(nfs4_stateid)); else - memcpy(arg.stateid, zero_stateid, sizeof(nfs4_stateid)); + memcpy(stateid, zero_stateid, sizeof(nfs4_stateid)); fattr->valid = 0; status = rpc_call_sync(server->client, &msg, flags); @@ -1061,7 +1052,6 @@ nfs4_proc_read(struct inode *inode, stru nfs_zap_caches(inode); } dprintk("NFS reply read: %d\n", status); - *eofp = res.eof; return status; } diff -puN fs/nfs/proc.c~22-read_proc fs/nfs/proc.c --- 25/fs/nfs/proc.c~22-read_proc 2003-06-26 18:38:23.000000000 -0700 +++ 25-akpm/fs/nfs/proc.c 2003-06-26 18:38:23.000000000 -0700 @@ -149,39 +149,31 @@ nfs_proc_readlink(struct inode *inode, s } static int -nfs_proc_read(struct inode *inode, struct rpc_cred *cred, - struct nfs_fattr *fattr, int flags, - unsigned int base, unsigned int count, struct page *page, - int *eofp) +nfs_proc_read(struct nfs_read_data *rdata) { - u64 offset = page_offset(page) + base; - struct nfs_readargs arg = { - .fh = NFS_FH(inode), - .offset = offset, - .count = count, - .pgbase = base, - .pages = &page - }; - struct nfs_readres res = { - .fattr = fattr, - .count = count - }; + int flags = rdata->flags; + struct inode * inode = rdata->inode; + struct nfs_fattr * fattr = rdata->res.fattr; struct rpc_message msg = { .rpc_proc = &nfs_procedures[NFSPROC_READ], - .rpc_argp = &arg, - .rpc_resp = &res, - .rpc_cred = cred + .rpc_argp = &rdata->args, + .rpc_resp = &rdata->res, + .rpc_cred = rdata->cred, }; int status; - dprintk("NFS call read %d @ %Ld\n", count, (long long)offset); + dprintk("NFS call read %d @ %Ld\n", rdata->args.count, + (long long) rdata->args.offset); fattr->valid = 0; status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags); - - if (status >= 0) + if (status >= 0) { nfs_refresh_inode(inode, fattr); + /* NFSv2 reads don't return an eof flag, so we make + * up a value here. XDR has already set eof to 0. */ + if (status < rdata->args.count) + rdata->res.eof = 1; + } dprintk("NFS reply read: %d\n", status); - *eofp = res.eof; return status; } diff -puN fs/nfs/read.c~22-read_proc fs/nfs/read.c --- 25/fs/nfs/read.c~22-read_proc 2003-06-26 18:38:23.000000000 -0700 +++ 25-akpm/fs/nfs/read.c 2003-06-26 18:38:23.000000000 -0700 @@ -69,19 +69,28 @@ void nfs_readdata_release(struct rpc_tas static int nfs_readpage_sync(struct file *file, struct inode *inode, struct page *page) { - struct rpc_cred *cred = NULL; - struct nfs_fattr fattr; - unsigned int offset = 0; unsigned int rsize = NFS_SERVER(inode)->rsize; unsigned int count = PAGE_CACHE_SIZE; int result; - int flags = IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0; - int eof; + struct nfs_read_data rdata = { + .flags = (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0), + .cred = NULL, + .inode = inode, + .args = { + .fh = NFS_FH(inode), + .pages = &page, + .pgbase = 0UL, + .count = rsize, + }, + .res = { + .fattr = &rdata.fattr, + } + }; dprintk("NFS: nfs_readpage_sync(%p)\n", page); if (file) - cred = nfs_file_cred(file); + rdata.cred = nfs_file_cred(file); /* * This works now because the socket layer never tries to DMA @@ -89,17 +98,19 @@ nfs_readpage_sync(struct file *file, str */ do { if (count < rsize) - rsize = count; + rdata.args.count = count; + rdata.res.count = rdata.args.count; + rdata.args.offset = page_offset(page) + rdata.args.pgbase; dprintk("NFS: nfs_proc_read(%s, (%s/%Ld), %Lu, %u)\n", NFS_SERVER(inode)->hostname, inode->i_sb->s_id, (long long)NFS_FILEID(inode), - (unsigned long long)offset, rsize); + (unsigned long long)rdata.args.pgbase, + rdata.args.count); lock_kernel(); - result = NFS_PROTO(inode)->read(inode, cred, &fattr, flags, - offset, rsize, page, &eof); + result = NFS_PROTO(inode)->read(&rdata); unlock_kernel(); /* @@ -111,14 +122,15 @@ nfs_readpage_sync(struct file *file, str result = -EINVAL; goto io_error; } - count -= result; - offset += result; - if (result < rsize) /* NFSv2ism */ + count -= result; + rdata.args.pgbase += result; + + if (rdata.res.eof) break; } while (count); if (count) - memclear_highpage_flush(page, offset, count); + memclear_highpage_flush(page, rdata.args.pgbase, count); SetPageUptodate(page); if (PageError(page)) ClearPageError(page); diff -puN include/linux/nfs_xdr.h~22-read_proc include/linux/nfs_xdr.h --- 25/include/linux/nfs_xdr.h~22-read_proc 2003-06-26 18:38:23.000000000 -0700 +++ 25-akpm/include/linux/nfs_xdr.h 2003-06-26 18:38:23.000000000 -0700 @@ -591,6 +591,7 @@ struct nfs4_compound { #endif /* CONFIG_NFS_V4 */ struct nfs_read_data { + int flags; struct rpc_task task; struct inode *inode; struct rpc_cred *cred; @@ -634,10 +635,7 @@ struct nfs_rpc_ops { struct nfs_fh *, struct nfs_fattr *); int (*access) (struct inode *, struct rpc_cred *, int); int (*readlink)(struct inode *, struct page *); - int (*read) (struct inode *, struct rpc_cred *, - struct nfs_fattr *, - int, unsigned int, unsigned int, - struct page *, int *eofp); + int (*read) (struct nfs_read_data *); int (*write) (struct inode *, struct rpc_cred *, struct nfs_fattr *, int, unsigned int, unsigned int, _