Commit 2c49ae54 authored by Joe Thornber's avatar Joe Thornber Committed by Jiri Slaby

dm thin: grab a virtual cell before looking up the mapping

commit c822ed96 upstream.

Avoids normal IO racing with discard.
Signed-off-by: default avatarJoe Thornber <ejt@redhat.com>
Signed-off-by: default avatarMike Snitzer <snitzer@redhat.com>
Signed-off-by: default avatarJiri Slaby <jslaby@suse.cz>
parent f0a72a0e
...@@ -1504,6 +1504,14 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio) ...@@ -1504,6 +1504,14 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio)
return DM_MAPIO_SUBMITTED; return DM_MAPIO_SUBMITTED;
} }
/*
* We must hold the virtual cell before doing the lookup, otherwise
* there's a race with discard.
*/
build_virtual_key(tc->td, block, &key);
if (dm_bio_detain(tc->pool->prison, &key, bio, &cell1, &cell_result))
return DM_MAPIO_SUBMITTED;
r = dm_thin_find_block(td, block, 0, &result); r = dm_thin_find_block(td, block, 0, &result);
/* /*
...@@ -1527,13 +1535,10 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio) ...@@ -1527,13 +1535,10 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio)
* shared flag will be set in their case. * shared flag will be set in their case.
*/ */
thin_defer_bio(tc, bio); thin_defer_bio(tc, bio);
cell_defer_no_holder_no_free(tc, &cell1);
return DM_MAPIO_SUBMITTED; return DM_MAPIO_SUBMITTED;
} }
build_virtual_key(tc->td, block, &key);
if (dm_bio_detain(tc->pool->prison, &key, bio, &cell1, &cell_result))
return DM_MAPIO_SUBMITTED;
build_data_key(tc->td, result.block, &key); build_data_key(tc->td, result.block, &key);
if (dm_bio_detain(tc->pool->prison, &key, bio, &cell2, &cell_result)) { if (dm_bio_detain(tc->pool->prison, &key, bio, &cell2, &cell_result)) {
cell_defer_no_holder_no_free(tc, &cell1); cell_defer_no_holder_no_free(tc, &cell1);
...@@ -1554,6 +1559,7 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio) ...@@ -1554,6 +1559,7 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio)
* of doing so. Just error it. * of doing so. Just error it.
*/ */
bio_io_error(bio); bio_io_error(bio);
cell_defer_no_holder_no_free(tc, &cell1);
return DM_MAPIO_SUBMITTED; return DM_MAPIO_SUBMITTED;
} }
/* fall through */ /* fall through */
...@@ -1564,6 +1570,7 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio) ...@@ -1564,6 +1570,7 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio)
* provide the hint to load the metadata into cache. * provide the hint to load the metadata into cache.
*/ */
thin_defer_bio(tc, bio); thin_defer_bio(tc, bio);
cell_defer_no_holder_no_free(tc, &cell1);
return DM_MAPIO_SUBMITTED; return DM_MAPIO_SUBMITTED;
default: default:
...@@ -1573,6 +1580,7 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio) ...@@ -1573,6 +1580,7 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio)
* pool is switched to fail-io mode. * pool is switched to fail-io mode.
*/ */
bio_io_error(bio); bio_io_error(bio);
cell_defer_no_holder_no_free(tc, &cell1);
return DM_MAPIO_SUBMITTED; return DM_MAPIO_SUBMITTED;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment