diff options
author | Kiyoshi Ueda <k-ueda@ct.jp.nec.com> | 2010-03-06 03:29:52 +0100 |
---|---|---|
committer | Alasdair G Kergon <agk@redhat.com> | 2010-03-06 03:29:52 +0100 |
commit | ecdb2e257abc33ae6798d3ccba87bdafa40ef6b6 (patch) | |
tree | 497db6a95a9f06270506f6a75354d5df855d5a66 /drivers/md/dm-table.c | |
parent | dm mpath: skip activate_path for failed paths (diff) | |
download | linux-ecdb2e257abc33ae6798d3ccba87bdafa40ef6b6.tar.xz linux-ecdb2e257abc33ae6798d3ccba87bdafa40ef6b6.zip |
dm table: remove dm_get from dm_table_get_md
Remove the dm_get() in dm_table_get_md() because dm_table_get_md() could
be called from presuspend/postsuspend, which are called while
mapped_device is in DMF_FREEING state, where dm_get() is not allowed.
Justification for that is the lifetime of both objects: As far as the
current dm design/implementation, mapped_device is never freed while
targets are doing something, because dm core waits for targets to become
quiet in dm_put() using presuspend/postsuspend. So targets should be
able to touch mapped_device without holding reference count of the
mapped_device, and we should allow targets to touch mapped_device even
if it is in DMF_FREEING state.
Backgrounds:
I'm trying to remove the multipath internal queue, since dm core now has
a generic queue for request-based dm. In the patch-set, the multipath
target wants to request dm core to start/stop queue. One of such
start/stop requests can happen during postsuspend() while the target
waits for pg-init to complete, because the target stops queue when
starting pg-init and tries to restart it when completing pg-init. Since
queue belongs to mapped_device, it involves calling dm_table_get_md()
and dm_put(). On the other hand, postsuspend() is called in dm_put()
for mapped_device which is in DMF_FREEING state, and that triggers
BUG_ON(DMF_FREEING) in the 2nd dm_put().
I had tried to solve this problem by changing only multipath not to
touch mapped_device which is in DMF_FREEING state, but I couldn't and I
came up with a question why we need dm_get() in dm_table_get_md().
Signed-off-by: Kiyoshi Ueda <k-ueda@ct.jp.nec.com>
Signed-off-by: Jun'ichi Nomura <j-nomura@ce.jp.nec.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers/md/dm-table.c')
-rw-r--r-- | drivers/md/dm-table.c | 2 |
1 files changed, 0 insertions, 2 deletions
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 4b22feb01a0c..7d70cca585ac 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -1231,8 +1231,6 @@ void dm_table_unplug_all(struct dm_table *t) struct mapped_device *dm_table_get_md(struct dm_table *t) { - dm_get(t->md); - return t->md; } |