Commit 0b6cfeaa authored by Trond Myklebust's avatar Trond Myklebust

Simplify the synchronous NFS read call interface by

passing a pointer to a filled nfs_read_data structure
(the same struct used by the asynchronous function calls)
parent 469e08df
...@@ -225,38 +225,26 @@ nfs3_proc_readlink(struct inode *inode, struct page *page) ...@@ -225,38 +225,26 @@ nfs3_proc_readlink(struct inode *inode, struct page *page)
} }
static int static int
nfs3_proc_read(struct inode *inode, struct rpc_cred *cred, nfs3_proc_read(struct nfs_read_data *rdata)
struct nfs_fattr *fattr, int flags,
unsigned int base, unsigned int count, struct page *page,
int *eofp)
{ {
u64 offset = page_offset(page) + base; int flags = rdata->flags;
struct nfs_readargs arg = { struct inode * inode = rdata->inode;
.fh = NFS_FH(inode), struct nfs_fattr * fattr = rdata->res.fattr;
.offset = offset,
.count = count,
.pgbase = base,
.pages = &page
};
struct nfs_readres res = {
.fattr = fattr,
.count = count,
};
struct rpc_message msg = { struct rpc_message msg = {
.rpc_proc = &nfs3_procedures[NFS3PROC_READ], .rpc_proc = &nfs3_procedures[NFS3PROC_READ],
.rpc_argp = &arg, .rpc_argp = &rdata->args,
.rpc_resp = &res, .rpc_resp = &rdata->res,
.rpc_cred = cred .rpc_cred = rdata->cred,
}; };
int status; 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; fattr->valid = 0;
status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags); status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
if (status >= 0) if (status >= 0)
nfs_refresh_inode(inode, fattr); nfs_refresh_inode(inode, fattr);
dprintk("NFS reply read: %d\n", status); dprintk("NFS reply read: %d\n", status);
*eofp = res.eof;
return status; return status;
} }
......
...@@ -1017,35 +1017,26 @@ nfs4_proc_readlink(struct inode *inode, struct page *page) ...@@ -1017,35 +1017,26 @@ nfs4_proc_readlink(struct inode *inode, struct page *page)
} }
static int static int
nfs4_proc_read(struct inode *inode, struct rpc_cred *cred, nfs4_proc_read(struct nfs_read_data *rdata)
struct nfs_fattr *fattr, int flags,
unsigned int base, unsigned int count,
struct page *page, int *eofp)
{ {
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 nfs_server *server = NFS_SERVER(inode);
struct nfs4_state_owner *sp; struct nfs4_state_owner *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 = { struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ], .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ],
.rpc_argp = &arg, .rpc_argp = &rdata->args,
.rpc_resp = &res, .rpc_resp = &rdata->res,
.rpc_cred = cred, .rpc_cred = rdata->cred,
}; };
unsigned long timestamp = jiffies; unsigned long timestamp = jiffies;
int status; 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.
*/ */
...@@ -1053,9 +1044,9 @@ nfs4_proc_read(struct inode *inode, struct rpc_cred *cred, ...@@ -1053,9 +1044,9 @@ nfs4_proc_read(struct inode *inode, struct rpc_cred *cred,
if (!sp) if (!sp)
sp = nfs4_get_inode_share(inode, O_RDWR); sp = nfs4_get_inode_share(inode, O_RDWR);
if (sp) if (sp)
memcpy(arg.stateid,sp->so_stateid, sizeof(nfs4_stateid)); memcpy(stateid, sp->so_stateid, sizeof(nfs4_stateid));
else else
memcpy(arg.stateid, zero_stateid, sizeof(nfs4_stateid)); memcpy(stateid, zero_stateid, sizeof(nfs4_stateid));
fattr->valid = 0; fattr->valid = 0;
status = rpc_call_sync(server->client, &msg, flags); status = rpc_call_sync(server->client, &msg, flags);
...@@ -1066,7 +1057,6 @@ nfs4_proc_read(struct inode *inode, struct rpc_cred *cred, ...@@ -1066,7 +1057,6 @@ nfs4_proc_read(struct inode *inode, struct rpc_cred *cred,
nfs_zap_caches(inode); nfs_zap_caches(inode);
} }
dprintk("NFS reply read: %d\n", status); dprintk("NFS reply read: %d\n", status);
*eofp = res.eof;
return status; return status;
} }
......
...@@ -149,39 +149,27 @@ nfs_proc_readlink(struct inode *inode, struct page *page) ...@@ -149,39 +149,27 @@ nfs_proc_readlink(struct inode *inode, struct page *page)
} }
static int static int
nfs_proc_read(struct inode *inode, struct rpc_cred *cred, nfs_proc_read(struct nfs_read_data *rdata)
struct nfs_fattr *fattr, int flags,
unsigned int base, unsigned int count, struct page *page,
int *eofp)
{ {
u64 offset = page_offset(page) + base; int flags = rdata->flags;
struct nfs_readargs arg = { struct inode * inode = rdata->inode;
.fh = NFS_FH(inode), struct nfs_fattr * fattr = rdata->res.fattr;
.offset = offset,
.count = count,
.pgbase = base,
.pages = &page
};
struct nfs_readres res = {
.fattr = fattr,
.count = count
};
struct rpc_message msg = { struct rpc_message msg = {
.rpc_proc = &nfs_procedures[NFSPROC_READ], .rpc_proc = &nfs_procedures[NFSPROC_READ],
.rpc_argp = &arg, .rpc_argp = &rdata->args,
.rpc_resp = &res, .rpc_resp = &rdata->res,
.rpc_cred = cred .rpc_cred = rdata->cred,
}; };
int status; 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; fattr->valid = 0;
status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags); status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
if (status >= 0) if (status >= 0)
nfs_refresh_inode(inode, fattr); nfs_refresh_inode(inode, fattr);
dprintk("NFS reply read: %d\n", status); dprintk("NFS reply read: %d\n", status);
*eofp = res.eof;
return status; return status;
} }
......
...@@ -69,19 +69,28 @@ void nfs_readdata_release(struct rpc_task *task) ...@@ -69,19 +69,28 @@ void nfs_readdata_release(struct rpc_task *task)
static int static int
nfs_readpage_sync(struct file *file, struct inode *inode, struct page *page) 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 rsize = NFS_SERVER(inode)->rsize;
unsigned int count = PAGE_CACHE_SIZE; unsigned int count = PAGE_CACHE_SIZE;
int result; int result;
int flags = IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0; struct nfs_read_data rdata = {
int eof; .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); dprintk("NFS: nfs_readpage_sync(%p)\n", page);
if (file) if (file)
cred = nfs_file_cred(file); rdata.cred = nfs_file_cred(file);
/* /*
* This works now because the socket layer never tries to DMA * This works now because the socket layer never tries to DMA
...@@ -89,17 +98,19 @@ nfs_readpage_sync(struct file *file, struct inode *inode, struct page *page) ...@@ -89,17 +98,19 @@ nfs_readpage_sync(struct file *file, struct inode *inode, struct page *page)
*/ */
do { do {
if (count < rsize) 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", dprintk("NFS: nfs_proc_read(%s, (%s/%Ld), %Lu, %u)\n",
NFS_SERVER(inode)->hostname, NFS_SERVER(inode)->hostname,
inode->i_sb->s_id, inode->i_sb->s_id,
(long long)NFS_FILEID(inode), (long long)NFS_FILEID(inode),
(unsigned long long)offset, rsize); (unsigned long long)rdata.args.pgbase,
rdata.args.count);
lock_kernel(); lock_kernel();
result = NFS_PROTO(inode)->read(inode, cred, &fattr, flags, result = NFS_PROTO(inode)->read(&rdata);
offset, rsize, page, &eof);
unlock_kernel(); unlock_kernel();
/* /*
...@@ -112,13 +123,13 @@ nfs_readpage_sync(struct file *file, struct inode *inode, struct page *page) ...@@ -112,13 +123,13 @@ nfs_readpage_sync(struct file *file, struct inode *inode, struct page *page)
goto io_error; goto io_error;
} }
count -= result; count -= result;
offset += result; rdata.args.pgbase += result;
if (result < rsize) /* NFSv2ism */ if (result < rdata.args.count) /* NFSv2ism */
break; break;
} while (count); } while (count);
if (count) if (count)
memclear_highpage_flush(page, offset, count); memclear_highpage_flush(page, rdata.args.pgbase, count);
SetPageUptodate(page); SetPageUptodate(page);
if (PageError(page)) if (PageError(page))
ClearPageError(page); ClearPageError(page);
......
...@@ -590,6 +590,7 @@ struct nfs4_compound { ...@@ -590,6 +590,7 @@ struct nfs4_compound {
#endif /* CONFIG_NFS_V4 */ #endif /* CONFIG_NFS_V4 */
struct nfs_read_data { struct nfs_read_data {
int flags;
struct rpc_task task; struct rpc_task task;
struct inode *inode; struct inode *inode;
struct rpc_cred *cred; struct rpc_cred *cred;
...@@ -633,10 +634,7 @@ struct nfs_rpc_ops { ...@@ -633,10 +634,7 @@ struct nfs_rpc_ops {
struct nfs_fh *, struct nfs_fattr *); struct nfs_fh *, struct nfs_fattr *);
int (*access) (struct inode *, struct rpc_cred *, int); int (*access) (struct inode *, struct rpc_cred *, int);
int (*readlink)(struct inode *, struct page *); int (*readlink)(struct inode *, struct page *);
int (*read) (struct inode *, struct rpc_cred *, int (*read) (struct nfs_read_data *);
struct nfs_fattr *,
int, unsigned int, unsigned int,
struct page *, int *eofp);
int (*write) (struct inode *, struct rpc_cred *, int (*write) (struct inode *, struct rpc_cred *,
struct nfs_fattr *, struct nfs_fattr *,
int, unsigned int, unsigned int, int, unsigned int, unsigned int,
......
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