aboutsummaryrefslogtreecommitdiffstats
path: root/net/ceph/messenger.c
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2013-03-12 00:34:23 -0400
committerSage Weil <sage@inktank.com>2013-05-02 00:17:25 -0400
commit463207aa40cf2cadcae84866b3f85ccaa7022ee8 (patch)
tree34a5cddfa662036377cea580682303dbc8d4070c /net/ceph/messenger.c
parent25aff7c559c8b54a810bc094d59fe037cfed6b18 (diff)
libceph: use cursor for bio reads
Replace the use of the information in con->in_msg_pos for incoming bio data. The old in_msg_pos and the new cursor mechanism do basically the same thing, just slightly differently. The main functional difference is that in_msg_pos keeps track of the length of the complete bio list, and assumed it was fully consumed when that many bytes had been transferred. The cursor does not assume a length, it simply consumes all bytes in the bio list. Because the only user of bio data is the rbd client, and because the length of a bio list provided by rbd client always matches the number of bytes in the list, both ways of tracking length are equivalent. In addition, for in_msg_pos the initial bio vector is selected as the initial value of the bio->bi_idx, while the cursor assumes this is zero. Again, the rbd client always passes 0 as the initial index so the effect is the same. Other than that, they basically match: in_msg_pos cursor ---------- ------ bio_iter bio bio_seg vec_index page_pos page_offset The in_msg_pos field is initialized by a call to init_bio_iter(). The bio cursor is initialized by ceph_msg_data_cursor_init(). Both now happen in the same spot, in prepare_message_data(). The in_msg_pos field is advanced by a call to in_msg_pos_next(), which updates page_pos and calls iter_bio_next() to move to the next bio vector, or to the next bio in the list. The cursor is advanced by ceph_msg_data_advance(). That isn't currently happening so add a call to that in in_msg_pos_next(). Finally, the next piece of data to use for a read is determined by a bunch of lines in read_partial_message_bio(). Those can be replaced by an equivalent ceph_msg_data_bio_next() call. This partially resolves: http://tracker.ceph.com/issues/4428 Signed-off-by: Alex Elder <elder@inktank.com> Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
Diffstat (limited to 'net/ceph/messenger.c')
-rw-r--r--net/ceph/messenger.c17
1 files changed, 6 insertions, 11 deletions
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index 0ac4f6cb7339..c795d46d7d4b 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -1468,6 +1468,10 @@ static void in_msg_pos_next(struct ceph_connection *con, size_t len,
1468 1468
1469 msg_pos->data_pos += received; 1469 msg_pos->data_pos += received;
1470 msg_pos->page_pos += received; 1470 msg_pos->page_pos += received;
1471#ifdef CONFIG_BLOCK
1472 if (ceph_msg_has_bio(msg))
1473 (void) ceph_msg_data_advance(&msg->b, received);
1474#endif /* CONFIG_BLOCK */
1471 if (received < len) 1475 if (received < len)
1472 return; 1476 return;
1473 1477
@@ -2255,23 +2259,14 @@ static int read_partial_message_bio(struct ceph_connection *con,
2255 unsigned int data_len, bool do_datacrc) 2259 unsigned int data_len, bool do_datacrc)
2256{ 2260{
2257 struct ceph_msg *msg = con->in_msg; 2261 struct ceph_msg *msg = con->in_msg;
2258 struct ceph_msg_pos *msg_pos = &con->in_msg_pos;
2259 struct bio_vec *bv;
2260 struct page *page; 2262 struct page *page;
2261 size_t page_offset; 2263 size_t page_offset;
2262 size_t length; 2264 size_t length;
2263 unsigned int left;
2264 int ret; 2265 int ret;
2265 2266
2266 BUG_ON(!msg); 2267 BUG_ON(!msg);
2267 BUG_ON(!msg->b.bio_iter); 2268
2268 bv = bio_iovec_idx(msg->b.bio_iter, msg->b.bio_seg); 2269 page = ceph_msg_data_next(&msg->b, &page_offset, &length, NULL);
2269 page = bv->bv_page;
2270 page_offset = bv->bv_offset + msg_pos->page_pos;
2271 BUG_ON(msg_pos->data_pos >= data_len);
2272 left = data_len - msg_pos->data_pos;
2273 BUG_ON(msg_pos->page_pos >= bv->bv_len);
2274 length = min_t(unsigned int, bv->bv_len - msg_pos->page_pos, left);
2275 2270
2276 ret = ceph_tcp_recvpage(con->sock, page, page_offset, length); 2271 ret = ceph_tcp_recvpage(con->sock, page, page_offset, length);
2277 if (ret <= 0) 2272 if (ret <= 0)