SUNRPC/NFSD: Implement xdr_reserve_space_vec()
Reserving space for a large READ payload requires special handling when reserving space in the xdr buffer pages. One problem we can have is use of the scratch buffer, which is used to get a pointer to a contiguous region of data up to PAGE_SIZE. When using the scratch buffer, calls to xdr_commit_encode() shift the data to it's proper alignment in the xdr buffer. If we've reserved several pages in a vector, then this could potentially invalidate earlier pointers and result in incorrect READ data being sent to the client. I get around this by looking at the amount of space left in the current page, and never reserve more than that for each entry in the read vector. This lets us place data directly where it needs to go in the buffer pages. Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
This commit is contained in:

committed by
J. Bruce Fields

parent
3caf91757c
commit
403217f304
@@ -234,6 +234,8 @@ typedef int (*kxdrdproc_t)(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
|
||||
extern void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf,
|
||||
__be32 *p, struct rpc_rqst *rqst);
|
||||
extern __be32 *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes);
|
||||
extern int xdr_reserve_space_vec(struct xdr_stream *xdr, struct kvec *vec,
|
||||
size_t nbytes);
|
||||
extern void xdr_commit_encode(struct xdr_stream *xdr);
|
||||
extern void xdr_truncate_encode(struct xdr_stream *xdr, size_t len);
|
||||
extern int xdr_restrict_buflen(struct xdr_stream *xdr, int newbuflen);
|
||||
|
Reference in New Issue
Block a user