md: make ->congested robust against personality changes.
authorNeilBrown <neilb@suse.de>
Mon, 15 Dec 2014 01:56:56 +0000 (12:56 +1100)
committerNeilBrown <neilb@suse.de>
Tue, 3 Feb 2015 21:35:52 +0000 (08:35 +1100)
commit5c675f83c68fbdf9c0e103c1090b06be747fa62c
tree9a03f84c7a3bcef7d5e757dc28ce7bd5d205b26a
parent85572d7c75fd5b9fa3fc911e1c99c68ec74903a0
md: make ->congested robust against personality changes.

There is currently no locking around calls to the 'congested'
bdi function.  If called at an awkward time while an array is
being converted from one level (or personality) to another, there
is a tiny chance of running code in an unreferenced module etc.

So add a 'congested' function to the md_personality operations
structure, and call it with appropriate locking from a central
'mddev_congested'.

When the array personality is changing the array will be 'suspended'
so no IO is processed.
If mddev_congested detects this, it simply reports that the
array is congested, which is a safe guess.
As mddev_suspend calls synchronize_rcu(), mddev_congested can
avoid races by included the whole call inside an rcu_read_lock()
region.
This require that the congested functions for all subordinate devices
can be run under rcu_lock.  Fortunately this is the case.

Signed-off-by: NeilBrown <neilb@suse.de>
12 files changed:
drivers/md/dm-raid.c
drivers/md/linear.c
drivers/md/md.c
drivers/md/md.h
drivers/md/multipath.c
drivers/md/raid0.c
drivers/md/raid1.c
drivers/md/raid1.h
drivers/md/raid10.c
drivers/md/raid10.h
drivers/md/raid5.c
drivers/md/raid5.h