diff options
author | Joe Thornber <ejt@redhat.com> | 2013-05-10 09:37:21 -0400 |
---|---|---|
committer | Alasdair G Kergon <agk@redhat.com> | 2013-05-10 09:37:21 -0400 |
commit | ac8c3f3df65e487bbcabf274eeeb9cd222f5da1e (patch) | |
tree | e1ab6d4662834bbbf248b1ad6224c9b7c3faa15e /drivers/md/dm-thin.c | |
parent | 2fc48021f4afdd109b9e52b6eef5db89ca80bac7 (diff) |
dm thin: generate event when metadata threshold passed
Generate a dm event when the amount of remaining thin pool metadata
space falls below a certain level.
The threshold is taken to be a quarter of the size of the metadata
device with a minimum threshold of 4MB.
Signed-off-by: Joe Thornber <ejt@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers/md/dm-thin.c')
-rw-r--r-- | drivers/md/dm-thin.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index f4632f97bd7b..759cffc45cab 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c | |||
@@ -1281,6 +1281,10 @@ static void process_bio_fail(struct thin_c *tc, struct bio *bio) | |||
1281 | bio_io_error(bio); | 1281 | bio_io_error(bio); |
1282 | } | 1282 | } |
1283 | 1283 | ||
1284 | /* | ||
1285 | * FIXME: should we also commit due to size of transaction, measured in | ||
1286 | * metadata blocks? | ||
1287 | */ | ||
1284 | static int need_commit_due_to_time(struct pool *pool) | 1288 | static int need_commit_due_to_time(struct pool *pool) |
1285 | { | 1289 | { |
1286 | return jiffies < pool->last_commit_jiffies || | 1290 | return jiffies < pool->last_commit_jiffies || |
@@ -1909,6 +1913,16 @@ static int parse_pool_features(struct dm_arg_set *as, struct pool_features *pf, | |||
1909 | return r; | 1913 | return r; |
1910 | } | 1914 | } |
1911 | 1915 | ||
1916 | static void metadata_low_callback(void *context) | ||
1917 | { | ||
1918 | struct pool *pool = context; | ||
1919 | |||
1920 | DMWARN("%s: reached low water mark for metadata device: sending event.", | ||
1921 | dm_device_name(pool->pool_md)); | ||
1922 | |||
1923 | dm_table_event(pool->ti->table); | ||
1924 | } | ||
1925 | |||
1912 | static sector_t get_metadata_dev_size(struct block_device *bdev) | 1926 | static sector_t get_metadata_dev_size(struct block_device *bdev) |
1913 | { | 1927 | { |
1914 | sector_t metadata_dev_size = i_size_read(bdev->bd_inode) >> SECTOR_SHIFT; | 1928 | sector_t metadata_dev_size = i_size_read(bdev->bd_inode) >> SECTOR_SHIFT; |
@@ -1933,6 +1947,23 @@ static dm_block_t get_metadata_dev_size_in_blocks(struct block_device *bdev) | |||
1933 | } | 1947 | } |
1934 | 1948 | ||
1935 | /* | 1949 | /* |
1950 | * When a metadata threshold is crossed a dm event is triggered, and | ||
1951 | * userland should respond by growing the metadata device. We could let | ||
1952 | * userland set the threshold, like we do with the data threshold, but I'm | ||
1953 | * not sure they know enough to do this well. | ||
1954 | */ | ||
1955 | static dm_block_t calc_metadata_threshold(struct pool_c *pt) | ||
1956 | { | ||
1957 | /* | ||
1958 | * 4M is ample for all ops with the possible exception of thin | ||
1959 | * device deletion which is harmless if it fails (just retry the | ||
1960 | * delete after you've grown the device). | ||
1961 | */ | ||
1962 | dm_block_t quarter = get_metadata_dev_size_in_blocks(pt->metadata_dev->bdev) / 4; | ||
1963 | return min((dm_block_t)1024ULL /* 4M */, quarter); | ||
1964 | } | ||
1965 | |||
1966 | /* | ||
1936 | * thin-pool <metadata dev> <data dev> | 1967 | * thin-pool <metadata dev> <data dev> |
1937 | * <data block size (sectors)> | 1968 | * <data block size (sectors)> |
1938 | * <low water mark (blocks)> | 1969 | * <low water mark (blocks)> |
@@ -2065,6 +2096,13 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv) | |||
2065 | } | 2096 | } |
2066 | ti->private = pt; | 2097 | ti->private = pt; |
2067 | 2098 | ||
2099 | r = dm_pool_register_metadata_threshold(pt->pool->pmd, | ||
2100 | calc_metadata_threshold(pt), | ||
2101 | metadata_low_callback, | ||
2102 | pool); | ||
2103 | if (r) | ||
2104 | goto out_free_pt; | ||
2105 | |||
2068 | pt->callbacks.congested_fn = pool_is_congested; | 2106 | pt->callbacks.congested_fn = pool_is_congested; |
2069 | dm_table_add_target_callbacks(ti->table, &pt->callbacks); | 2107 | dm_table_add_target_callbacks(ti->table, &pt->callbacks); |
2070 | 2108 | ||