summaryrefslogtreecommitdiffstats
path: root/net/ceph
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2016-01-09 20:55:45 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2016-12-26 21:35:41 -0500
commit61ff6e9b452d6158e0fd659c6d987f47cfcfbd7b (patch)
tree2b37dddc0968d59fca2c22ca7299ca8c22fb8857 /net/ceph
parent39c6aceae961776a11a3767553b0e295fc9d413b (diff)
downloadlinux-61ff6e9b452d6158e0fd659c6d987f47cfcfbd7b.tar.bz2
ceph_tcp_sendpage(): use ITER_BVEC sendmsg
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'net/ceph')
-rw-r--r--net/ceph/messenger.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index 9e46db7e5968..6f3b5754cc7e 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -583,18 +583,28 @@ static int __ceph_tcp_sendpage(struct socket *sock, struct page *page,
static int ceph_tcp_sendpage(struct socket *sock, struct page *page,
int offset, size_t size, bool more)
{
+ struct msghdr msg = { .msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL };
+ struct bio_vec bvec;
int ret;
- struct kvec iov;
/* sendpage cannot properly handle pages with page_count == 0,
* we need to fallback to sendmsg if that's the case */
if (page_count(page) >= 1)
return __ceph_tcp_sendpage(sock, page, offset, size, more);
- iov.iov_base = kmap(page) + offset;
- iov.iov_len = size;
- ret = ceph_tcp_sendmsg(sock, &iov, 1, size, more);
- kunmap(page);
+ bvec.bv_page = page;
+ bvec.bv_offset = offset;
+ bvec.bv_len = size;
+
+ if (more)
+ msg.msg_flags |= MSG_MORE;
+ else
+ msg.msg_flags |= MSG_EOR; /* superfluous, but what the hell */
+
+ iov_iter_bvec(&msg.msg_iter, WRITE | ITER_BVEC, &bvec, 1, size);
+ ret = sock_sendmsg(sock, &msg);
+ if (ret == -EAGAIN)
+ ret = 0;
return ret;
}