Skip to content

Commit ac8c3f3

Browse files
jthornberkergon
authored andcommitted
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 <[email protected]> Signed-off-by: Alasdair G Kergon <[email protected]>
1 parent 2fc4802 commit ac8c3f3

File tree

3 files changed

+58
-0
lines changed

3 files changed

+58
-0
lines changed

drivers/md/dm-thin-metadata.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1696,3 +1696,17 @@ void dm_pool_metadata_read_only(struct dm_pool_metadata *pmd)
16961696
dm_bm_set_read_only(pmd->bm);
16971697
up_write(&pmd->root_lock);
16981698
}
1699+
1700+
int dm_pool_register_metadata_threshold(struct dm_pool_metadata *pmd,
1701+
dm_block_t threshold,
1702+
dm_sm_threshold_fn fn,
1703+
void *context)
1704+
{
1705+
int r;
1706+
1707+
down_write(&pmd->root_lock);
1708+
r = dm_sm_register_threshold_callback(pmd->metadata_sm, threshold, fn, context);
1709+
up_write(&pmd->root_lock);
1710+
1711+
return r;
1712+
}

drivers/md/dm-thin-metadata.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#define DM_THIN_METADATA_H
99

1010
#include "persistent-data/dm-block-manager.h"
11+
#include "persistent-data/dm-space-map.h"
1112

1213
#define THIN_METADATA_BLOCK_SIZE 4096
1314

@@ -193,6 +194,11 @@ int dm_pool_resize_metadata_dev(struct dm_pool_metadata *pmd, dm_block_t new_siz
193194
*/
194195
void dm_pool_metadata_read_only(struct dm_pool_metadata *pmd);
195196

197+
int dm_pool_register_metadata_threshold(struct dm_pool_metadata *pmd,
198+
dm_block_t threshold,
199+
dm_sm_threshold_fn fn,
200+
void *context);
201+
196202
/*----------------------------------------------------------------*/
197203

198204
#endif

drivers/md/dm-thin.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,6 +1281,10 @@ static void process_bio_fail(struct thin_c *tc, struct bio *bio)
12811281
bio_io_error(bio);
12821282
}
12831283

1284+
/*
1285+
* FIXME: should we also commit due to size of transaction, measured in
1286+
* metadata blocks?
1287+
*/
12841288
static int need_commit_due_to_time(struct pool *pool)
12851289
{
12861290
return jiffies < pool->last_commit_jiffies ||
@@ -1909,6 +1913,16 @@ static int parse_pool_features(struct dm_arg_set *as, struct pool_features *pf,
19091913
return r;
19101914
}
19111915

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+
19121926
static sector_t get_metadata_dev_size(struct block_device *bdev)
19131927
{
19141928
sector_t metadata_dev_size = i_size_read(bdev->bd_inode) >> SECTOR_SHIFT;
@@ -1932,6 +1946,23 @@ static dm_block_t get_metadata_dev_size_in_blocks(struct block_device *bdev)
19321946
return metadata_dev_size;
19331947
}
19341948

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+
19351966
/*
19361967
* thin-pool <metadata dev> <data dev>
19371968
* <data block size (sectors)>
@@ -2065,6 +2096,13 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)
20652096
}
20662097
ti->private = pt;
20672098

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+
20682106
pt->callbacks.congested_fn = pool_is_congested;
20692107
dm_table_add_target_callbacks(ti->table, &pt->callbacks);
20702108

0 commit comments

Comments
 (0)