ceph: Don't use data_pages Signed-off-by: David Howells <dhowells@redhat.com> cc: Ilya Dryomov <idryomov@gmail.com> cc: Xiubo Li <xiubli@redhat.com> cc: Jeff Layton <jlayton@kernel.org> cc: ceph-devel@vger.kernel.org cc: linux-fsdevel@vger.kernel.org
diff --git a/include/linux/ceph/messenger.h b/include/linux/ceph/messenger.h index 8a7f723..2da9c5e 100644 --- a/include/linux/ceph/messenger.h +++ b/include/linux/ceph/messenger.h
@@ -308,7 +308,7 @@ struct ceph_connection_v2_info { int in_enc_page_cnt; int in_enc_resid; int in_enc_i; - struct page **out_enc_pages; + struct bvecq *out_enc_buffer; int out_enc_page_cnt; int out_enc_resid; int out_enc_i;
diff --git a/net/ceph/messenger_v2.c b/net/ceph/messenger_v2.c index b323b61..ffa10c1 100644 --- a/net/ceph/messenger_v2.c +++ b/net/ceph/messenger_v2.c
@@ -64,7 +64,7 @@ #define OUT_S_QUEUE_DATA 1 #define OUT_S_QUEUE_DATA_CONT 2 -#define OUT_S_QUEUE_ENC_PAGE 3 +#define OUT_S_QUEUE_ENC_BVECQ 3 #define OUT_S_QUEUE_ZEROS 4 #define OUT_S_FINISH_MESSAGE 5 #define OUT_S_GET_NEXT 6 @@ -1634,10 +1634,12 @@ static int prepare_message_secure(struct ceph_connection *con, struct ceph_msg *msg) { void *zerop = page_address(ceph_zero_page); + struct bvecq *enc_buffer = NULL, *bq; + struct iov_iter enc_iter; struct sg_table enc_sgt = {}; struct sg_table sgt = {}; - struct page **enc_pages; - int enc_page_cnt; + unsigned int nr_segs = 0; + ssize_t xsize; int tail_len; int ret; @@ -1662,23 +1664,30 @@ static int prepare_message_secure(struct ceph_connection *con, if (ret) goto out; - enc_page_cnt = calc_pages_for(0, tail_len); - enc_pages = ceph_alloc_page_vector(enc_page_cnt, GFP_NOIO); - if (IS_ERR(enc_pages)) { - ret = PTR_ERR(enc_pages); + enc_buffer = bvecq_alloc_buffer(tail_len, GFP_NOIO, false); + if (ret < 0) + goto out; + + for (bq = enc_buffer; bq; bq = bq->next) + nr_segs += bq->nr_slots; + + ret = sg_alloc_table(&enc_sgt, nr_segs, GFP_NOIO); + if (ret) + goto out; + + iov_iter_bvec_queue(&enc_iter, READ, enc_buffer, 0, 0, tail_len); + xsize = extract_iter_to_sg(&enc_iter, tail_len, &enc_sgt, nr_segs, 0); + if (WARN_ON(xsize != tail_len)) { + ret = -EIO; goto out; } - WARN_ON(con->v2.out_enc_pages || con->v2.out_enc_page_cnt); - con->v2.out_enc_pages = enc_pages; - con->v2.out_enc_page_cnt = enc_page_cnt; + WARN_ON(con->v2.out_enc_buffer || con->v2.out_enc_page_cnt); + con->v2.out_enc_buffer = enc_buffer; + con->v2.out_enc_page_cnt = nr_segs; con->v2.out_enc_resid = tail_len; con->v2.out_enc_i = 0; - - ret = sg_alloc_table_from_pages(&enc_sgt, enc_pages, enc_page_cnt, - 0, tail_len, GFP_NOIO); - if (ret) - goto out; + enc_buffer = NULL; ret = gcm_crypt(con, true, sgt.sgl, enc_sgt.sgl, tail_len - CEPH_GCM_TAG_LEN); @@ -1686,12 +1695,13 @@ static int prepare_message_secure(struct ceph_connection *con, goto out; dout("%s con %p msg %p sg_cnt %d enc_page_cnt %d\n", __func__, con, - msg, sgt.orig_nents, enc_page_cnt); - con->v2.out_state = OUT_S_QUEUE_ENC_PAGE; + msg, sgt.orig_nents, nr_segs); + con->v2.out_state = OUT_S_QUEUE_ENC_BVECQ; out: sg_free_table(&sgt); sg_free_table(&enc_sgt); + bvecq_put(enc_buffer); return ret; }