Commit 47462c3c authored by Trond Myklebust's avatar Trond Myklebust

Make NFSv4 'read' code use the cached stateid if it exists.

parent be6c1a46
...@@ -1013,6 +1013,7 @@ nfs4_proc_read(struct inode *inode, struct rpc_cred *cred, ...@@ -1013,6 +1013,7 @@ nfs4_proc_read(struct inode *inode, struct rpc_cred *cred,
struct page *page, int *eofp) struct page *page, int *eofp)
{ {
struct nfs_server *server = NFS_SERVER(inode); struct nfs_server *server = NFS_SERVER(inode);
struct nfs4_shareowner *sp;
uint64_t offset = page_offset(page) + base; uint64_t offset = page_offset(page) + base;
struct nfs_readargs arg = { struct nfs_readargs arg = {
.fh = NFS_FH(inode), .fh = NFS_FH(inode),
...@@ -1035,6 +1036,17 @@ nfs4_proc_read(struct inode *inode, struct rpc_cred *cred, ...@@ -1035,6 +1036,17 @@ nfs4_proc_read(struct inode *inode, struct rpc_cred *cred,
int status; int status;
dprintk("NFS call read %d @ %Ld\n", count, (long long)offset); dprintk("NFS call read %d @ %Ld\n", count, (long long)offset);
/*
* 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));
else
memcpy(arg.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);
if (!status) { if (!status) {
...@@ -1441,6 +1453,7 @@ nfs4_proc_read_setup(struct nfs_read_data *data, unsigned int count) ...@@ -1441,6 +1453,7 @@ nfs4_proc_read_setup(struct nfs_read_data *data, unsigned int count)
}; };
struct inode *inode = data->inode; struct inode *inode = data->inode;
struct nfs_page *req = nfs_list_entry(data->pages.next); struct nfs_page *req = nfs_list_entry(data->pages.next);
struct nfs4_shareowner *sp;
int flags; int flags;
data->args.fh = NFS_FH(inode); data->args.fh = NFS_FH(inode);
...@@ -1453,6 +1466,19 @@ nfs4_proc_read_setup(struct nfs_read_data *data, unsigned int count) ...@@ -1453,6 +1466,19 @@ nfs4_proc_read_setup(struct nfs_read_data *data, unsigned int count)
data->res.eof = 0; data->res.eof = 0;
data->timestamp = jiffies; data->timestamp = jiffies;
if(req->wb_file) {
unsigned int oflags = req->wb_file->f_flags;
sp = nfs4_get_inode_share(inode, oflags);
} else {
sp = nfs4_get_inode_share(inode, O_RDONLY);
if (!sp)
sp = nfs4_get_inode_share(inode, O_RDWR);
}
if (sp)
memcpy(data->args.stateid,sp->so_stateid, sizeof(nfs4_stateid));
else
memcpy(data->args.stateid, zero_stateid, sizeof(nfs4_stateid));
/* N.B. Do we need to test? Never called for swapfile inode */ /* N.B. Do we need to test? Never called for swapfile inode */
flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0); flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0);
......
...@@ -654,10 +654,7 @@ encode_read(struct xdr_stream *xdr, struct nfs_readargs *args) ...@@ -654,10 +654,7 @@ encode_read(struct xdr_stream *xdr, struct nfs_readargs *args)
RESERVE_SPACE(32); RESERVE_SPACE(32);
WRITE32(OP_READ); WRITE32(OP_READ);
WRITE32(0); /* all-zero stateid! */ WRITEMEM(args->stateid, sizeof(nfs4_stateid));
WRITE32(0);
WRITE32(0);
WRITE32(0);
WRITE64(args->offset); WRITE64(args->offset);
WRITE32(args->count); WRITE32(args->count);
......
...@@ -157,6 +157,7 @@ struct nfs_closeres { ...@@ -157,6 +157,7 @@ struct nfs_closeres {
struct nfs_readargs { struct nfs_readargs {
struct nfs_fh * fh; struct nfs_fh * fh;
nfs4_stateid stateid;
__u64 offset; __u64 offset;
__u32 count; __u32 count;
unsigned int pgbase; unsigned int pgbase;
......
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