Commit afb3d90e authored by Alex Elder's avatar Alex Elder Committed by Sage Weil

libceph: define and use ceph_tcp_recvpage()

Define a new function ceph_tcp_recvpage() that behaves in a way
comparable to ceph_tcp_sendpage().

Rearrange the code in both read_partial_message_pages() and
read_partial_message_bio() so they have matching structure,
(similar to what's in write_partial_msg_pages()), and use
this new function.
Signed-off-by: default avatarAlex Elder <elder@inktank.com>
Reviewed-by: default avatarJosh Durgin <josh.durgin@inktank.com>
parent 34d2d200
...@@ -471,6 +471,22 @@ static int ceph_tcp_recvmsg(struct socket *sock, void *buf, size_t len) ...@@ -471,6 +471,22 @@ static int ceph_tcp_recvmsg(struct socket *sock, void *buf, size_t len)
return r; return r;
} }
static int ceph_tcp_recvpage(struct socket *sock, struct page *page,
int page_offset, size_t length)
{
void *kaddr;
int ret;
BUG_ON(page_offset + length > PAGE_SIZE);
kaddr = kmap(page);
BUG_ON(!kaddr);
ret = ceph_tcp_recvmsg(sock, kaddr + page_offset, length);
kunmap(page);
return ret;
}
/* /*
* write something. @more is true if caller will be sending more data * write something. @more is true if caller will be sending more data
* shortly. * shortly.
...@@ -1809,26 +1825,36 @@ static int read_partial_message_pages(struct ceph_connection *con, ...@@ -1809,26 +1825,36 @@ static int read_partial_message_pages(struct ceph_connection *con,
{ {
struct ceph_msg_pos *msg_pos = &con->in_msg_pos; struct ceph_msg_pos *msg_pos = &con->in_msg_pos;
struct page *page; struct page *page;
void *p; size_t page_offset;
size_t length;
unsigned int left;
int ret; int ret;
int left;
left = min((int)(data_len - msg_pos->data_pos),
(int)(PAGE_SIZE - msg_pos->page_pos));
/* (page) data */ /* (page) data */
BUG_ON(pages == NULL); BUG_ON(pages == NULL);
page = pages[msg_pos->page]; page = pages[msg_pos->page];
p = kmap(page); page_offset = msg_pos->page_pos;
ret = ceph_tcp_recvmsg(con->sock, p + msg_pos->page_pos, left); BUG_ON(msg_pos->data_pos >= data_len);
if (ret > 0 && do_datacrc) left = data_len - msg_pos->data_pos;
con->in_data_crc = BUG_ON(page_offset >= PAGE_SIZE);
crc32c(con->in_data_crc, length = min_t(unsigned int, PAGE_SIZE - page_offset, left);
p + msg_pos->page_pos, ret);
kunmap(page); ret = ceph_tcp_recvpage(con->sock, page, page_offset, length);
if (ret <= 0) if (ret <= 0)
return ret; return ret;
in_msg_pos_next(con, left, ret); if (do_datacrc) {
void *kaddr;
void *base;
kaddr = kmap(page);
BUG_ON(!kaddr);
base = kaddr + page_offset;
con->in_data_crc = crc32c(con->in_data_crc, base, ret);
kunmap(page);
}
in_msg_pos_next(con, length, ret);
return ret; return ret;
} }
...@@ -1841,29 +1867,37 @@ static int read_partial_message_bio(struct ceph_connection *con, ...@@ -1841,29 +1867,37 @@ static int read_partial_message_bio(struct ceph_connection *con,
struct ceph_msg_pos *msg_pos = &con->in_msg_pos; struct ceph_msg_pos *msg_pos = &con->in_msg_pos;
struct bio_vec *bv; struct bio_vec *bv;
struct page *page; struct page *page;
void *p; size_t page_offset;
int ret, left; size_t length;
unsigned int left;
int ret;
BUG_ON(!msg); BUG_ON(!msg);
BUG_ON(!msg->bio_iter); BUG_ON(!msg->bio_iter);
bv = bio_iovec_idx(msg->bio_iter, msg->bio_seg); bv = bio_iovec_idx(msg->bio_iter, msg->bio_seg);
left = min((int)(data_len - msg_pos->data_pos),
(int)(bv->bv_len - msg_pos->page_pos));
page = bv->bv_page; page = bv->bv_page;
p = kmap(page) + bv->bv_offset; page_offset = bv->bv_offset + msg_pos->page_pos;
BUG_ON(msg_pos->data_pos >= data_len);
left = data_len - msg_pos->data_pos;
BUG_ON(msg_pos->page_pos >= bv->bv_len);
length = min_t(unsigned int, bv->bv_len - msg_pos->page_pos, left);
ret = ceph_tcp_recvmsg(con->sock, p + msg_pos->page_pos, left); ret = ceph_tcp_recvpage(con->sock, page, page_offset, length);
if (ret > 0 && do_datacrc)
con->in_data_crc =
crc32c(con->in_data_crc,
p + msg_pos->page_pos, ret);
kunmap(page);
if (ret <= 0) if (ret <= 0)
return ret; return ret;
in_msg_pos_next(con, left, ret); if (do_datacrc) {
void *kaddr;
void *base;
kaddr = kmap(page);
BUG_ON(!kaddr);
base = kaddr + page_offset;
con->in_data_crc = crc32c(con->in_data_crc, base, ret);
kunmap(page);
}
in_msg_pos_next(con, length, ret);
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment