Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>

authored by

Chuck Lever and committed by
Trond Myklebust
b4687da7 38359352

+21 -14
+1 -5
fs/nfs/nfs2xdr.c
··· 596 596 struct kvec *iov = rcvbuf->head; 597 597 size_t hdrlen; 598 598 u32 len, recvd; 599 - char *kaddr; 600 599 int status; 601 600 602 601 if ((status = ntohl(*p++))) ··· 622 623 return -EIO; 623 624 } 624 625 625 - /* NULL terminate the string we got */ 626 - kaddr = (char *)kmap_atomic(rcvbuf->pages[0], KM_USER0); 627 - kaddr[len+rcvbuf->page_base] = '\0'; 628 - kunmap_atomic(kaddr, KM_USER0); 626 + xdr_terminate_string(rcvbuf, len); 629 627 return 0; 630 628 } 631 629
+1 -5
fs/nfs/nfs3xdr.c
··· 824 824 struct kvec *iov = rcvbuf->head; 825 825 size_t hdrlen; 826 826 u32 len, recvd; 827 - char *kaddr; 828 827 int status; 829 828 830 829 status = ntohl(*p++); ··· 856 857 return -EIO; 857 858 } 858 859 859 - /* NULL terminate the string we got */ 860 - kaddr = (char*)kmap_atomic(rcvbuf->pages[0], KM_USER0); 861 - kaddr[len+rcvbuf->page_base] = '\0'; 862 - kunmap_atomic(kaddr, KM_USER0); 860 + xdr_terminate_string(rcvbuf, len); 863 861 return 0; 864 862 } 865 863
+1 -4
fs/nfs/nfs4xdr.c
··· 4299 4299 size_t hdrlen; 4300 4300 u32 len, recvd; 4301 4301 __be32 *p; 4302 - char *kaddr; 4303 4302 int status; 4304 4303 4305 4304 status = decode_op_hdr(xdr, OP_READLINK); ··· 4329 4330 * and and null-terminate the text (the VFS expects 4330 4331 * null-termination). 4331 4332 */ 4332 - kaddr = (char *)kmap_atomic(rcvbuf->pages[0], KM_USER0); 4333 - kaddr[len+rcvbuf->page_base] = '\0'; 4334 - kunmap_atomic(kaddr, KM_USER0); 4333 + xdr_terminate_string(rcvbuf, len); 4335 4334 return 0; 4336 4335 out_overflow: 4337 4336 print_overflow_msg(__func__, xdr);
+1
include/linux/sunrpc/xdr.h
··· 108 108 unsigned int); 109 109 void xdr_inline_pages(struct xdr_buf *, unsigned int, 110 110 struct page **, unsigned int, unsigned int); 111 + void xdr_terminate_string(struct xdr_buf *, const u32); 111 112 112 113 static inline __be32 *xdr_encode_array(__be32 *p, const void *s, unsigned int len) 113 114 {
+17
net/sunrpc/xdr.c
··· 111 111 } 112 112 EXPORT_SYMBOL_GPL(xdr_decode_string_inplace); 113 113 114 + /** 115 + * xdr_terminate_string - '\0'-terminate a string residing in an xdr_buf 116 + * @buf: XDR buffer where string resides 117 + * @len: length of string, in bytes 118 + * 119 + */ 120 + void 121 + xdr_terminate_string(struct xdr_buf *buf, const u32 len) 122 + { 123 + char *kaddr; 124 + 125 + kaddr = kmap_atomic(buf->pages[0], KM_USER0); 126 + kaddr[buf->page_base + len] = '\0'; 127 + kunmap_atomic(kaddr, KM_USER0); 128 + } 129 + EXPORT_SYMBOL(xdr_terminate_string); 130 + 114 131 void 115 132 xdr_encode_pages(struct xdr_buf *xdr, struct page **pages, unsigned int base, 116 133 unsigned int len)