Commit b90f6ff0 authored by Artur Paszkiewicz's avatar Artur Paszkiewicz Committed by Shaohua Li

md: don't check MD_SB_CHANGE_CLEAN in md_allow_write

Only MD_SB_CHANGE_PENDING should be used to wait for transition from
clean to dirty. Checking also MD_SB_CHANGE_CLEAN is unnecessary and can
race with e.g. md_do_sync(). This sporadically causes a hang when
changing consistency policy during resync:

INFO: task mdadm:6183 blocked for more than 30 seconds.
      Not tainted 4.14.0-rc3+ #391
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
mdadm           D12752  6183   6022 0x00000000
Call Trace:
 md_allow_write+0x100/0x130 [md_mod]
 ? do_wait_intr_irq+0x90/0x90
 resize_stripes+0x3a/0x5b0 [raid456]
 ? kernfs_fop_write+0xbe/0x180
 raid5_change_consistency_policy+0xa6/0x200 [raid456]
 consistency_policy_store+0x2e/0x70 [md_mod]
 md_attr_store+0x90/0xc0 [md_mod]
 ? rcu_sync_lockdep_assert+0x12/0x60
 ? __sb_start_write+0x15a/0x1c0
 ? vfs_write+0xa3/0x1a0

Fixes: 2214c260 ("md: don't return -EAGAIN in md_allow_write for external metadata arrays")
Cc: <>
Signed-off-by: default avatarArtur Paszkiewicz <>
Signed-off-by: default avatarShaohua Li <>
parent f0e230ad
...@@ -8125,7 +8125,6 @@ void md_allow_write(struct mddev *mddev) ...@@ -8125,7 +8125,6 @@ void md_allow_write(struct mddev *mddev)
sysfs_notify_dirent_safe(mddev->sysfs_state); sysfs_notify_dirent_safe(mddev->sysfs_state);
/* wait for the dirty state to be recorded in the metadata */ /* wait for the dirty state to be recorded in the metadata */
wait_event(mddev->sb_wait, wait_event(mddev->sb_wait,
!test_bit(MD_SB_CHANGE_CLEAN, &mddev->sb_flags) &&
!test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)); !test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags));
} else } else
spin_unlock(&mddev->lock); spin_unlock(&mddev->lock);
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment