#endif
 }
 
+static void in_msg_pos_next(struct ceph_connection *con, size_t len,
+                               size_t received)
+{
+       struct ceph_msg *msg = con->in_msg;
+
+       BUG_ON(!msg);
+       BUG_ON(!received);
+
+       con->in_msg_pos.data_pos += received;
+       con->in_msg_pos.page_pos += received;
+       if (received < len)
+               return;
+
+       BUG_ON(received != len);
+       con->in_msg_pos.page_pos = 0;
+       con->in_msg_pos.page++;
+#ifdef CONFIG_BLOCK
+       if (msg->bio)
+               iter_bio_next(&msg->bio_iter, &msg->bio_seg);
+#endif /* CONFIG_BLOCK */
+}
+
 /*
  * Write as much message data payload as we can.  If we finish, queue
  * up the footer.
                                      struct page **pages,
                                      unsigned int data_len, bool do_datacrc)
 {
+       struct page *page;
        void *p;
        int ret;
        int left;
                   (int)(PAGE_SIZE - con->in_msg_pos.page_pos));
        /* (page) data */
        BUG_ON(pages == NULL);
-       p = kmap(pages[con->in_msg_pos.page]);
-       ret = ceph_tcp_recvmsg(con->sock, p + con->in_msg_pos.page_pos,
-                              left);
+       page = pages[con->in_msg_pos.page];
+       p = kmap(page);
+       ret = ceph_tcp_recvmsg(con->sock, p + con->in_msg_pos.page_pos, left);
        if (ret > 0 && do_datacrc)
                con->in_data_crc =
                        crc32c(con->in_data_crc,
                                  p + con->in_msg_pos.page_pos, ret);
-       kunmap(pages[con->in_msg_pos.page]);
+       kunmap(page);
        if (ret <= 0)
                return ret;
-       con->in_msg_pos.data_pos += ret;
-       con->in_msg_pos.page_pos += ret;
-       if (con->in_msg_pos.page_pos == PAGE_SIZE) {
-               con->in_msg_pos.page_pos = 0;
-               con->in_msg_pos.page++;
-       }
+
+       in_msg_pos_next(con, left, ret);
 
        return ret;
 }
 {
        struct ceph_msg *msg = con->in_msg;
        struct bio_vec *bv;
+       struct page *page;
        void *p;
        int ret, left;
 
        BUG_ON(!msg);
        BUG_ON(!msg->bio_iter);
        bv = bio_iovec_idx(msg->bio_iter, msg->bio_seg);
+
        left = min((int)(data_len - con->in_msg_pos.data_pos),
                   (int)(bv->bv_len - con->in_msg_pos.page_pos));
 
-       p = kmap(bv->bv_page) + bv->bv_offset;
+       page = bv->bv_page;
+       p = kmap(page) + bv->bv_offset;
 
-       ret = ceph_tcp_recvmsg(con->sock, p + con->in_msg_pos.page_pos,
-                              left);
+       ret = ceph_tcp_recvmsg(con->sock, p + con->in_msg_pos.page_pos, left);
        if (ret > 0 && do_datacrc)
                con->in_data_crc =
                        crc32c(con->in_data_crc,
                                  p + con->in_msg_pos.page_pos, ret);
-       kunmap(bv->bv_page);
+       kunmap(page);
        if (ret <= 0)
                return ret;
-       con->in_msg_pos.data_pos += ret;
-       con->in_msg_pos.page_pos += ret;
-       if (con->in_msg_pos.page_pos == bv->bv_len) {
-               con->in_msg_pos.page_pos = 0;
-               iter_bio_next(&msg->bio_iter, &msg->bio_seg);
-       }
+
+       in_msg_pos_next(con, left, ret);
 
        return ret;
 }