diff options
Diffstat (limited to 'net/ceph/messenger.c')
-rw-r--r-- | net/ceph/messenger.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index dac7f9b98687..1948d592aa54 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c | |||
@@ -557,7 +557,7 @@ static int ceph_tcp_sendmsg(struct socket *sock, struct kvec *iov, | |||
557 | return r; | 557 | return r; |
558 | } | 558 | } |
559 | 559 | ||
560 | static int ceph_tcp_sendpage(struct socket *sock, struct page *page, | 560 | static int __ceph_tcp_sendpage(struct socket *sock, struct page *page, |
561 | int offset, size_t size, bool more) | 561 | int offset, size_t size, bool more) |
562 | { | 562 | { |
563 | int flags = MSG_DONTWAIT | MSG_NOSIGNAL | (more ? MSG_MORE : MSG_EOR); | 563 | int flags = MSG_DONTWAIT | MSG_NOSIGNAL | (more ? MSG_MORE : MSG_EOR); |
@@ -570,6 +570,24 @@ static int ceph_tcp_sendpage(struct socket *sock, struct page *page, | |||
570 | return ret; | 570 | return ret; |
571 | } | 571 | } |
572 | 572 | ||
573 | static int ceph_tcp_sendpage(struct socket *sock, struct page *page, | ||
574 | int offset, size_t size, bool more) | ||
575 | { | ||
576 | int ret; | ||
577 | struct kvec iov; | ||
578 | |||
579 | /* sendpage cannot properly handle pages with page_count == 0, | ||
580 | * we need to fallback to sendmsg if that's the case */ | ||
581 | if (page_count(page) >= 1) | ||
582 | return __ceph_tcp_sendpage(sock, page, offset, size, more); | ||
583 | |||
584 | iov.iov_base = kmap(page) + offset; | ||
585 | iov.iov_len = size; | ||
586 | ret = ceph_tcp_sendmsg(sock, &iov, 1, size, more); | ||
587 | kunmap(page); | ||
588 | |||
589 | return ret; | ||
590 | } | ||
573 | 591 | ||
574 | /* | 592 | /* |
575 | * Shutdown/close the socket for the given connection. | 593 | * Shutdown/close the socket for the given connection. |