diff options
author | Joe Thornber <ejt@redhat.com> | 2015-09-01 12:38:19 +0200 |
---|---|---|
committer | Mike Snitzer <snitzer@redhat.com> | 2015-09-01 14:56:14 +0200 |
commit | cc7da0ba9c96699592d0a69d7d146ac6adcc18e7 (patch) | |
tree | 84a021e91e6bb4a9e395315fcf4a80bfc3f3fd51 /drivers | |
parent | dm cache: small cleanups related to deferred prison cell cleanup (diff) | |
download | linux-cc7da0ba9c96699592d0a69d7d146ac6adcc18e7.tar.xz linux-cc7da0ba9c96699592d0a69d7d146ac6adcc18e7.zip |
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')
-rw-r--r-- | drivers/md/dm-cache-target.c | 15 |
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) static void free_io_migration(struct dm_cache_migration *mg) { - dec_io_migrations(mg->cache); + struct cache *cache = mg->cache; + + dec_io_migrations(cache); free_migration(mg); - wake_worker(mg->cache); + wake_worker(cache); } static void migration_failure(struct dm_cache_migration *mg) @@ -1342,17 +1344,18 @@ static void issue_discard(struct dm_cache_migration *mg) { dm_dblock_t b, e; struct bio *bio = mg->new_ocell->holder; + struct cache *cache = mg->cache; - calc_discard_block_range(mg->cache, bio, &b, &e); + calc_discard_block_range(cache, bio, &b, &e); while (b != e) { - set_discard(mg->cache, b); + set_discard(cache, b); b = to_dblock(from_dblock(b) + 1); } bio_endio(bio, 0); - cell_defer(mg->cache, mg->new_ocell, false); + cell_defer(cache, mg->new_ocell, false); free_migration(mg); - wake_worker(mg->cache); + wake_worker(cache); } static void issue_copy_or_discard(struct dm_cache_migration *mg) |