• NeilBrown's avatar
    md: only allow remove_and_add_spares when no sync_thread running. · 39772f0a
    NeilBrown authored
    The locking protocols in md assume that a device will
    never be removed from an array during resync/recovery/reshape.
    When that isn't happening, rcu or reconfig_mutex is needed
    to protect an rdev pointer while taking a refcount.  When
    it is happening, that protection isn't needed.
    
    Unfortunately there are cases were remove_and_add_spares() is
    called when recovery might be happening: is state_store(),
    slot_store() and hot_remove_disk().
    In each case, this is just an optimization, to try to expedite
    removal from the personality so the device can be removed from
    the array.  If resync etc is happening, we just have to wait
    for md_check_recover to find a suitable time to call
    remove_and_add_spares().
    
    This optimization and not essential so it doesn't
    matter if it fails.
    So change remove_and_add_spares() to abort early if
    resync/recovery/reshape is happening, unless it is called
    from md_check_recovery() as part of a newly started recovery.
    The parameter "this" is only NULL when called from
    md_check_recovery() so when it is NULL, there is no need to abort.
    
    As this can result in a NULL dereference, the fix is suitable
    for -stable.
    
    cc: yuyufen <yuyufen@huawei.com>
    Cc: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
    Fixes: 8430e7e0 ("md: disconnect device from personality before trying to remove it.")
    Cc: stable@ver.kernel.org (v4.8+)
    Signed-off-by: default avatarNeilBrown <neilb@suse.com>
    Signed-off-by: default avatarShaohua Li <sh.li@alibaba-inc.com>
    39772f0a
md.c 244 KB