diff options
Diffstat (limited to 'drivers/md/dm-thin.c')
-rw-r--r-- | drivers/md/dm-thin.c | 39 |
1 files changed, 25 insertions, 14 deletions
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index faaf944597ab..7e84baccf0ad 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c | |||
@@ -1357,7 +1357,8 @@ static void process_deferred_bios(struct pool *pool) | |||
1357 | bio_list_init(&pool->deferred_flush_bios); | 1357 | bio_list_init(&pool->deferred_flush_bios); |
1358 | spin_unlock_irqrestore(&pool->lock, flags); | 1358 | spin_unlock_irqrestore(&pool->lock, flags); |
1359 | 1359 | ||
1360 | if (bio_list_empty(&bios) && !need_commit_due_to_time(pool)) | 1360 | if (bio_list_empty(&bios) && |
1361 | !(dm_pool_changed_this_transaction(pool->pmd) && need_commit_due_to_time(pool))) | ||
1361 | return; | 1362 | return; |
1362 | 1363 | ||
1363 | if (commit(pool)) { | 1364 | if (commit(pool)) { |
@@ -1999,16 +2000,27 @@ static void metadata_low_callback(void *context) | |||
1999 | dm_table_event(pool->ti->table); | 2000 | dm_table_event(pool->ti->table); |
2000 | } | 2001 | } |
2001 | 2002 | ||
2002 | static sector_t get_metadata_dev_size(struct block_device *bdev) | 2003 | static sector_t get_dev_size(struct block_device *bdev) |
2004 | { | ||
2005 | return i_size_read(bdev->bd_inode) >> SECTOR_SHIFT; | ||
2006 | } | ||
2007 | |||
2008 | static void warn_if_metadata_device_too_big(struct block_device *bdev) | ||
2003 | { | 2009 | { |
2004 | sector_t metadata_dev_size = i_size_read(bdev->bd_inode) >> SECTOR_SHIFT; | 2010 | sector_t metadata_dev_size = get_dev_size(bdev); |
2005 | char buffer[BDEVNAME_SIZE]; | 2011 | char buffer[BDEVNAME_SIZE]; |
2006 | 2012 | ||
2007 | if (metadata_dev_size > THIN_METADATA_MAX_SECTORS_WARNING) { | 2013 | if (metadata_dev_size > THIN_METADATA_MAX_SECTORS_WARNING) |
2008 | DMWARN("Metadata device %s is larger than %u sectors: excess space will not be used.", | 2014 | DMWARN("Metadata device %s is larger than %u sectors: excess space will not be used.", |
2009 | bdevname(bdev, buffer), THIN_METADATA_MAX_SECTORS); | 2015 | bdevname(bdev, buffer), THIN_METADATA_MAX_SECTORS); |
2010 | metadata_dev_size = THIN_METADATA_MAX_SECTORS_WARNING; | 2016 | } |
2011 | } | 2017 | |
2018 | static sector_t get_metadata_dev_size(struct block_device *bdev) | ||
2019 | { | ||
2020 | sector_t metadata_dev_size = get_dev_size(bdev); | ||
2021 | |||
2022 | if (metadata_dev_size > THIN_METADATA_MAX_SECTORS) | ||
2023 | metadata_dev_size = THIN_METADATA_MAX_SECTORS; | ||
2012 | 2024 | ||
2013 | return metadata_dev_size; | 2025 | return metadata_dev_size; |
2014 | } | 2026 | } |
@@ -2017,7 +2029,7 @@ static dm_block_t get_metadata_dev_size_in_blocks(struct block_device *bdev) | |||
2017 | { | 2029 | { |
2018 | sector_t metadata_dev_size = get_metadata_dev_size(bdev); | 2030 | sector_t metadata_dev_size = get_metadata_dev_size(bdev); |
2019 | 2031 | ||
2020 | sector_div(metadata_dev_size, THIN_METADATA_BLOCK_SIZE >> SECTOR_SHIFT); | 2032 | sector_div(metadata_dev_size, THIN_METADATA_BLOCK_SIZE); |
2021 | 2033 | ||
2022 | return metadata_dev_size; | 2034 | return metadata_dev_size; |
2023 | } | 2035 | } |
@@ -2095,12 +2107,7 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv) | |||
2095 | ti->error = "Error opening metadata block device"; | 2107 | ti->error = "Error opening metadata block device"; |
2096 | goto out_unlock; | 2108 | goto out_unlock; |
2097 | } | 2109 | } |
2098 | 2110 | warn_if_metadata_device_too_big(metadata_dev->bdev); | |
2099 | /* | ||
2100 | * Run for the side-effect of possibly issuing a warning if the | ||
2101 | * device is too big. | ||
2102 | */ | ||
2103 | (void) get_metadata_dev_size(metadata_dev->bdev); | ||
2104 | 2111 | ||
2105 | r = dm_get_device(ti, argv[1], FMODE_READ | FMODE_WRITE, &data_dev); | 2112 | r = dm_get_device(ti, argv[1], FMODE_READ | FMODE_WRITE, &data_dev); |
2106 | if (r) { | 2113 | if (r) { |
@@ -2287,6 +2294,7 @@ static int maybe_resize_metadata_dev(struct dm_target *ti, bool *need_commit) | |||
2287 | return -EINVAL; | 2294 | return -EINVAL; |
2288 | 2295 | ||
2289 | } else if (metadata_dev_size > sb_metadata_dev_size) { | 2296 | } else if (metadata_dev_size > sb_metadata_dev_size) { |
2297 | warn_if_metadata_device_too_big(pool->md_dev); | ||
2290 | DMINFO("%s: growing the metadata device from %llu to %llu blocks", | 2298 | DMINFO("%s: growing the metadata device from %llu to %llu blocks", |
2291 | dm_device_name(pool->pool_md), | 2299 | dm_device_name(pool->pool_md), |
2292 | sb_metadata_dev_size, metadata_dev_size); | 2300 | sb_metadata_dev_size, metadata_dev_size); |
@@ -2894,6 +2902,7 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv) | |||
2894 | 2902 | ||
2895 | if (get_pool_mode(tc->pool) == PM_FAIL) { | 2903 | if (get_pool_mode(tc->pool) == PM_FAIL) { |
2896 | ti->error = "Couldn't open thin device, Pool is in fail mode"; | 2904 | ti->error = "Couldn't open thin device, Pool is in fail mode"; |
2905 | r = -EINVAL; | ||
2897 | goto bad_thin_open; | 2906 | goto bad_thin_open; |
2898 | } | 2907 | } |
2899 | 2908 | ||
@@ -2905,7 +2914,7 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv) | |||
2905 | 2914 | ||
2906 | r = dm_set_target_max_io_len(ti, tc->pool->sectors_per_block); | 2915 | r = dm_set_target_max_io_len(ti, tc->pool->sectors_per_block); |
2907 | if (r) | 2916 | if (r) |
2908 | goto bad_thin_open; | 2917 | goto bad_target_max_io_len; |
2909 | 2918 | ||
2910 | ti->num_flush_bios = 1; | 2919 | ti->num_flush_bios = 1; |
2911 | ti->flush_supported = true; | 2920 | ti->flush_supported = true; |
@@ -2926,6 +2935,8 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv) | |||
2926 | 2935 | ||
2927 | return 0; | 2936 | return 0; |
2928 | 2937 | ||
2938 | bad_target_max_io_len: | ||
2939 | dm_pool_close_thin_device(tc->td); | ||
2929 | bad_thin_open: | 2940 | bad_thin_open: |
2930 | __pool_dec(tc->pool); | 2941 | __pool_dec(tc->pool); |
2931 | bad_pool_lookup: | 2942 | bad_pool_lookup: |