diff options
author | Li Nan <linan122@huawei.com> | 2024-02-26 11:14:42 +0800 |
---|---|---|
committer | Song Liu <song@kernel.org> | 2024-02-26 10:22:22 -0800 |
commit | 99b902ac17253ee65d23012e2be390c026b77fa4 (patch) | |
tree | b1d68ee1df7c4b43b1bbcd1e7245f037cfe941c9 /drivers/md/md.c | |
parent | f74aaf614e84d8e5767a062e1172b4907c7b775e (diff) | |
download | linux-99b902ac17253ee65d23012e2be390c026b77fa4.tar.gz linux-99b902ac17253ee65d23012e2be390c026b77fa4.tar.bz2 linux-99b902ac17253ee65d23012e2be390c026b77fa4.zip |
md: sync blockdev before stopping raid or setting readonly
Commit a05b7ea03d72 ("md: avoid crash when stopping md array races
with closing other open fds.") added sync_block before stopping raid and
setting readonly. Later in commit 260fa034ef7a ("md: avoid deadlock when
dirty buffers during md_stop.") it is moved to ioctl. array_state_store()
was ignored. Add sync blockdev to array_state_store() now.
Signed-off-by: Li Nan <linan122@huawei.com>
Signed-off-by: Song Liu <song@kernel.org>
Link: https://lore.kernel.org/r/20240226031444.3606764-8-linan666@huaweicloud.com
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r-- | drivers/md/md.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 4d58e3496d16..3b653e68db0c 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -4500,6 +4500,17 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len) case broken: /* cannot be set */ case bad_word: return -EINVAL; + case clear: + case readonly: + case inactive: + case read_auto: + if (!mddev->pers || !md_is_rdwr(mddev)) + break; + /* write sysfs will not open mddev and opener should be 0 */ + err = mddev_set_closing_and_sync_blockdev(mddev, 0); + if (err) + return err; + break; default: break; } @@ -4599,6 +4610,11 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len) sysfs_notify_dirent_safe(mddev->sysfs_state); } mddev_unlock(mddev); + + if (st == readonly || st == read_auto || st == inactive || + (err && st == clear)) + clear_bit(MD_CLOSING, &mddev->flags); + return err ?: len; } static struct md_sysfs_entry md_array_state = |