diff -u --recursive --new-file linux-2.5.59-04-nfsv4-setattrstate/fs/nfs/nfs3proc.c linux-2.5.59-05-nfsv4-readstate/fs/nfs/nfs3proc.c --- linux-2.5.59-04-nfsv4-setattrstate/fs/nfs/nfs3proc.c 2003-01-17 14:15:51.000000000 +0100 +++ linux-2.5.59-05-nfsv4-readstate/fs/nfs/nfs3proc.c 2003-01-17 14:16:56.000000000 +0100 @@ -226,7 +226,7 @@ static int nfs3_proc_read(struct inode *inode, struct rpc_cred *cred, - struct nfs_fattr *fattr, int flags, + struct nfs_fattr *fattr, int flags, unsigned int oflags, unsigned int base, unsigned int count, struct page *page, int *eofp) { diff -u --recursive --new-file linux-2.5.59-04-nfsv4-setattrstate/fs/nfs/nfs4proc.c linux-2.5.59-05-nfsv4-readstate/fs/nfs/nfs4proc.c --- linux-2.5.59-04-nfsv4-setattrstate/fs/nfs/nfs4proc.c 2003-01-17 14:16:31.000000000 +0100 +++ linux-2.5.59-05-nfsv4-readstate/fs/nfs/nfs4proc.c 2003-01-17 14:16:56.000000000 +0100 @@ -1011,11 +1011,12 @@ static int nfs4_proc_read(struct inode *inode, struct rpc_cred *cred, - struct nfs_fattr *fattr, int flags, + struct nfs_fattr *fattr, int flags, unsigned int oflags, unsigned int base, unsigned int count, 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), @@ -1038,6 +1039,21 @@ int status; dprintk("NFS call read %d @ %Ld\n", count, (long long)offset); + /* + * If oflags are not set, try first to use O_RDONLY, then + * O_RDWR stateid. + */ + if (oflags) + sp = nfs4_get_inode_share(inode, oflags); + else + sp = nfs4_get_inode_share(inode, + NFS4_SHARE_ACCESS_READ | NFS4_SHARE_ACCESS_BOTH); + + 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) { @@ -1444,6 +1460,7 @@ }; 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); @@ -1456,6 +1473,21 @@ data->res.eof = 0; data->timestamp = jiffies; + if(req->wb_file) { + unsigned int oflags = req->wb_file->f_flags; + + if ((oflags & 3) != 3) + oflags++; + sp = nfs4_get_inode_share(inode, oflags); + } else + sp = nfs4_get_inode_share(inode, + NFS4_SHARE_ACCESS_BOTH | NFS4_SHARE_ACCESS_WRITE); + + 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 -u --recursive --new-file linux-2.5.59-04-nfsv4-setattrstate/fs/nfs/nfs4xdr.c linux-2.5.59-05-nfsv4-readstate/fs/nfs/nfs4xdr.c --- linux-2.5.59-04-nfsv4-setattrstate/fs/nfs/nfs4xdr.c 2003-01-17 14:16:31.000000000 +0100 +++ linux-2.5.59-05-nfsv4-readstate/fs/nfs/nfs4xdr.c 2003-01-17 14:16:56.000000000 +0100 @@ -651,10 +651,7 @@ 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 -u --recursive --new-file linux-2.5.59-04-nfsv4-setattrstate/fs/nfs/proc.c linux-2.5.59-05-nfsv4-readstate/fs/nfs/proc.c --- linux-2.5.59-04-nfsv4-setattrstate/fs/nfs/proc.c 2003-01-17 14:15:51.000000000 +0100 +++ linux-2.5.59-05-nfsv4-readstate/fs/nfs/proc.c 2003-01-17 14:16:56.000000000 +0100 @@ -150,7 +150,7 @@ static int nfs_proc_read(struct inode *inode, struct rpc_cred *cred, - struct nfs_fattr *fattr, int flags, + struct nfs_fattr *fattr, int flags, unsigned int oflags, unsigned int base, unsigned int count, struct page *page, int *eofp) { diff -u --recursive --new-file linux-2.5.59-04-nfsv4-setattrstate/fs/nfs/read.c linux-2.5.59-05-nfsv4-readstate/fs/nfs/read.c --- linux-2.5.59-04-nfsv4-setattrstate/fs/nfs/read.c 2003-01-08 12:30:45.000000000 +0100 +++ linux-2.5.59-05-nfsv4-readstate/fs/nfs/read.c 2003-01-17 14:16:56.000000000 +0100 @@ -76,13 +76,17 @@ unsigned int count = PAGE_CACHE_SIZE; int result; int flags = IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0; + unsigned int oflags = 0; int eof; dprintk("NFS: nfs_readpage_sync(%p)\n", page); - if (file) + if (file) { cred = nfs_file_cred(file); - + oflags = file->f_flags; + if ((oflags & 3) != 3) + oflags++; + } /* * This works now because the socket layer never tries to DMA * into this buffer directly. @@ -99,7 +103,7 @@ lock_kernel(); result = NFS_PROTO(inode)->read(inode, cred, &fattr, flags, - offset, rsize, page, &eof); + oflags, offset, rsize, page, &eof); unlock_kernel(); /* diff -u --recursive --new-file linux-2.5.59-04-nfsv4-setattrstate/include/linux/nfs_xdr.h linux-2.5.59-05-nfsv4-readstate/include/linux/nfs_xdr.h --- linux-2.5.59-04-nfsv4-setattrstate/include/linux/nfs_xdr.h 2003-01-17 14:16:31.000000000 +0100 +++ linux-2.5.59-05-nfsv4-readstate/include/linux/nfs_xdr.h 2003-01-17 14:16:56.000000000 +0100 @@ -157,6 +157,7 @@ struct nfs_readargs { struct nfs_fh * fh; + nfs4_stateid stateid; __u64 offset; __u32 count; unsigned int pgbase; @@ -630,7 +631,7 @@ int (*readlink)(struct inode *, struct page *); int (*read) (struct inode *, struct rpc_cred *, struct nfs_fattr *, - int, unsigned int, unsigned int, + int, unsigned int, unsigned int, unsigned int, struct page *, int *eofp); int (*write) (struct inode *, struct rpc_cred *, struct nfs_fattr *,