• NeilBrown's avatar
    md: fix deadlock between mddev_suspend() and md_write_start() · cc27b0c7
    NeilBrown authored
    If mddev_suspend() races with md_write_start() we can deadlock
    with mddev_suspend() waiting for the request that is currently
    in md_write_start() to complete the ->make_request() call,
    and md_write_start() waiting for the metadata to be updated
    to mark the array as 'dirty'.
    As metadata updates done by md_check_recovery() only happen then
    the mddev_lock() can be claimed, and as mddev_suspend() is often
    called with the lock held, these threads wait indefinitely for each
    other.
    
    We fix this by having md_write_start() abort if mddev_suspend()
    is happening, and ->make_request() aborts if md_write_start()
    aborted.
    md_make_request() can detect this abort, decrease the ->active_io
    count, and wait for mddev_suspend().
    Reported-by: default avatarNix <nix@esperi.org.uk>
    Fix: 68866e42(MD: no sync IO while suspended)
    Cc: stable@vger.kernel.org
    Signed-off-by: default avatarNeilBrown <neilb@suse.com>
    Signed-off-by: default avatarShaohua Li <shli@fb.com>
    cc27b0c7
md.c 241 KB