Skip to content

Commit c9f7cb5

Browse files
YuKuai-huaweiliu-song-6
authored andcommitted
md: don't leave 'MD_RECOVERY_FROZEN' in error path of md_set_readonly()
If md_set_readonly() failed, the array could still be read-write, however 'MD_RECOVERY_FROZEN' could still be set, which leave the array in an abnormal state that sync or recovery can't continue anymore. Hence make sure the flag is cleared after md_set_readonly() returns. Fixes: 88724bf ("md: wait for pending superblock updates before switching to read-only") Signed-off-by: Yu Kuai <yukuai3@huawei.com> Acked-by: Xiao Ni <xni@redhat.com> Signed-off-by: Song Liu <song@kernel.org> Link: https://lore.kernel.org/r/20231205094215.1824240-3-yukuai1@huaweicloud.com
1 parent f2d87a7 commit c9f7cb5

File tree

1 file changed

+13
-11
lines changed

1 file changed

+13
-11
lines changed

drivers/md/md.c

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6355,6 +6355,9 @@ static int md_set_readonly(struct mddev *mddev, struct block_device *bdev)
63556355
int err = 0;
63566356
int did_freeze = 0;
63576357

6358+
if (mddev->external && test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags))
6359+
return -EBUSY;
6360+
63586361
if (!test_bit(MD_RECOVERY_FROZEN, &mddev->recovery)) {
63596362
did_freeze = 1;
63606363
set_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
@@ -6369,8 +6372,6 @@ static int md_set_readonly(struct mddev *mddev, struct block_device *bdev)
63696372
*/
63706373
md_wakeup_thread_directly(mddev->sync_thread);
63716374

6372-
if (mddev->external && test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags))
6373-
return -EBUSY;
63746375
mddev_unlock(mddev);
63756376
wait_event(resync_wait, !test_bit(MD_RECOVERY_RUNNING,
63766377
&mddev->recovery));
@@ -6383,29 +6384,30 @@ static int md_set_readonly(struct mddev *mddev, struct block_device *bdev)
63836384
mddev->sync_thread ||
63846385
test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) {
63856386
pr_warn("md: %s still in use.\n",mdname(mddev));
6386-
if (did_freeze) {
6387-
clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
6388-
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
6389-
md_wakeup_thread(mddev->thread);
6390-
}
63916387
err = -EBUSY;
63926388
goto out;
63936389
}
6390+
63946391
if (mddev->pers) {
63956392
__md_stop_writes(mddev);
63966393

6397-
err = -ENXIO;
6398-
if (mddev->ro == MD_RDONLY)
6394+
if (mddev->ro == MD_RDONLY) {
6395+
err = -ENXIO;
63996396
goto out;
6397+
}
6398+
64006399
mddev->ro = MD_RDONLY;
64016400
set_disk_ro(mddev->gendisk, 1);
6401+
}
6402+
6403+
out:
6404+
if ((mddev->pers && !err) || did_freeze) {
64026405
clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
64036406
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
64046407
md_wakeup_thread(mddev->thread);
64056408
sysfs_notify_dirent_safe(mddev->sysfs_state);
6406-
err = 0;
64076409
}
6408-
out:
6410+
64096411
mutex_unlock(&mddev->open_mutex);
64106412
return err;
64116413
}

0 commit comments

Comments
 (0)