Skip to content

Commit

Permalink
dm: fix handling of multiple internal suspends
Browse files Browse the repository at this point in the history
Commit ffcc393 ("dm: enhance internal suspend and resume interface")
attempted to handle multiple internal suspends on the same device, but
it did that incorrectly.  When these functions are called in this order
on the same device the device is no longer suspended, but it should be:
	dm_internal_suspend_noflush
	dm_internal_suspend_noflush
	dm_internal_resume

Fix this bug by maintaining an 'internal_suspend_count' and resuming
the device when this count drops to zero.

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
  • Loading branch information
Mikulas Patocka authored and Mike Snitzer committed Jan 24, 2015
1 parent a59db67 commit 96b26c8
Showing 1 changed file with 7 additions and 2 deletions.
9 changes: 7 additions & 2 deletions drivers/md/dm.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,9 @@ struct mapped_device {
/* zero-length flush that will be cloned and submitted to targets */
struct bio flush_bio;

/* the number of internal suspends */
unsigned internal_suspend_count;

struct dm_stats stats;
};

Expand Down Expand Up @@ -2928,7 +2931,7 @@ static void __dm_internal_suspend(struct mapped_device *md, unsigned suspend_fla
{
struct dm_table *map = NULL;

if (dm_suspended_internally_md(md))
if (md->internal_suspend_count++)
return; /* nested internal suspend */

if (dm_suspended_md(md)) {
Expand All @@ -2953,7 +2956,9 @@ static void __dm_internal_suspend(struct mapped_device *md, unsigned suspend_fla

static void __dm_internal_resume(struct mapped_device *md)
{
if (!dm_suspended_internally_md(md))
BUG_ON(!md->internal_suspend_count);

if (--md->internal_suspend_count)
return; /* resume from nested internal suspend */

if (dm_suspended_md(md))
Expand Down

0 comments on commit 96b26c8

Please sign in to comment.