aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/md/dm-thin-metadata.c4
-rw-r--r--drivers/md/dm-thin-metadata.h8
-rw-r--r--drivers/md/dm-thin.c31
-rw-r--r--drivers/md/persistent-data/dm-space-map-metadata.c2
-rw-r--r--drivers/md/persistent-data/dm-space-map-metadata.h11
5 files changed, 37 insertions, 19 deletions
diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c
index 3bb4506582a9..baa87ff12816 100644
--- a/drivers/md/dm-thin-metadata.c
+++ b/drivers/md/dm-thin-metadata.c
@@ -483,7 +483,7 @@ static int __write_initial_superblock(struct dm_pool_metadata *pmd)
483 483
484 disk_super->data_mapping_root = cpu_to_le64(pmd->root); 484 disk_super->data_mapping_root = cpu_to_le64(pmd->root);
485 disk_super->device_details_root = cpu_to_le64(pmd->details_root); 485 disk_super->device_details_root = cpu_to_le64(pmd->details_root);
486 disk_super->metadata_block_size = cpu_to_le32(THIN_METADATA_BLOCK_SIZE >> SECTOR_SHIFT); 486 disk_super->metadata_block_size = cpu_to_le32(THIN_METADATA_BLOCK_SIZE);
487 disk_super->metadata_nr_blocks = cpu_to_le64(bdev_size >> SECTOR_TO_BLOCK_SHIFT); 487 disk_super->metadata_nr_blocks = cpu_to_le64(bdev_size >> SECTOR_TO_BLOCK_SHIFT);
488 disk_super->data_block_size = cpu_to_le32(pmd->data_block_size); 488 disk_super->data_block_size = cpu_to_le32(pmd->data_block_size);
489 489
@@ -651,7 +651,7 @@ static int __create_persistent_data_objects(struct dm_pool_metadata *pmd, bool f
651{ 651{
652 int r; 652 int r;
653 653
654 pmd->bm = dm_block_manager_create(pmd->bdev, THIN_METADATA_BLOCK_SIZE, 654 pmd->bm = dm_block_manager_create(pmd->bdev, THIN_METADATA_BLOCK_SIZE << SECTOR_SHIFT,
655 THIN_METADATA_CACHE_SIZE, 655 THIN_METADATA_CACHE_SIZE,
656 THIN_MAX_CONCURRENT_LOCKS); 656 THIN_MAX_CONCURRENT_LOCKS);
657 if (IS_ERR(pmd->bm)) { 657 if (IS_ERR(pmd->bm)) {
diff --git a/drivers/md/dm-thin-metadata.h b/drivers/md/dm-thin-metadata.h
index dd6088a17a65..82ea384d36ff 100644
--- a/drivers/md/dm-thin-metadata.h
+++ b/drivers/md/dm-thin-metadata.h
@@ -9,16 +9,14 @@
9 9
10#include "persistent-data/dm-block-manager.h" 10#include "persistent-data/dm-block-manager.h"
11#include "persistent-data/dm-space-map.h" 11#include "persistent-data/dm-space-map.h"
12#include "persistent-data/dm-space-map-metadata.h"
12 13
13#define THIN_METADATA_BLOCK_SIZE 4096 14#define THIN_METADATA_BLOCK_SIZE DM_SM_METADATA_BLOCK_SIZE
14 15
15/* 16/*
16 * The metadata device is currently limited in size. 17 * The metadata device is currently limited in size.
17 *
18 * We have one block of index, which can hold 255 index entries. Each
19 * index entry contains allocation info about 16k metadata blocks.
20 */ 18 */
21#define THIN_METADATA_MAX_SECTORS (255 * (1 << 14) * (THIN_METADATA_BLOCK_SIZE / (1 << SECTOR_SHIFT))) 19#define THIN_METADATA_MAX_SECTORS DM_SM_METADATA_MAX_SECTORS
22 20
23/* 21/*
24 * A metadata device larger than 16GB triggers a warning. 22 * A metadata device larger than 16GB triggers a warning.
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
index 4cf4b198cb60..7e84baccf0ad 100644
--- a/drivers/md/dm-thin.c
+++ b/drivers/md/dm-thin.c
@@ -2000,16 +2000,27 @@ static void metadata_low_callback(void *context)
2000 dm_table_event(pool->ti->table); 2000 dm_table_event(pool->ti->table);
2001} 2001}
2002 2002
2003static sector_t get_metadata_dev_size(struct block_device *bdev) 2003static sector_t get_dev_size(struct block_device *bdev)
2004{
2005 return i_size_read(bdev->bd_inode) >> SECTOR_SHIFT;
2006}
2007
2008static void warn_if_metadata_device_too_big(struct block_device *bdev)
2004{ 2009{
2005 sector_t metadata_dev_size = i_size_read(bdev->bd_inode) >> SECTOR_SHIFT; 2010 sector_t metadata_dev_size = get_dev_size(bdev);
2006 char buffer[BDEVNAME_SIZE]; 2011 char buffer[BDEVNAME_SIZE];
2007 2012
2008 if (metadata_dev_size > THIN_METADATA_MAX_SECTORS_WARNING) { 2013 if (metadata_dev_size > THIN_METADATA_MAX_SECTORS_WARNING)
2009 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.",
2010 bdevname(bdev, buffer), THIN_METADATA_MAX_SECTORS); 2015 bdevname(bdev, buffer), THIN_METADATA_MAX_SECTORS);
2011 metadata_dev_size = THIN_METADATA_MAX_SECTORS_WARNING; 2016}
2012 } 2017
2018static 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;
2013 2024
2014 return metadata_dev_size; 2025 return metadata_dev_size;
2015} 2026}
@@ -2018,7 +2029,7 @@ static dm_block_t get_metadata_dev_size_in_blocks(struct block_device *bdev)
2018{ 2029{
2019 sector_t metadata_dev_size = get_metadata_dev_size(bdev); 2030 sector_t metadata_dev_size = get_metadata_dev_size(bdev);
2020 2031
2021 sector_div(metadata_dev_size, THIN_METADATA_BLOCK_SIZE >> SECTOR_SHIFT); 2032 sector_div(metadata_dev_size, THIN_METADATA_BLOCK_SIZE);
2022 2033
2023 return metadata_dev_size; 2034 return metadata_dev_size;
2024} 2035}
@@ -2096,12 +2107,7 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)
2096 ti->error = "Error opening metadata block device"; 2107 ti->error = "Error opening metadata block device";
2097 goto out_unlock; 2108 goto out_unlock;
2098 } 2109 }
2099 2110 warn_if_metadata_device_too_big(metadata_dev->bdev);
2100 /*
2101 * Run for the side-effect of possibly issuing a warning if the
2102 * device is too big.
2103 */
2104 (void) get_metadata_dev_size(metadata_dev->bdev);
2105 2111
2106 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);
2107 if (r) { 2113 if (r) {
@@ -2288,6 +2294,7 @@ static int maybe_resize_metadata_dev(struct dm_target *ti, bool *need_commit)
2288 return -EINVAL; 2294 return -EINVAL;
2289 2295
2290 } 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);
2291 DMINFO("%s: growing the metadata device from %llu to %llu blocks", 2298 DMINFO("%s: growing the metadata device from %llu to %llu blocks",
2292 dm_device_name(pool->pool_md), 2299 dm_device_name(pool->pool_md),
2293 sb_metadata_dev_size, metadata_dev_size); 2300 sb_metadata_dev_size, metadata_dev_size);
diff --git a/drivers/md/persistent-data/dm-space-map-metadata.c b/drivers/md/persistent-data/dm-space-map-metadata.c
index 536782e3bcb7..e9bdd462f4f5 100644
--- a/drivers/md/persistent-data/dm-space-map-metadata.c
+++ b/drivers/md/persistent-data/dm-space-map-metadata.c
@@ -680,6 +680,8 @@ int dm_sm_metadata_create(struct dm_space_map *sm,
680 if (r) 680 if (r)
681 return r; 681 return r;
682 682
683 if (nr_blocks > DM_SM_METADATA_MAX_BLOCKS)
684 nr_blocks = DM_SM_METADATA_MAX_BLOCKS;
683 r = sm_ll_extend(&smm->ll, nr_blocks); 685 r = sm_ll_extend(&smm->ll, nr_blocks);
684 if (r) 686 if (r)
685 return r; 687 return r;
diff --git a/drivers/md/persistent-data/dm-space-map-metadata.h b/drivers/md/persistent-data/dm-space-map-metadata.h
index 39bba0801cf2..64df923974d8 100644
--- a/drivers/md/persistent-data/dm-space-map-metadata.h
+++ b/drivers/md/persistent-data/dm-space-map-metadata.h
@@ -9,6 +9,17 @@
9 9
10#include "dm-transaction-manager.h" 10#include "dm-transaction-manager.h"
11 11
12#define DM_SM_METADATA_BLOCK_SIZE (4096 >> SECTOR_SHIFT)
13
14/*
15 * The metadata device is currently limited in size.
16 *
17 * We have one block of index, which can hold 255 index entries. Each
18 * index entry contains allocation info about ~16k metadata blocks.
19 */
20#define DM_SM_METADATA_MAX_BLOCKS (255 * ((1 << 14) - 64))
21#define DM_SM_METADATA_MAX_SECTORS (DM_SM_METADATA_MAX_BLOCKS * DM_SM_METADATA_BLOCK_SIZE)
22
12/* 23/*
13 * Unfortunately we have to use two-phase construction due to the cycle 24 * Unfortunately we have to use two-phase construction due to the cycle
14 * between the tm and sm. 25 * between the tm and sm.