From f60d81b124c8f16d0b21e1266e27f7d7d9138cd8 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 8 Oct 2003 04:51:15 -0700 Subject: [PATCH] [PATCH] NFS: fix the synchronous READ/WRITE bugs - Use correct credentials in the NFSv4 synchronous read/write code. - Return correct number of read bytes in the NFSv4 synchronous read code. - SunRPC XDR fix: NFSv4 reads when caller requests a non-word aligned number of bytes was broken. --- fs/nfs/nfs4proc.c | 13 +++++++++---- fs/nfs/nfs4xdr.c | 2 ++ net/sunrpc/xdr.c | 5 +++-- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 2ef48c737a005..4bd0e37c9cd94 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -1038,7 +1038,6 @@ nfs4_proc_read(struct nfs_read_data *rdata, struct file *filp) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ], .rpc_argp = &rdata->args, .rpc_resp = &rdata->res, - .rpc_cred = rdata->cred, }; unsigned long timestamp = jiffies; int status; @@ -1053,8 +1052,11 @@ nfs4_proc_read(struct nfs_read_data *rdata, struct file *filp) struct nfs4_state *state; state = (struct nfs4_state *)filp->private_data; memcpy(&rdata->args.stateid, &state->stateid, sizeof(rdata->args.stateid)); - } else + msg.rpc_cred = state->owner->so_cred; + } else { memcpy(&rdata->args.stateid, &zero_stateid, sizeof(rdata->args.stateid)); + msg.rpc_cred = NFS_I(inode)->mm_cred; + } fattr->valid = 0; status = rpc_call_sync(server->client, &msg, flags); @@ -1079,7 +1081,6 @@ nfs4_proc_write(struct nfs_write_data *wdata, struct file *filp) .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_WRITE], .rpc_argp = &wdata->args, .rpc_resp = &wdata->res, - .rpc_cred = wdata->cred, }; int status; @@ -1093,11 +1094,15 @@ nfs4_proc_write(struct nfs_write_data *wdata, struct file *filp) struct nfs4_state *state; state = (struct nfs4_state *)filp->private_data; memcpy(&wdata->args.stateid, &state->stateid, sizeof(wdata->args.stateid)); - } else + msg.rpc_cred = state->owner->so_cred; + } else { memcpy(&wdata->args.stateid, &zero_stateid, sizeof(wdata->args.stateid)); + msg.rpc_cred = NFS_I(inode)->mm_cred; + } fattr->valid = 0; status = rpc_call_sync(server->client, &msg, rpcflags); + NFS_CACHEINV(inode); dprintk("NFS reply write: %d\n", status); return status; } diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index f80cea7b29231..1ff99644aa498 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -2323,6 +2323,8 @@ nfs4_xdr_dec_read(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_readres *res) status = decode_read_getattr(&xdr, res->fattr); if (!status) status = -nfs_stat_to_errno(hdr.status); + if (!status) + status = res->count; out: return status; } diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index f5411631c6b5e..078dad8a90e5c 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c @@ -715,6 +715,7 @@ xdr_read_pages(struct xdr_stream *xdr, unsigned int len) struct xdr_buf *buf = xdr->buf; struct iovec *iov; ssize_t shift; + int padding; /* Realign pages to current pointer position */ iov = buf->head; @@ -723,10 +724,10 @@ xdr_read_pages(struct xdr_stream *xdr, unsigned int len) xdr_shrink_bufhead(buf, shift); /* Truncate page data and move it into the tail */ - len = XDR_QUADLEN(len) << 2; if (buf->page_len > len) xdr_shrink_pagelen(buf, buf->page_len - len); + padding = (XDR_QUADLEN(len) << 2) - len; xdr->iov = iov = buf->tail; - xdr->p = (uint32_t *)iov->iov_base; + xdr->p = (uint32_t *)((char *)iov->iov_base + padding); xdr->end = (uint32_t *)((char *)iov->iov_base + iov->iov_len); } -- 2.53.0