diff options
author | J. Bruce Fields <bfields@redhat.com> | 2014-02-25 17:21:08 -0500 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2014-03-28 21:24:49 -0400 |
commit | de4aee2e0a376fb272f44139150115a6dec1da95 (patch) | |
tree | 6eb394e6792d24331afde16e4704ce558b1882e1 /net | |
parent | 3f42d2c428c724212c5f4249daea97e254eb0546 (diff) |
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>
Diffstat (limited to 'net')
-rw-r--r-- | net/sunrpc/xdr.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index 1504bb11e4f3..dd97ba3c4456 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c | |||
@@ -833,8 +833,20 @@ xdr_buf_from_iov(struct kvec *iov, struct xdr_buf *buf) | |||
833 | } | 833 | } |
834 | EXPORT_SYMBOL_GPL(xdr_buf_from_iov); | 834 | EXPORT_SYMBOL_GPL(xdr_buf_from_iov); |
835 | 835 | ||
836 | /* Sets subbuf to the portion of buf of length len beginning base bytes | 836 | /** |
837 | * from the start of buf. Returns -1 if base of length are out of bounds. */ | 837 | * xdr_buf_subsegment - set subbuf to a portion of buf |
838 | * @buf: an xdr buffer | ||
839 | * @subbuf: the result buffer | ||
840 | * @base: beginning of range in bytes | ||
841 | * @len: length of range in bytes | ||
842 | * | ||
843 | * sets @subbuf to an xdr buffer representing the portion of @buf of | ||
844 | * length @len starting at offset @base. | ||
845 | * | ||
846 | * @buf and @subbuf may be pointers to the same struct xdr_buf. | ||
847 | * | ||
848 | * Returns -1 if base of length are out of bounds. | ||
849 | */ | ||
838 | int | 850 | int |
839 | xdr_buf_subsegment(struct xdr_buf *buf, struct xdr_buf *subbuf, | 851 | xdr_buf_subsegment(struct xdr_buf *buf, struct xdr_buf *subbuf, |
840 | unsigned int base, unsigned int len) | 852 | unsigned int base, unsigned int len) |
@@ -847,9 +859,8 @@ xdr_buf_subsegment(struct xdr_buf *buf, struct xdr_buf *subbuf, | |||
847 | len -= subbuf->head[0].iov_len; | 859 | len -= subbuf->head[0].iov_len; |
848 | base = 0; | 860 | base = 0; |
849 | } else { | 861 | } else { |
850 | subbuf->head[0].iov_base = NULL; | ||
851 | subbuf->head[0].iov_len = 0; | ||
852 | base -= buf->head[0].iov_len; | 862 | base -= buf->head[0].iov_len; |
863 | subbuf->head[0].iov_len = 0; | ||
853 | } | 864 | } |
854 | 865 | ||
855 | if (base < buf->page_len) { | 866 | if (base < buf->page_len) { |
@@ -871,9 +882,8 @@ xdr_buf_subsegment(struct xdr_buf *buf, struct xdr_buf *subbuf, | |||
871 | len -= subbuf->tail[0].iov_len; | 882 | len -= subbuf->tail[0].iov_len; |
872 | base = 0; | 883 | base = 0; |
873 | } else { | 884 | } else { |
874 | subbuf->tail[0].iov_base = NULL; | ||
875 | subbuf->tail[0].iov_len = 0; | ||
876 | base -= buf->tail[0].iov_len; | 885 | base -= buf->tail[0].iov_len; |
886 | subbuf->tail[0].iov_len = 0; | ||
877 | } | 887 | } |
878 | 888 | ||
879 | if (base || len) | 889 | if (base || len) |