md: fix deadlock between mddev_suspend() and md_write_start()
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:Nix <nix@esperi.org.uk> Fix: 68866e42(MD: no sync IO while suspended) Cc: stable@vger.kernel.org Signed-off-by:
NeilBrown <neilb@suse.com> Signed-off-by:
Shaohua Li <shli@fb.com>
Showing
- drivers/md/faulty.c 3 additions, 2 deletionsdrivers/md/faulty.c
- drivers/md/linear.c 4 additions, 3 deletionsdrivers/md/linear.c
- drivers/md/md.c 17 additions, 5 deletionsdrivers/md/md.c
- drivers/md/md.h 2 additions, 2 deletionsdrivers/md/md.h
- drivers/md/multipath.c 4 additions, 4 deletionsdrivers/md/multipath.c
- drivers/md/raid0.c 4 additions, 3 deletionsdrivers/md/raid0.c
- drivers/md/raid1.c 7 additions, 4 deletionsdrivers/md/raid1.c
- drivers/md/raid10.c 6 additions, 4 deletionsdrivers/md/raid10.c
- drivers/md/raid5.c 9 additions, 8 deletionsdrivers/md/raid5.c
Loading
Please register or sign in to comment