]> git.apps.os.sepia.ceph.com Git - ceph-client.git/commitdiff
libceph:
authorJeff Layton <jlayton@kernel.org>
Thu, 19 May 2022 20:42:56 +0000 (16:42 -0400)
committerJeff Layton <jlayton@kernel.org>
Thu, 19 May 2022 20:42:56 +0000 (16:42 -0400)
Signed-off-by: Jeff Layton <jlayton@kernel.org>
include/linux/ceph/messenger.h
net/ceph/messenger.c
net/ceph/messenger_v2.c

index edd27e12e1d91c622281e5c7708a44bb37aa4b3d..175f795bcf469933ced1ae2aa6a16b8efbd94ed2 100644 (file)
@@ -228,6 +228,7 @@ struct ceph_msg_data_cursor {
                        struct page     *page;          /* page from list */
                        size_t          offset;         /* bytes from list */
                };
+               struct iov_iter         iov_iter;
        };
 };
 
index 9caa6eaee73710c12624382018258edf491b6891..90ceaac9c70e7d409c8f3126ce89cc4503ec6671 100644 (file)
@@ -990,6 +990,47 @@ static bool ceph_msg_data_pagelist_advance(struct ceph_msg_data_cursor *cursor,
        return true;
 }
 
+static void ceph_msg_data_iter_cursor_init(struct ceph_msg_data_cursor *cursor,
+                                       size_t length)
+{
+       struct ceph_msg_data *data = cursor->data;
+       size_t count = iov_iter_count(&data->iter);
+
+       cursor->resid = min_t(size_t, length, count);
+       cursor->iov_iter = data->iter;
+       cursor->last_piece = cursor->resid == count;
+}
+
+static struct page *ceph_msg_data_iter_next(struct ceph_msg_data_cursor *cursor,
+                                               size_t *page_offset,
+                                               size_t *length)
+{
+       struct page *page;
+       ssize_t len = iov_iter_get_pages(&cursor->iov_iter, &page, PAGE_SIZE,
+                                        1, page_offset);
+
+       BUG_ON(len < 0);
+       *length = len;
+       return page;
+}
+
+static bool ceph_msg_data_iter_advance(struct ceph_msg_data_cursor *cursor,
+                                       size_t bytes)
+{
+       BUG_ON(bytes > cursor->resid);
+       cursor->resid -= bytes;
+       iov_iter_advance(&cursor->iov_iter, bytes);
+
+       if (!cursor->resid) {
+               BUG_ON(!cursor->last_piece);
+               return false;   /* no more data */
+       }
+
+       BUG_ON(cursor->last_piece);
+       cursor->last_piece = cursor->resid == iov_iter_count(&cursor->iov_iter);
+       return true;
+}
+
 /*
  * Message data is handled (sent or received) in pieces, where each
  * piece resides on a single page.  The network layer might not
@@ -1023,7 +1064,7 @@ static void __ceph_msg_data_cursor_init(struct ceph_msg_data_cursor *cursor)
                ceph_msg_data_bvecs_cursor_init(cursor, length);
                break;
        case CEPH_MSG_DATA_ITER:
-               cursor->last_piece = true;
+               ceph_msg_data_iter_cursor_init(cursor, length);
                break;
        case CEPH_MSG_DATA_NONE:
        default:
@@ -1073,7 +1114,8 @@ struct page *ceph_msg_data_next(struct ceph_msg_data_cursor *cursor,
                page = ceph_msg_data_bvecs_next(cursor, page_offset, length);
                break;
        case CEPH_MSG_DATA_ITER:
-               BUG(); /* Shouldn't get here */
+               page = ceph_msg_data_iter_next(cursor, page_offset, length);
+               break;
        case CEPH_MSG_DATA_NONE:
        default:
                page = NULL;
@@ -1115,7 +1157,8 @@ void ceph_msg_data_advance(struct ceph_msg_data_cursor *cursor, size_t bytes)
                new_piece = ceph_msg_data_bvecs_advance(cursor, bytes);
                break;
        case CEPH_MSG_DATA_ITER:
-               BUG(); /* Shouldn't get here */
+               new_piece = ceph_msg_data_iter_advance(cursor, bytes);
+               break;
        case CEPH_MSG_DATA_NONE:
        default:
                BUG();
index c6e5bfc717d5460fb8b4238da7484aadeee2a6d8..7fab0e170c592c53a864c963f9c7a4bf49ea42c8 100644 (file)
@@ -1059,6 +1059,16 @@ static int decrypt_tail(struct ceph_connection *con)
        if (ret)
                goto out;
 
+       if (con->v2.in_cursor.data->type == CEPH_MSG_DATA_ITER) {
+               int i;
+               struct scatterlist *sg;
+#if 0
+               for_each_sg_table_sg(&sgt, sg, i) {
+                       put_page(sg_page(sg));
+               }
+#endif
+       }
+
        WARN_ON(!con->v2.in_enc_page_cnt);
        ceph_release_page_vector(con->v2.in_enc_pages,
                                 con->v2.in_enc_page_cnt);
@@ -1792,6 +1802,7 @@ static void prepare_read_data_cont(struct ceph_connection *con)
                memcpy_to_page(bv.bv_page, bv.bv_offset,
                               page_address(con->bounce_page),
                               con->v2.in_bvec.bv_len);
+
        } else {
                con->in_data_crc = ceph_crc32c_page(con->in_data_crc,
                                                    con->v2.in_bvec.bv_page,
@@ -1799,6 +1810,9 @@ static void prepare_read_data_cont(struct ceph_connection *con)
                                                    con->v2.in_bvec.bv_len);
        }
 
+       if (con->v2.in_cursor.data->type == CEPH_MSG_DATA_ITER)
+               put_page(bv.bv_page);
+
        ceph_msg_data_advance(&con->v2.in_cursor, con->v2.in_bvec.bv_len);
        if (con->v2.in_cursor.total_resid) {
                get_bvec_at(&con->v2.in_cursor, &bv);