libceph: rename ceph_msg::front_max to front_alloc_len
[pandora-kernel.git] / net / ceph / messenger.c
index ad5b708..7a239f0 100644 (file)
@@ -284,6 +284,37 @@ static int ceph_tcp_sendmsg(struct socket *sock, struct kvec *iov,
        return r;
 }
 
+static int __ceph_tcp_sendpage(struct socket *sock, struct page *page,
+                    int offset, size_t size, bool more)
+{
+       int flags = MSG_DONTWAIT | MSG_NOSIGNAL | (more ? MSG_MORE : MSG_EOR);
+       int ret;
+
+       ret = kernel_sendpage(sock, page, offset, size, flags);
+       if (ret == -EAGAIN)
+               ret = 0;
+
+       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.
@@ -851,18 +882,14 @@ static int write_partial_msg_pages(struct ceph_connection *con)
                                cpu_to_le32(crc32c(tmpcrc, base, len));
                        con->out_msg_pos.did_page_crc = 1;
                }
-               ret = kernel_sendpage(con->sock, page,
+               ret = ceph_tcp_sendpage(con->sock, page,
                                      con->out_msg_pos.page_pos + page_shift,
-                                     len,
-                                     MSG_DONTWAIT | MSG_NOSIGNAL |
-                                     MSG_MORE);
+                                     len, 1);
 
                if (crc &&
                    (msg->pages || msg->pagelist || msg->bio || in_trail))
                        kunmap(page);
 
-               if (ret == -EAGAIN)
-                       ret = 0;
                if (ret <= 0)
                        goto out;
 
@@ -2396,7 +2423,7 @@ struct ceph_msg *ceph_msg_new(int type, int front_len, gfp_t flags,
        m->footer.middle_crc = 0;
        m->footer.data_crc = 0;
        m->footer.flags = 0;
-       m->front_max = front_len;
+       m->front_alloc_len = front_len;
        m->front_is_vmalloc = false;
        m->more_to_follow = false;
        m->ack_stamp = 0;
@@ -2567,8 +2594,8 @@ EXPORT_SYMBOL(ceph_msg_last_put);
 
 void ceph_msg_dump(struct ceph_msg *msg)
 {
-       pr_debug("msg_dump %p (front_max %d nr_pages %d)\n", msg,
-                msg->front_max, msg->nr_pages);
+       pr_debug("msg_dump %p (front_alloc_len %d nr_pages %d)\n", msg,
+                msg->front_alloc_len, msg->nr_pages);
        print_hex_dump(KERN_DEBUG, "header: ",
                       DUMP_PREFIX_OFFSET, 16, 1,
                       &msg->hdr, sizeof(msg->hdr), true);