summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@fys.uio.no>2003-04-08 04:31:06 +0200
committerTrond Myklebust <trond.myklebust@fys.uio.no>2003-04-08 04:31:06 +0200
commit47462c3c70719e77c7431dfd8ac0a722bc026087 (patch)
tree4dc952eda3363325d9ae152e6661bddbfb860767
parentbe6c1a46a0609afffd8926a2f533158a8481689c (diff)
Make NFSv4 'read' code use the cached stateid if it exists.
-rw-r--r--fs/nfs/nfs4proc.c26
-rw-r--r--fs/nfs/nfs4xdr.c5
-rw-r--r--include/linux/nfs_xdr.h1
3 files changed, 28 insertions, 4 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index f302bd233380..966cdddf2940 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -1013,6 +1013,7 @@ nfs4_proc_read(struct inode *inode, struct rpc_cred *cred,
struct page *page, int *eofp)
{
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),
@@ -1035,6 +1036,17 @@ nfs4_proc_read(struct inode *inode, struct rpc_cred *cred,
int status;
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;
status = rpc_call_sync(server->client, &msg, flags);
if (!status) {
@@ -1441,6 +1453,7 @@ nfs4_proc_read_setup(struct nfs_read_data *data, unsigned int count)
};
struct inode *inode = data->inode;
struct nfs_page *req = nfs_list_entry(data->pages.next);
+ struct nfs4_shareowner *sp;
int flags;
data->args.fh = NFS_FH(inode);
@@ -1453,6 +1466,19 @@ nfs4_proc_read_setup(struct nfs_read_data *data, unsigned int count)
data->res.eof = 0;
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 */
flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0);
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index ef6e32ce91be..78eca301cf93 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -654,10 +654,7 @@ encode_read(struct xdr_stream *xdr, struct nfs_readargs *args)
RESERVE_SPACE(32);
WRITE32(OP_READ);
- WRITE32(0); /* all-zero stateid! */
- WRITE32(0);
- WRITE32(0);
- WRITE32(0);
+ WRITEMEM(args->stateid, sizeof(nfs4_stateid));
WRITE64(args->offset);
WRITE32(args->count);
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 7c37e245e732..515168676c24 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -157,6 +157,7 @@ struct nfs_closeres {
struct nfs_readargs {
struct nfs_fh * fh;
+ nfs4_stateid stateid;
__u64 offset;
__u32 count;
unsigned int pgbase;