aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-cache-target.c
diff options
context:
space:
mode:
authorJoe Thornber <ejt@redhat.com>2015-09-01 06:38:19 -0400
committerMike Snitzer <snitzer@redhat.com>2015-09-01 08:56:14 -0400
commitcc7da0ba9c96699592d0a69d7d146ac6adcc18e7 (patch)
tree84a021e91e6bb4a9e395315fcf4a80bfc3f3fd51 /drivers/md/dm-cache-target.c
parentdc9cee5db50afaf38506bc12eb479fb8ea536dba (diff)
dm cache: fix use after freeing migrations
Both free_io_migration() and issue_discard() dereference a migration that was just freed. Fix those by saving off the migrations's cache object before freeing the migration. Also cleanup needless mg->cache dereferences now that the cache object is available directly. Fixes: e44b6a5a3c ("dm cache: move wake_waker() from free_migrations() to where it is needed") Signed-off-by: Joe Thornber <ejt@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Diffstat (limited to 'drivers/md/dm-cache-target.c')
-rw-r--r--drivers/md/dm-cache-target.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c
index e13e5edf2298..f9d9cc6a094b 100644
--- a/drivers/md/dm-cache-target.c
+++ b/drivers/md/dm-cache-target.c
@@ -1113,9 +1113,11 @@ static void cell_requeue(struct cache *cache, struct dm_bio_prison_cell *cell)
1113 1113
1114static void free_io_migration(struct dm_cache_migration *mg) 1114static void free_io_migration(struct dm_cache_migration *mg)
1115{ 1115{
1116 dec_io_migrations(mg->cache); 1116 struct cache *cache = mg->cache;
1117
1118 dec_io_migrations(cache);
1117 free_migration(mg); 1119 free_migration(mg);
1118 wake_worker(mg->cache); 1120 wake_worker(cache);
1119} 1121}
1120 1122
1121static void migration_failure(struct dm_cache_migration *mg) 1123static void migration_failure(struct dm_cache_migration *mg)
@@ -1342,17 +1344,18 @@ static void issue_discard(struct dm_cache_migration *mg)
1342{ 1344{
1343 dm_dblock_t b, e; 1345 dm_dblock_t b, e;
1344 struct bio *bio = mg->new_ocell->holder; 1346 struct bio *bio = mg->new_ocell->holder;
1347 struct cache *cache = mg->cache;
1345 1348
1346 calc_discard_block_range(mg->cache, bio, &b, &e); 1349 calc_discard_block_range(cache, bio, &b, &e);
1347 while (b != e) { 1350 while (b != e) {
1348 set_discard(mg->cache, b); 1351 set_discard(cache, b);
1349 b = to_dblock(from_dblock(b) + 1); 1352 b = to_dblock(from_dblock(b) + 1);
1350 } 1353 }
1351 1354
1352 bio_endio(bio, 0); 1355 bio_endio(bio, 0);
1353 cell_defer(mg->cache, mg->new_ocell, false); 1356 cell_defer(cache, mg->new_ocell, false);
1354 free_migration(mg); 1357 free_migration(mg);
1355 wake_worker(mg->cache); 1358 wake_worker(cache);
1356} 1359}
1357 1360
1358static void issue_copy_or_discard(struct dm_cache_migration *mg) 1361static void issue_copy_or_discard(struct dm_cache_migration *mg)