md: close a race with setting mddev->in_sync
authorNeilBrown <neilb@suse.com>
Wed, 15 Mar 2017 03:05:14 +0000 (14:05 +1100)
committerShaohua Li <shli@fb.com>
Thu, 23 Mar 2017 02:18:30 +0000 (19:18 -0700)
commit55cc39f345256af241deb6152ff5c06bedd10f11
tree9d6958f5b6960b3ba9010aa0d23bbe9c3feb5ff2
parent6497709b5d1bccce7de1df678d5f147d614551d1
md: close a race with setting mddev->in_sync

If ->in_sync is being set just as md_write_start() is being called,
it is possible that set_in_sync() won't see the elevated
->writes_pending, and md_write_start() won't see the set ->in_sync.

To close this race, re-test ->writes_pending after setting ->in_sync,
and add memory barriers to ensure the increment of ->writes_pending
will be seen by the time of this second test, or the new ->in_sync
will be seen by md_write_start().

Add a spinlock to array_state_show() to ensure this temporary
instability is never visible from userspace.

Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: Shaohua Li <shli@fb.com>
drivers/md/md.c