rpc: Allow xdr_buf_subsegment to operate in-place

Allow

	xdr_buf_subsegment(&buf, &buf, base, len)

to modify an xdr_buf in-place.

Also, none of the callers need the iov_base of head or tail to be zeroed
out.

Also add documentation.

(As it turns out, I'm not really using this new guarantee, but it seems
a simple way to make this function a bit more robust.)

Signed-off-by: J. Bruce Fields <bfields@redhat.com>
This commit is contained in:
J. Bruce Fields 2014-02-25 17:21:08 -05:00
parent 3f42d2c428
commit de4aee2e0a

View File

@ -833,8 +833,20 @@ xdr_buf_from_iov(struct kvec *iov, struct xdr_buf *buf)
} }
EXPORT_SYMBOL_GPL(xdr_buf_from_iov); EXPORT_SYMBOL_GPL(xdr_buf_from_iov);
/* Sets subbuf to the portion of buf of length len beginning base bytes /**
* from the start of buf. Returns -1 if base of length are out of bounds. */ * xdr_buf_subsegment - set subbuf to a portion of buf
* @buf: an xdr buffer
* @subbuf: the result buffer
* @base: beginning of range in bytes
* @len: length of range in bytes
*
* sets @subbuf to an xdr buffer representing the portion of @buf of
* length @len starting at offset @base.
*
* @buf and @subbuf may be pointers to the same struct xdr_buf.
*
* Returns -1 if base of length are out of bounds.
*/
int int
xdr_buf_subsegment(struct xdr_buf *buf, struct xdr_buf *subbuf, xdr_buf_subsegment(struct xdr_buf *buf, struct xdr_buf *subbuf,
unsigned int base, unsigned int len) unsigned int base, unsigned int len)
@ -847,9 +859,8 @@ xdr_buf_subsegment(struct xdr_buf *buf, struct xdr_buf *subbuf,
len -= subbuf->head[0].iov_len; len -= subbuf->head[0].iov_len;
base = 0; base = 0;
} else { } else {
subbuf->head[0].iov_base = NULL;
subbuf->head[0].iov_len = 0;
base -= buf->head[0].iov_len; base -= buf->head[0].iov_len;
subbuf->head[0].iov_len = 0;
} }
if (base < buf->page_len) { if (base < buf->page_len) {
@ -871,9 +882,8 @@ xdr_buf_subsegment(struct xdr_buf *buf, struct xdr_buf *subbuf,
len -= subbuf->tail[0].iov_len; len -= subbuf->tail[0].iov_len;
base = 0; base = 0;
} else { } else {
subbuf->tail[0].iov_base = NULL;
subbuf->tail[0].iov_len = 0;
base -= buf->tail[0].iov_len; base -= buf->tail[0].iov_len;
subbuf->tail[0].iov_len = 0;
} }
if (base || len) if (base || len)