Commit b4687da7 authored by Chuck Lever's avatar Chuck Lever Committed by Trond Myklebust

SUNRPC: Refactor logic to NUL-terminate strings in pages

Clean up: Introduce a helper to '\0'-terminate XDR strings
that are placed in a page in the page cache.
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 38359352
...@@ -596,7 +596,6 @@ nfs_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, void *dummy) ...@@ -596,7 +596,6 @@ nfs_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, void *dummy)
struct kvec *iov = rcvbuf->head; struct kvec *iov = rcvbuf->head;
size_t hdrlen; size_t hdrlen;
u32 len, recvd; u32 len, recvd;
char *kaddr;
int status; int status;
if ((status = ntohl(*p++))) if ((status = ntohl(*p++)))
...@@ -623,10 +622,7 @@ nfs_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, void *dummy) ...@@ -623,10 +622,7 @@ nfs_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, void *dummy)
return -EIO; return -EIO;
} }
/* NULL terminate the string we got */ xdr_terminate_string(rcvbuf, len);
kaddr = (char *)kmap_atomic(rcvbuf->pages[0], KM_USER0);
kaddr[len+rcvbuf->page_base] = '\0';
kunmap_atomic(kaddr, KM_USER0);
return 0; return 0;
} }
......
...@@ -824,7 +824,6 @@ nfs3_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr) ...@@ -824,7 +824,6 @@ nfs3_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
struct kvec *iov = rcvbuf->head; struct kvec *iov = rcvbuf->head;
size_t hdrlen; size_t hdrlen;
u32 len, recvd; u32 len, recvd;
char *kaddr;
int status; int status;
status = ntohl(*p++); status = ntohl(*p++);
...@@ -857,10 +856,7 @@ nfs3_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr) ...@@ -857,10 +856,7 @@ nfs3_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
return -EIO; return -EIO;
} }
/* NULL terminate the string we got */ xdr_terminate_string(rcvbuf, len);
kaddr = (char*)kmap_atomic(rcvbuf->pages[0], KM_USER0);
kaddr[len+rcvbuf->page_base] = '\0';
kunmap_atomic(kaddr, KM_USER0);
return 0; return 0;
} }
......
...@@ -4299,7 +4299,6 @@ static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req) ...@@ -4299,7 +4299,6 @@ static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req)
size_t hdrlen; size_t hdrlen;
u32 len, recvd; u32 len, recvd;
__be32 *p; __be32 *p;
char *kaddr;
int status; int status;
status = decode_op_hdr(xdr, OP_READLINK); status = decode_op_hdr(xdr, OP_READLINK);
...@@ -4330,9 +4329,7 @@ static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req) ...@@ -4330,9 +4329,7 @@ static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req)
* and and null-terminate the text (the VFS expects * and and null-terminate the text (the VFS expects
* null-termination). * null-termination).
*/ */
kaddr = (char *)kmap_atomic(rcvbuf->pages[0], KM_USER0); xdr_terminate_string(rcvbuf, len);
kaddr[len+rcvbuf->page_base] = '\0';
kunmap_atomic(kaddr, KM_USER0);
return 0; return 0;
out_overflow: out_overflow:
print_overflow_msg(__func__, xdr); print_overflow_msg(__func__, xdr);
......
...@@ -108,6 +108,7 @@ void xdr_encode_pages(struct xdr_buf *, struct page **, unsigned int, ...@@ -108,6 +108,7 @@ void xdr_encode_pages(struct xdr_buf *, struct page **, unsigned int,
unsigned int); unsigned int);
void xdr_inline_pages(struct xdr_buf *, unsigned int, void xdr_inline_pages(struct xdr_buf *, unsigned int,
struct page **, unsigned int, unsigned int); struct page **, unsigned int, unsigned int);
void xdr_terminate_string(struct xdr_buf *, const u32);
static inline __be32 *xdr_encode_array(__be32 *p, const void *s, unsigned int len) static inline __be32 *xdr_encode_array(__be32 *p, const void *s, unsigned int len)
{ {
......
...@@ -111,6 +111,23 @@ xdr_decode_string_inplace(__be32 *p, char **sp, ...@@ -111,6 +111,23 @@ xdr_decode_string_inplace(__be32 *p, char **sp,
} }
EXPORT_SYMBOL_GPL(xdr_decode_string_inplace); EXPORT_SYMBOL_GPL(xdr_decode_string_inplace);
/**
* xdr_terminate_string - '\0'-terminate a string residing in an xdr_buf
* @buf: XDR buffer where string resides
* @len: length of string, in bytes
*
*/
void
xdr_terminate_string(struct xdr_buf *buf, const u32 len)
{
char *kaddr;
kaddr = kmap_atomic(buf->pages[0], KM_USER0);
kaddr[buf->page_base + len] = '\0';
kunmap_atomic(kaddr, KM_USER0);
}
EXPORT_SYMBOL(xdr_terminate_string);
void void
xdr_encode_pages(struct xdr_buf *xdr, struct page **pages, unsigned int base, xdr_encode_pages(struct xdr_buf *xdr, struct page **pages, unsigned int base,
unsigned int len) unsigned int 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