diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-01-25 17:25:01 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-01-25 17:25:01 -0800 |
commit | bfc835b5716fd86b568d4f9b15be04c4f361082b (patch) | |
tree | 7269b5dfd07dddfa3e5457ae804dbcb4a8694a65 /drivers/md/dm.c | |
parent | 8e908e990438173f44819bff3dcef8eba496ed97 (diff) | |
parent | 96b26c8c64c7a30488b8b404f7a63346df4c3bff (diff) | |
download | op-kernel-dev-bfc835b5716fd86b568d4f9b15be04c4f361082b.zip op-kernel-dev-bfc835b5716fd86b568d4f9b15be04c4f361082b.tar.gz |
Merge tag 'dm-3.19-fixes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm
Pull device mapper fixes from Mike Snitzer:
"Two stable fixes for dm-cache and one 3.19 DM core fix:
- fix potential for dm-cache metadata corruption via stale metadata
buffers being used when switching an inactive cache table to
active; this could occur due to each table having it's own bufio
client rather than sharing the client between tables.
- fix dm-cache target to properly account for discard IO while
suspending otherwise IO quiescing could complete prematurely.
- fix DM core's handling of multiple internal suspends by maintaining
an 'internal_suspend_count' and only resuming the device when this
count drops to zero"
* tag 'dm-3.19-fixes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm:
dm: fix handling of multiple internal suspends
dm cache: fix problematic dual use of a single migration count variable
dm cache: share cache-metadata object across inactive and active DM tables
Diffstat (limited to 'drivers/md/dm.c')
-rw-r--r-- | drivers/md/dm.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index b98cd9d..2caf5b3 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -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; }; @@ -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)) { @@ -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)) |