• Lars Ellenberg's avatar
    drbd: cleanup bogus assert message · 9114d795
    Lars Ellenberg authored
    This fixes ASSERT( mdev->state.disk == D_FAILED ) in drivers/block/drbd/drbd_main.c
    
    When we detach from local disk, we let the local refcount hit zero twice.
    
    First, we transition to D_FAILED, so we won't give out new references
    to incoming requests; we still may give out *internal* references, though.
    Once the refcount hits zero [1] while in D_FAILED, we queue a transition
    to D_DISKLESS to our worker.  We need to queue it, because we may be in
    atomic context when putting the reference.
    Once the transition to D_DISKLESS actually happened [2] from worker context,
    we don't give out new internal references either.
    
    Between hitting zero the first time [1] and actually transition to
    D_DISKLESS [2], there may be a few very short lived internal get/put,
    so we may hit zero more than once while being in D_FAILED, or even see a
    race where a an internal get_ldev() happened while D_FAILED, but the
    corresponding put_ldev() happens just after the transition to D_DISKLESS.
    
    That's why we have the additional test_and_set_bit(GO_DISKLESS,);
    and that's why the assert was placed wrong.
    Since there was exactly one code path left to drbd_go_diskless(),
    and that checks already for D_FAILED, drop that assert,
    and fold in the drbd_queue_work().
    Signed-off-by: default avatarPhilipp Reisner <philipp.reisner@linbit.com>
    Signed-off-by: default avatarLars Ellenberg <lars.ellenberg@linbit.com>
    Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
    9114d795
drbd_int.h 76.1 KB