lkml.org 
[lkml]   [2019]   [Aug]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.14 40/62] libceph: fix PG split vs OSD (re)connect race
    Date
    From: Ilya Dryomov <idryomov@gmail.com>

    commit a561372405cf6bc6f14239b3a9e57bb39f2788b0 upstream.

    We can't rely on ->peer_features in calc_target() because it may be
    called both when the OSD session is established and open and when it's
    not. ->peer_features is not valid unless the OSD session is open. If
    this happens on a PG split (pg_num increase), that could mean we don't
    resend a request that should have been resent, hanging the client
    indefinitely.

    In userspace this was fixed by looking at require_osd_release and
    get_xinfo[osd].features fields of the osdmap. However these fields
    belong to the OSD section of the osdmap, which the kernel doesn't
    decode (only the client section is decoded).

    Instead, let's drop this feature check. It effectively checks for
    luminous, so only pre-luminous OSDs would be affected in that on a PG
    split the kernel might resend a request that should not have been
    resent. Duplicates can occur in other scenarios, so both sides should
    already be prepared for them: see dup/replay logic on the OSD side and
    retry_attempt check on the client side.

    Cc: stable@vger.kernel.org
    Fixes: 7de030d6b10a ("libceph: resend on PG splits if OSD has RESEND_ON_SPLIT")
    Link: https://tracker.ceph.com/issues/41162
    Reported-by: Jerry Lee <leisurelysw24@gmail.com>
    Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
    Tested-by: Jerry Lee <leisurelysw24@gmail.com>
    Reviewed-by: Jeff Layton <jlayton@kernel.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    net/ceph/osd_client.c | 9 ++++-----
    1 file changed, 4 insertions(+), 5 deletions(-)

    --- a/net/ceph/osd_client.c
    +++ b/net/ceph/osd_client.c
    @@ -1330,7 +1330,7 @@ static enum calc_target_result calc_targ
    struct ceph_osds up, acting;
    bool force_resend = false;
    bool unpaused = false;
    - bool legacy_change;
    + bool legacy_change = false;
    bool split = false;
    bool sort_bitwise = ceph_osdmap_flag(osdc, CEPH_OSDMAP_SORTBITWISE);
    bool recovery_deletes = ceph_osdmap_flag(osdc,
    @@ -1426,15 +1426,14 @@ static enum calc_target_result calc_targ
    t->osd = acting.primary;
    }

    - if (unpaused || legacy_change || force_resend ||
    - (split && con && CEPH_HAVE_FEATURE(con->peer_features,
    - RESEND_ON_SPLIT)))
    + if (unpaused || legacy_change || force_resend || split)
    ct_res = CALC_TARGET_NEED_RESEND;
    else
    ct_res = CALC_TARGET_NO_ACTION;

    out:
    - dout("%s t %p -> ct_res %d osd %d\n", __func__, t, ct_res, t->osd);
    + dout("%s t %p -> %d%d%d%d ct_res %d osd%d\n", __func__, t, unpaused,
    + legacy_change, force_resend, split, ct_res, t->osd);
    return ct_res;
    }


    \
     
     \ /
      Last update: 2019-08-27 09:54    [W:9.351 / U:0.028 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site