Commit f60d81b1 authored by Trond Myklebust's avatar Trond Myklebust Committed by Linus Torvalds

[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.
parent cc7d1ffd
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -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);
}
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