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)
}
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;
}
......
......@@ -1017,35 +1017,26 @@ nfs4_proc_readlink(struct inode *inode, struct page *page)
}
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_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 = {
.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.
*/
......@@ -1053,9 +1044,9 @@ nfs4_proc_read(struct inode *inode, struct rpc_cred *cred,
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);
......@@ -1066,7 +1057,6 @@ nfs4_proc_read(struct inode *inode, struct rpc_cred *cred,
nfs_zap_caches(inode);
}
dprintk("NFS reply read: %d\n", status);
*eofp = res.eof;
return status;
}
......
......@@ -149,39 +149,27 @@ nfs_proc_readlink(struct inode *inode, struct page *page)
}
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)
nfs_refresh_inode(inode, fattr);
dprintk("NFS reply read: %d\n", status);
*eofp = res.eof;
return status;
}
......
......@@ -69,19 +69,28 @@ void nfs_readdata_release(struct rpc_task *task)
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, struct inode *inode, struct page *page)
*/
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();
/*
......@@ -112,13 +123,13 @@ nfs_readpage_sync(struct file *file, struct inode *inode, struct page *page)
goto io_error;
}
count -= result;
offset += result;
if (result < rsize) /* NFSv2ism */
rdata.args.pgbase += result;
if (result < rdata.args.count) /* NFSv2ism */
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);
......
......@@ -590,6 +590,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;
......@@ -633,10 +634,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,
......
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