diff options
author | Yehuda Sadeh <yehuda@hq.newdream.net> | 2010-01-11 13:32:02 -0500 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2010-01-25 15:57:43 -0500 |
commit | 9d7f0f139edfdce1a1539b100c617fd9182b0829 (patch) | |
tree | 75b1e921e859b3ee9f110f01237a17e79c7a0074 | |
parent | 2450418c47b7998ad55a73f23707b1e21c371eef (diff) |
ceph: refactor messages data section allocation
Signed-off-by: Yehuda Sadeh <yehuda@hq.newdream.net>
-rw-r--r-- | fs/ceph/messenger.c | 67 |
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 | ||
1443 | no_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 | ||
2117 | static 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 | ||