summaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-uevent.c
diff options
context:
space:
mode:
authorKiyoshi Ueda <k-ueda@ct.jp.nec.com>2010-03-06 02:29:52 +0000
committerAlasdair G Kergon <agk@redhat.com>2010-03-06 02:29:52 +0000
commitecdb2e257abc33ae6798d3ccba87bdafa40ef6b6 (patch)
tree497db6a95a9f06270506f6a75354d5df855d5a66 /drivers/md/dm-uevent.c
parentf7b934c8127deebf4eb56fbe4a4ae0da16b6dbcd (diff)
downloadop-kernel-dev-ecdb2e257abc33ae6798d3ccba87bdafa40ef6b6.zip
op-kernel-dev-ecdb2e257abc33ae6798d3ccba87bdafa40ef6b6.tar.gz
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-uevent.c')
-rw-r--r--drivers/md/dm-uevent.c7
1 files changed, 2 insertions, 5 deletions
diff --git a/drivers/md/dm-uevent.c b/drivers/md/dm-uevent.c
index c7c555a..6b1e3b6 100644
--- a/drivers/md/dm-uevent.c
+++ b/drivers/md/dm-uevent.c
@@ -187,7 +187,7 @@ void dm_path_uevent(enum dm_uevent_type event_type, struct dm_target *ti,
if (event_type >= ARRAY_SIZE(_dm_uevent_type_names)) {
DMERR("%s: Invalid event_type %d", __func__, event_type);
- goto out;
+ return;
}
event = dm_build_path_uevent(md, ti,
@@ -195,12 +195,9 @@ void dm_path_uevent(enum dm_uevent_type event_type, struct dm_target *ti,
_dm_uevent_type_names[event_type].name,
path, nr_valid_paths);
if (IS_ERR(event))
- goto out;
+ return;
dm_uevent_add(md, &event->elist);
-
-out:
- dm_put(md);
}
EXPORT_SYMBOL_GPL(dm_path_uevent);
OpenPOWER on IntegriCloud