aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/dm.c')
-rw-r--r--drivers/md/dm.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 73f28802dc7a..9b641b38b857 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -2616,6 +2616,19 @@ void dm_get(struct mapped_device *md)
2616 BUG_ON(test_bit(DMF_FREEING, &md->flags)); 2616 BUG_ON(test_bit(DMF_FREEING, &md->flags));
2617} 2617}
2618 2618
2619int dm_hold(struct mapped_device *md)
2620{
2621 spin_lock(&_minor_lock);
2622 if (test_bit(DMF_FREEING, &md->flags)) {
2623 spin_unlock(&_minor_lock);
2624 return -EBUSY;
2625 }
2626 dm_get(md);
2627 spin_unlock(&_minor_lock);
2628 return 0;
2629}
2630EXPORT_SYMBOL_GPL(dm_hold);
2631
2619const char *dm_device_name(struct mapped_device *md) 2632const char *dm_device_name(struct mapped_device *md)
2620{ 2633{
2621 return md->name; 2634 return md->name;
@@ -2638,10 +2651,16 @@ static void __dm_destroy(struct mapped_device *md, bool wait)
2638 if (dm_request_based(md)) 2651 if (dm_request_based(md))
2639 flush_kthread_worker(&md->kworker); 2652 flush_kthread_worker(&md->kworker);
2640 2653
2654 /*
2655 * Take suspend_lock so that presuspend and postsuspend methods
2656 * do not race with internal suspend.
2657 */
2658 mutex_lock(&md->suspend_lock);
2641 if (!dm_suspended_md(md)) { 2659 if (!dm_suspended_md(md)) {
2642 dm_table_presuspend_targets(map); 2660 dm_table_presuspend_targets(map);
2643 dm_table_postsuspend_targets(map); 2661 dm_table_postsuspend_targets(map);
2644 } 2662 }
2663 mutex_unlock(&md->suspend_lock);
2645 2664
2646 /* dm_put_live_table must be before msleep, otherwise deadlock is possible */ 2665 /* dm_put_live_table must be before msleep, otherwise deadlock is possible */
2647 dm_put_live_table(md, srcu_idx); 2666 dm_put_live_table(md, srcu_idx);
@@ -3115,6 +3134,7 @@ void dm_internal_suspend_fast(struct mapped_device *md)
3115 flush_workqueue(md->wq); 3134 flush_workqueue(md->wq);
3116 dm_wait_for_completion(md, TASK_UNINTERRUPTIBLE); 3135 dm_wait_for_completion(md, TASK_UNINTERRUPTIBLE);
3117} 3136}
3137EXPORT_SYMBOL_GPL(dm_internal_suspend_fast);
3118 3138
3119void dm_internal_resume_fast(struct mapped_device *md) 3139void dm_internal_resume_fast(struct mapped_device *md)
3120{ 3140{
@@ -3126,6 +3146,7 @@ void dm_internal_resume_fast(struct mapped_device *md)
3126done: 3146done:
3127 mutex_unlock(&md->suspend_lock); 3147 mutex_unlock(&md->suspend_lock);
3128} 3148}
3149EXPORT_SYMBOL_GPL(dm_internal_resume_fast);
3129 3150
3130/*----------------------------------------------------------------- 3151/*-----------------------------------------------------------------
3131 * Event notification. 3152 * Event notification.