From 19487feafb6b5c55bebd2a1f979217277a8157f8 Mon Sep 17 00:00:00 2001 From: Liu Kui Date: Wed, 19 Apr 2023 18:49:03 +0800 Subject: [PATCH RH9 v2] fuse/kio: do not use sendpage on pages which cannot be sendpaged It looks like the new API iov_iter_get_pages is not safe for use when trying to get a page from a bvec to be sent by kernel_sendpage(). So just revert back our own implentation where we check the page before making get_page(), if the page can't be sendpage, fall back to copy mode. Affects: #PSBM-146821, #PSBM-146846 https://jira.vzint.dev/browse/PSBM-146821 https://jira.vzint.dev/browse/PSBM-146846 Signed-off-by: Liu Kui --- fs/fuse/kio/pcs/pcs_sock_io.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/fs/fuse/kio/pcs/pcs_sock_io.c b/fs/fuse/kio/pcs/pcs_sock_io.c index 552b82ab398b..710940eafa34 100644 --- a/fs/fuse/kio/pcs/pcs_sock_io.c +++ b/fs/fuse/kio/pcs/pcs_sock_io.c @@ -143,16 +143,30 @@ static int do_send_one_seg(struct socket *sock, struct iov_iter *it, size_t left } if (iov_iter_is_bvec(it)) { - /* Zerocopy */ size_t offset; ssize_t len; struct page *page; - len = iov_iter_get_pages(it, &page, size, 1, &offset); - BUG_ON(len <= 0); - - ret = kernel_sendpage(sock, page, offset, len, flags); - put_page(page); + /* Only support single page bvec here */ + page = it->bvec->bv_page; + offset = it->bvec->bv_offset + it->iov_offset; + len = min(size, it->bvec->bv_len - it->iov_offset); + + if (sendpage_ok(page)) { + /* Zero copy */ + get_page(page); + ret = kernel_sendpage(sock, page, offset, len, flags); + put_page(page); + } else { + /* Fall back to copy mode */ + struct msghdr msg = { .msg_flags = flags }; + struct kvec kv; + + kv.iov_base = kmap(page) + offset; + kv.iov_len = len; + ret = kernel_sendmsg(sock, &msg, &kv, 1, size); + kunmap(page); + } } out: -- 2.32.0 (Apple Git-132)