lkml.org 
[lkml]   [2013]   [Jan]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[ 190/221] libceph: socket can close in any connection state
    Date
    3.7-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Alex Elder <elder@inktank.com>

    (cherry picked from commit 7bb21d68c535ad8be38e14a715632ae398b37ac1)

    A connection's socket can close for any reason, independent of the
    state of the connection (and without irrespective of the connection
    mutex). As a result, the connectino can be in pretty much any state
    at the time its socket is closed.

    Handle those other cases at the top of con_work(). Pull this whole
    block of code into a separate function to reduce the clutter.

    Signed-off-by: Alex Elder <elder@inktank.com>
    Reviewed-by: Sage Weil <sage@inktank.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    net/ceph/messenger.c | 47 ++++++++++++++++++++++++++++++-----------------
    1 file changed, 30 insertions(+), 17 deletions(-)

    --- a/net/ceph/messenger.c
    +++ b/net/ceph/messenger.c
    @@ -2262,6 +2262,35 @@ static void queue_con(struct ceph_connec
    }
    }

    +static bool con_sock_closed(struct ceph_connection *con)
    +{
    + if (!test_and_clear_bit(CON_FLAG_SOCK_CLOSED, &con->flags))
    + return false;
    +
    +#define CASE(x) \
    + case CON_STATE_ ## x: \
    + con->error_msg = "socket closed (con state " #x ")"; \
    + break;
    +
    + switch (con->state) {
    + CASE(CLOSED);
    + CASE(PREOPEN);
    + CASE(CONNECTING);
    + CASE(NEGOTIATING);
    + CASE(OPEN);
    + CASE(STANDBY);
    + default:
    + pr_warning("%s con %p unrecognized state %lu\n",
    + __func__, con, con->state);
    + con->error_msg = "unrecognized con state";
    + BUG();
    + break;
    + }
    +#undef CASE
    +
    + return true;
    +}
    +
    /*
    * Do some work on a connection. Drop a connection ref when we're done.
    */
    @@ -2273,24 +2302,8 @@ static void con_work(struct work_struct

    mutex_lock(&con->mutex);
    restart:
    - if (test_and_clear_bit(CON_FLAG_SOCK_CLOSED, &con->flags)) {
    - switch (con->state) {
    - case CON_STATE_CONNECTING:
    - con->error_msg = "connection failed";
    - break;
    - case CON_STATE_NEGOTIATING:
    - con->error_msg = "negotiation failed";
    - break;
    - case CON_STATE_OPEN:
    - con->error_msg = "socket closed";
    - break;
    - default:
    - dout("unrecognized con state %d\n", (int)con->state);
    - con->error_msg = "unrecognized con state";
    - BUG();
    - }
    + if (con_sock_closed(con))
    goto fault;
    - }

    if (test_and_clear_bit(CON_FLAG_BACKOFF, &con->flags)) {
    dout("con_work %p backing off\n", con);



    \
     
     \ /
      Last update: 2013-01-16 00:41    [W:4.265 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site