|
@@ -557,7 +557,7 @@ static int ceph_tcp_sendmsg(struct socket *sock, struct kvec *iov,
|
|
return r;
|
|
return r;
|
|
}
|
|
}
|
|
|
|
|
|
-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)
|
|
int offset, size_t size, bool more)
|
|
{
|
|
{
|
|
int flags = MSG_DONTWAIT | MSG_NOSIGNAL | (more ? MSG_MORE : MSG_EOR);
|
|
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,
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int ceph_tcp_sendpage(struct socket *sock, struct page *page,
|
|
|
|
+ int offset, size_t size, bool more)
|
|
|
|
+{
|
|
|
|
+ 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);
|
|
|
|
+
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
|
|
/*
|
|
/*
|
|
* Shutdown/close the socket for the given connection.
|
|
* Shutdown/close the socket for the given connection.
|