aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/xprtsock.c
diff options
context:
space:
mode:
authorTrond Myklebust <trondmy@gmail.com>2019-01-03 09:04:45 -0500
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2019-01-08 12:44:51 -0500
commit6a829eb8619fbdde6d7d627ad582fe119805f39d (patch)
treeed35a8545101f3c88de6142f16455e3603a66624 /net/sunrpc/xprtsock.c
parent6e17f58c486d9554341f70aa5b63b8fbed07b3fa (diff)
SUNRPC: Fix TCP receive code on archs with flush_dcache_page()
After receiving data into the page cache, we need to call flush_dcache_page() for the architectures that define it. Fixes: 277e4ab7d530b ("SUNRPC: Simplify TCP receive code by switching...") Reported-by: Geert Uytterhoeven <geert@linux-m68k.org> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Cc: stable@vger.kernel.org # v4.20 Tested-by: Geert Uytterhoeven <geert@linux-m68k.org> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Diffstat (limited to 'net/sunrpc/xprtsock.c')
-rw-r--r--net/sunrpc/xprtsock.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 13559e6a460b..7754aa3e434f 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -48,6 +48,7 @@
48#include <net/udp.h> 48#include <net/udp.h>
49#include <net/tcp.h> 49#include <net/tcp.h>
50#include <linux/bvec.h> 50#include <linux/bvec.h>
51#include <linux/highmem.h>
51#include <linux/uio.h> 52#include <linux/uio.h>
52 53
53#include <trace/events/sunrpc.h> 54#include <trace/events/sunrpc.h>
@@ -376,6 +377,26 @@ xs_read_discard(struct socket *sock, struct msghdr *msg, int flags,
376 return sock_recvmsg(sock, msg, flags); 377 return sock_recvmsg(sock, msg, flags);
377} 378}
378 379
380#if ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE
381static void
382xs_flush_bvec(const struct bio_vec *bvec, size_t count, size_t seek)
383{
384 struct bvec_iter bi = {
385 .bi_size = count,
386 };
387 struct bio_vec bv;
388
389 bvec_iter_advance(bvec, &bi, seek & PAGE_MASK);
390 for_each_bvec(bv, bvec, bi, bi)
391 flush_dcache_page(bv.bv_page);
392}
393#else
394static inline void
395xs_flush_bvec(const struct bio_vec *bvec, size_t count, size_t seek)
396{
397}
398#endif
399
379static ssize_t 400static ssize_t
380xs_read_xdr_buf(struct socket *sock, struct msghdr *msg, int flags, 401xs_read_xdr_buf(struct socket *sock, struct msghdr *msg, int flags,
381 struct xdr_buf *buf, size_t count, size_t seek, size_t *read) 402 struct xdr_buf *buf, size_t count, size_t seek, size_t *read)
@@ -409,6 +430,7 @@ xs_read_xdr_buf(struct socket *sock, struct msghdr *msg, int flags,
409 seek + buf->page_base); 430 seek + buf->page_base);
410 if (ret <= 0) 431 if (ret <= 0)
411 goto sock_err; 432 goto sock_err;
433 xs_flush_bvec(buf->bvec, ret, seek + buf->page_base);
412 offset += ret - buf->page_base; 434 offset += ret - buf->page_base;
413 if (offset == count || msg->msg_flags & (MSG_EOR|MSG_TRUNC)) 435 if (offset == count || msg->msg_flags & (MSG_EOR|MSG_TRUNC))
414 goto out; 436 goto out;