]> git.karo-electronics.de Git - karo-tx-linux.git/commit
md: take a reference to mddev during sysfs access.
authorNeilBrown <neilb@suse.de>
Wed, 9 Nov 2011 00:32:05 +0000 (11:32 +1100)
committerNeilBrown <neilb@suse.de>
Wed, 9 Nov 2011 00:32:05 +0000 (11:32 +1100)
commit733cfef05c8761dbb95d7a0e0736e9c8b7a88a27
tree3d21e0a221414b9940510343e71e99600be77edb
parent01e25c4bbe472652f4712dace37e42d6a8212c28
md: take a reference to mddev during sysfs access.

When we are accessing an mddev via sysfs we know that the
mddev cannot disappear because it has an embedded kobj which
is refcounted by sysfs.
And we also take the mddev_lock.
However this is not enough.

The final mddev_put could have been called and the
mddev_delayed_delete is waiting for sysfs to let go so it can destroy
the kobj and mddev.
In this state there are a lot of changes that should not be attempted.

To to guard against this we:
 - initialise mddev->all_mddevs in on last put so the state can be
   easily detected.
 - in md_attr_show and md_attr_store, check ->all_mddevs under
   all_mddevs_lock and mddev_get the mddev if it still appears to
   be active.

This means that if we get to sysfs as the mddev is being deleted we
will get -EBUSY.

rdev_attr_store and rdev_attr_show are similar but already have
sufficient protection.  They check that rdev->mddev still points to
mddev after taking mddev_lock.  As this is cleared  before delayed
removal which can only be requested under the mddev_lock, this
ensure the rdev and mddev are still alive.

Signed-off-by: NeilBrown <neilb@suse.de>
drivers/md/md.c