diff options
author | NeilBrown <neilb@suse.de> | 2012-07-19 15:59:18 +1000 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2012-07-19 15:59:18 +1000 |
commit | a05b7ea03d72f36edb0cec05e8893803335c61a0 (patch) | |
tree | 2b35d0dd6d5edebf22f8ab2ff3eca5f28af6e7c8 /drivers/md/raid1.c | |
parent | 25f7fd470bc97bb93d3a674e8c56c4a29063ec97 (diff) | |
download | lwn-a05b7ea03d72f36edb0cec05e8893803335c61a0.tar.gz lwn-a05b7ea03d72f36edb0cec05e8893803335c61a0.zip |
md: avoid crash when stopping md array races with closing other open fds.
md will refuse to stop an array if any other fd (or mounted fs) is
using it.
When any fs is unmounted of when the last open fd is closed all
pending IO will be flushed (e.g. sync_blockdev call in __blkdev_put)
so there will be no pending IO to worry about when the array is
stopped.
However in order to send the STOP_ARRAY ioctl to stop the array one
must first get and open fd on the block device.
If some fd is being used to write to the block device and it is closed
after mdadm open the block device, but before mdadm issues the
STOP_ARRAY ioctl, then there will be no last-close on the md device so
__blkdev_put will not call sync_blockdev.
If this happens, then IO can still be in-flight while md tears down
the array and bad things can happen (use-after-free and subsequent
havoc).
So in the case where do_md_stop is being called from an open file
descriptor, call sync_block after taking the mutex to ensure there
will be no new openers.
This is needed when setting a read-write device to read-only too.
Cc: stable@vger.kernel.org
Reported-by: majianpeng <majianpeng@gmail.com>
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/raid1.c')
0 files changed, 0 insertions, 0 deletions