diff options
author | Sage Weil <sage@inktank.com> | 2012-07-30 19:24:37 -0400 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2012-07-30 21:15:30 -0400 |
commit | 8c50c817566dfa4581f82373aac39f3e608a7dc8 (patch) | |
tree | 875162b047de3e18de801e1e6152f6d8f4810652 /net/ceph | |
parent | 3a140a0d5c4b9e35373b016e41dfc85f1e526bdb (diff) |
libceph: fix mutex coverage for ceph_con_close
Hold the mutex while twiddling all of the state bits to avoid possible
races. While we're here, make not of why we cannot close the socket
directly.
Signed-off-by: Sage Weil <sage@inktank.com>
Reviewed-by: Alex Elder <elder@inktank.com>
Reviewed-by: Yehuda Sadeh <yehuda@inktank.com>
Diffstat (limited to 'net/ceph')
-rw-r--r-- | net/ceph/messenger.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index 6e2f67816f61..e65b15d5d8b9 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c | |||
@@ -503,6 +503,7 @@ static void reset_connection(struct ceph_connection *con) | |||
503 | */ | 503 | */ |
504 | void ceph_con_close(struct ceph_connection *con) | 504 | void ceph_con_close(struct ceph_connection *con) |
505 | { | 505 | { |
506 | mutex_lock(&con->mutex); | ||
506 | dout("con_close %p peer %s\n", con, | 507 | dout("con_close %p peer %s\n", con, |
507 | ceph_pr_addr(&con->peer_addr.in_addr)); | 508 | ceph_pr_addr(&con->peer_addr.in_addr)); |
508 | clear_bit(NEGOTIATING, &con->state); | 509 | clear_bit(NEGOTIATING, &con->state); |
@@ -515,11 +516,16 @@ void ceph_con_close(struct ceph_connection *con) | |||
515 | clear_bit(KEEPALIVE_PENDING, &con->flags); | 516 | clear_bit(KEEPALIVE_PENDING, &con->flags); |
516 | clear_bit(WRITE_PENDING, &con->flags); | 517 | clear_bit(WRITE_PENDING, &con->flags); |
517 | 518 | ||
518 | mutex_lock(&con->mutex); | ||
519 | reset_connection(con); | 519 | reset_connection(con); |
520 | con->peer_global_seq = 0; | 520 | con->peer_global_seq = 0; |
521 | cancel_delayed_work(&con->work); | 521 | cancel_delayed_work(&con->work); |
522 | mutex_unlock(&con->mutex); | 522 | mutex_unlock(&con->mutex); |
523 | |||
524 | /* | ||
525 | * We cannot close the socket directly from here because the | ||
526 | * work threads use it without holding the mutex. Instead, let | ||
527 | * con_work() do it. | ||
528 | */ | ||
523 | queue_con(con); | 529 | queue_con(con); |
524 | } | 530 | } |
525 | EXPORT_SYMBOL(ceph_con_close); | 531 | EXPORT_SYMBOL(ceph_con_close); |