aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYehuda Sadeh <yehuda@hq.newdream.net>2010-01-11 13:32:02 -0500
committerSage Weil <sage@newdream.net>2010-01-25 15:57:43 -0500
commit9d7f0f139edfdce1a1539b100c617fd9182b0829 (patch)
tree75b1e921e859b3ee9f110f01237a17e79c7a0074
parent2450418c47b7998ad55a73f23707b1e21c371eef (diff)
ceph: refactor messages data section allocation
Signed-off-by: Yehuda Sadeh <yehuda@hq.newdream.net>
-rw-r--r--fs/ceph/messenger.c67
1 files changed, 39 insertions, 28 deletions
diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c
index 25de15c006b1..e8742cc9ecdf 100644
--- a/fs/ceph/messenger.c
+++ b/fs/ceph/messenger.c
@@ -1315,7 +1315,7 @@ static int read_partial_message(struct ceph_connection *con)
1315 struct ceph_msg *m = con->in_msg; 1315 struct ceph_msg *m = con->in_msg;
1316 void *p; 1316 void *p;
1317 int ret; 1317 int ret;
1318 int to, want, left; 1318 int to, left;
1319 unsigned front_len, middle_len, data_len, data_off; 1319 unsigned front_len, middle_len, data_len, data_off;
1320 int datacrc = con->msgr->nocrc; 1320 int datacrc = con->msgr->nocrc;
1321 int skip; 1321 int skip;
@@ -1351,6 +1351,7 @@ static int read_partial_message(struct ceph_connection *con)
1351 data_len = le32_to_cpu(con->in_hdr.data_len); 1351 data_len = le32_to_cpu(con->in_hdr.data_len);
1352 if (data_len > CEPH_MSG_MAX_DATA_LEN) 1352 if (data_len > CEPH_MSG_MAX_DATA_LEN)
1353 return -EIO; 1353 return -EIO;
1354 data_off = le16_to_cpu(con->in_hdr.data_off);
1354 1355
1355 /* allocate message? */ 1356 /* allocate message? */
1356 if (!con->in_msg) { 1357 if (!con->in_msg) {
@@ -1375,7 +1376,10 @@ static int read_partial_message(struct ceph_connection *con)
1375 m->front.iov_len = 0; /* haven't read it yet */ 1376 m->front.iov_len = 0; /* haven't read it yet */
1376 if (m->middle) 1377 if (m->middle)
1377 m->middle->vec.iov_len = 0; 1378 m->middle->vec.iov_len = 0;
1378 memcpy(&m->hdr, &con->in_hdr, sizeof(con->in_hdr)); 1379
1380 con->in_msg_pos.page = 0;
1381 con->in_msg_pos.page_pos = data_off & ~PAGE_MASK;
1382 con->in_msg_pos.data_pos = 0;
1379 } 1383 }
1380 1384
1381 /* front */ 1385 /* front */
@@ -1393,31 +1397,6 @@ static int read_partial_message(struct ceph_connection *con)
1393 } 1397 }
1394 1398
1395 /* (page) data */ 1399 /* (page) data */
1396 data_off = le16_to_cpu(m->hdr.data_off);
1397 if (data_len == 0)
1398 goto no_data;
1399
1400 if (m->nr_pages == 0) {
1401 con->in_msg_pos.page = 0;
1402 con->in_msg_pos.page_pos = data_off & ~PAGE_MASK;
1403 con->in_msg_pos.data_pos = 0;
1404 /* find pages for data payload */
1405 want = calc_pages_for(data_off & ~PAGE_MASK, data_len);
1406 ret = -1;
1407 mutex_unlock(&con->mutex);
1408 if (con->ops->prepare_pages)
1409 ret = con->ops->prepare_pages(con, m, want);
1410 mutex_lock(&con->mutex);
1411 if (ret < 0) {
1412 dout("%p prepare_pages failed, skipping payload\n", m);
1413 con->in_base_pos = -data_len - sizeof(m->footer);
1414 ceph_msg_put(con->in_msg);
1415 con->in_msg = NULL;
1416 con->in_tag = CEPH_MSGR_TAG_READY;
1417 return 0;
1418 }
1419 BUG_ON(m->nr_pages < want);
1420 }
1421 while (con->in_msg_pos.data_pos < data_len) { 1400 while (con->in_msg_pos.data_pos < data_len) {
1422 left = min((int)(data_len - con->in_msg_pos.data_pos), 1401 left = min((int)(data_len - con->in_msg_pos.data_pos),
1423 (int)(PAGE_SIZE - con->in_msg_pos.page_pos)); 1402 (int)(PAGE_SIZE - con->in_msg_pos.page_pos));
@@ -1440,7 +1419,6 @@ static int read_partial_message(struct ceph_connection *con)
1440 } 1419 }
1441 } 1420 }
1442 1421
1443no_data:
1444 /* footer */ 1422 /* footer */
1445 to = sizeof(m->hdr) + sizeof(m->footer); 1423 to = sizeof(m->hdr) + sizeof(m->footer);
1446 while (con->in_base_pos < to) { 1424 while (con->in_base_pos < to) {
@@ -2136,6 +2114,25 @@ static int ceph_alloc_middle(struct ceph_connection *con, struct ceph_msg *msg)
2136 return 0; 2114 return 0;
2137} 2115}
2138 2116
2117static int ceph_alloc_data_section(struct ceph_connection *con, struct ceph_msg *msg)
2118{
2119 int ret;
2120 int want;
2121 int data_len = le32_to_cpu(msg->hdr.data_len);
2122 unsigned data_off = le16_to_cpu(msg->hdr.data_off);
2123
2124 want = calc_pages_for(data_off & ~PAGE_MASK, data_len);
2125 ret = -1;
2126 mutex_unlock(&con->mutex);
2127 if (con->ops->prepare_pages)
2128 ret = con->ops->prepare_pages(con, msg, want);
2129 mutex_lock(&con->mutex);
2130
2131 BUG_ON(msg->nr_pages < want);
2132
2133 return ret;
2134}
2135
2139/* 2136/*
2140 * Generic message allocator, for incoming messages. 2137 * Generic message allocator, for incoming messages.
2141 */ 2138 */
@@ -2146,6 +2143,7 @@ static struct ceph_msg *ceph_alloc_msg(struct ceph_connection *con,
2146 int type = le16_to_cpu(hdr->type); 2143 int type = le16_to_cpu(hdr->type);
2147 int front_len = le32_to_cpu(hdr->front_len); 2144 int front_len = le32_to_cpu(hdr->front_len);
2148 int middle_len = le32_to_cpu(hdr->middle_len); 2145 int middle_len = le32_to_cpu(hdr->middle_len);
2146 int data_len = le32_to_cpu(hdr->data_len);
2149 struct ceph_msg *msg = NULL; 2147 struct ceph_msg *msg = NULL;
2150 int ret; 2148 int ret;
2151 2149
@@ -2166,6 +2164,7 @@ static struct ceph_msg *ceph_alloc_msg(struct ceph_connection *con,
2166 return ERR_PTR(-ENOMEM); 2164 return ERR_PTR(-ENOMEM);
2167 } 2165 }
2168 } 2166 }
2167 memcpy(&msg->hdr, &con->in_hdr, sizeof(con->in_hdr));
2169 2168
2170 if (middle_len) { 2169 if (middle_len) {
2171 ret = ceph_alloc_middle(con, msg); 2170 ret = ceph_alloc_middle(con, msg);
@@ -2175,6 +2174,18 @@ static struct ceph_msg *ceph_alloc_msg(struct ceph_connection *con,
2175 return msg; 2174 return msg;
2176 } 2175 }
2177 } 2176 }
2177
2178 if (data_len) {
2179 ret = ceph_alloc_data_section(con, msg);
2180
2181 if (ret < 0) {
2182 *skip = 1;
2183 ceph_msg_put(msg);
2184 return NULL;
2185 }
2186 }
2187
2188
2178 return msg; 2189 return msg;
2179} 2190}
2180 2191