diff options
author | Sage Weil <sage@newdream.net> | 2009-12-11 12:48:05 -0500 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2009-12-21 19:39:53 -0500 |
commit | cf3e5c409b5d66ec66207092a3f7e3e2c42c0f3f (patch) | |
tree | 132e0095756777f4716f59e6c05ac85b80e830fd | |
parent | 9ec7cab14e6de732d4e7c355fe67c5810c32c758 (diff) |
ceph: plug leak of incoming message during connection fault/close
If we explicitly close a connection, or there is a socket error, we need
to drop any partially received message.
Signed-off-by: Sage Weil <sage@newdream.net>
-rw-r--r-- | fs/ceph/messenger.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index b10f88c56706..b12604ef1846 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c | |||
@@ -320,6 +320,11 @@ static void reset_connection(struct ceph_connection *con) | |||
320 | ceph_msg_remove_list(&con->out_queue); | 320 | ceph_msg_remove_list(&con->out_queue); |
321 | ceph_msg_remove_list(&con->out_sent); | 321 | ceph_msg_remove_list(&con->out_sent); |
322 | 322 | ||
323 | if (con->in_msg) { | ||
324 | ceph_msg_put(con->in_msg); | ||
325 | con->in_msg = NULL; | ||
326 | } | ||
327 | |||
323 | con->connect_seq = 0; | 328 | con->connect_seq = 0; |
324 | con->out_seq = 0; | 329 | con->out_seq = 0; |
325 | if (con->out_msg) { | 330 | if (con->out_msg) { |
@@ -1288,7 +1293,7 @@ static int read_partial_message(struct ceph_connection *con) | |||
1288 | con->in_msg = con->ops->alloc_msg(con, &con->in_hdr); | 1293 | con->in_msg = con->ops->alloc_msg(con, &con->in_hdr); |
1289 | if (!con->in_msg) { | 1294 | if (!con->in_msg) { |
1290 | /* skip this message */ | 1295 | /* skip this message */ |
1291 | dout("alloc_msg returned NULL, skipping message\n"); | 1296 | pr_err("alloc_msg returned NULL, skipping message\n"); |
1292 | con->in_base_pos = -front_len - middle_len - data_len - | 1297 | con->in_base_pos = -front_len - middle_len - data_len - |
1293 | sizeof(m->footer); | 1298 | sizeof(m->footer); |
1294 | con->in_tag = CEPH_MSGR_TAG_READY; | 1299 | con->in_tag = CEPH_MSGR_TAG_READY; |
@@ -1327,7 +1332,7 @@ static int read_partial_message(struct ceph_connection *con) | |||
1327 | if (con->ops->alloc_middle) | 1332 | if (con->ops->alloc_middle) |
1328 | ret = con->ops->alloc_middle(con, m); | 1333 | ret = con->ops->alloc_middle(con, m); |
1329 | if (ret < 0) { | 1334 | if (ret < 0) { |
1330 | dout("alloc_middle failed, skipping payload\n"); | 1335 | pr_err("alloc_middle fail skipping payload\n"); |
1331 | con->in_base_pos = -middle_len - data_len | 1336 | con->in_base_pos = -middle_len - data_len |
1332 | - sizeof(m->footer); | 1337 | - sizeof(m->footer); |
1333 | ceph_msg_put(con->in_msg); | 1338 | ceph_msg_put(con->in_msg); |
@@ -1498,6 +1503,7 @@ more: | |||
1498 | set_bit(CONNECTING, &con->state); | 1503 | set_bit(CONNECTING, &con->state); |
1499 | clear_bit(NEGOTIATING, &con->state); | 1504 | clear_bit(NEGOTIATING, &con->state); |
1500 | 1505 | ||
1506 | BUG_ON(con->in_msg); | ||
1501 | con->in_tag = CEPH_MSGR_TAG_READY; | 1507 | con->in_tag = CEPH_MSGR_TAG_READY; |
1502 | dout("try_write initiating connect on %p new state %lu\n", | 1508 | dout("try_write initiating connect on %p new state %lu\n", |
1503 | con, con->state); | 1509 | con, con->state); |