diff options
Diffstat (limited to 'drivers/md/dm-thin.c')
| -rw-r--r-- | drivers/md/dm-thin.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index 4843801173fe..0f86d802b533 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c | |||
| @@ -1936,6 +1936,14 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio) | |||
| 1936 | return DM_MAPIO_SUBMITTED; | 1936 | return DM_MAPIO_SUBMITTED; |
| 1937 | } | 1937 | } |
| 1938 | 1938 | ||
| 1939 | /* | ||
| 1940 | * We must hold the virtual cell before doing the lookup, otherwise | ||
| 1941 | * there's a race with discard. | ||
| 1942 | */ | ||
| 1943 | build_virtual_key(tc->td, block, &key); | ||
| 1944 | if (dm_bio_detain(tc->pool->prison, &key, bio, &cell1, &cell_result)) | ||
| 1945 | return DM_MAPIO_SUBMITTED; | ||
| 1946 | |||
| 1939 | r = dm_thin_find_block(td, block, 0, &result); | 1947 | r = dm_thin_find_block(td, block, 0, &result); |
| 1940 | 1948 | ||
| 1941 | /* | 1949 | /* |
| @@ -1959,13 +1967,10 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio) | |||
| 1959 | * shared flag will be set in their case. | 1967 | * shared flag will be set in their case. |
| 1960 | */ | 1968 | */ |
| 1961 | thin_defer_bio(tc, bio); | 1969 | thin_defer_bio(tc, bio); |
| 1970 | cell_defer_no_holder_no_free(tc, &cell1); | ||
| 1962 | return DM_MAPIO_SUBMITTED; | 1971 | return DM_MAPIO_SUBMITTED; |
| 1963 | } | 1972 | } |
| 1964 | 1973 | ||
| 1965 | build_virtual_key(tc->td, block, &key); | ||
| 1966 | if (dm_bio_detain(tc->pool->prison, &key, bio, &cell1, &cell_result)) | ||
| 1967 | return DM_MAPIO_SUBMITTED; | ||
| 1968 | |||
| 1969 | build_data_key(tc->td, result.block, &key); | 1974 | build_data_key(tc->td, result.block, &key); |
| 1970 | if (dm_bio_detain(tc->pool->prison, &key, bio, &cell2, &cell_result)) { | 1975 | if (dm_bio_detain(tc->pool->prison, &key, bio, &cell2, &cell_result)) { |
| 1971 | cell_defer_no_holder_no_free(tc, &cell1); | 1976 | cell_defer_no_holder_no_free(tc, &cell1); |
| @@ -1986,6 +1991,7 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio) | |||
| 1986 | * of doing so. | 1991 | * of doing so. |
| 1987 | */ | 1992 | */ |
| 1988 | handle_unserviceable_bio(tc->pool, bio); | 1993 | handle_unserviceable_bio(tc->pool, bio); |
| 1994 | cell_defer_no_holder_no_free(tc, &cell1); | ||
| 1989 | return DM_MAPIO_SUBMITTED; | 1995 | return DM_MAPIO_SUBMITTED; |
| 1990 | } | 1996 | } |
| 1991 | /* fall through */ | 1997 | /* fall through */ |
| @@ -1996,6 +2002,7 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio) | |||
| 1996 | * provide the hint to load the metadata into cache. | 2002 | * provide the hint to load the metadata into cache. |
| 1997 | */ | 2003 | */ |
| 1998 | thin_defer_bio(tc, bio); | 2004 | thin_defer_bio(tc, bio); |
| 2005 | cell_defer_no_holder_no_free(tc, &cell1); | ||
| 1999 | return DM_MAPIO_SUBMITTED; | 2006 | return DM_MAPIO_SUBMITTED; |
| 2000 | 2007 | ||
| 2001 | default: | 2008 | default: |
| @@ -2005,6 +2012,7 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio) | |||
| 2005 | * pool is switched to fail-io mode. | 2012 | * pool is switched to fail-io mode. |
| 2006 | */ | 2013 | */ |
| 2007 | bio_io_error(bio); | 2014 | bio_io_error(bio); |
| 2015 | cell_defer_no_holder_no_free(tc, &cell1); | ||
| 2008 | return DM_MAPIO_SUBMITTED; | 2016 | return DM_MAPIO_SUBMITTED; |
| 2009 | } | 2017 | } |
| 2010 | } | 2018 | } |
