dm persistent metadata: add space map threshold callback
Add a threshold callback to dm persistent data space maps. Signed-off-by: Joe Thornber <ejt@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
This commit is contained in:
parent
7c3d3f2a87
commit
2fc48021f4
1 changed files with 76 additions and 1 deletions
|
@ -16,6 +16,55 @@
|
||||||
|
|
||||||
/*----------------------------------------------------------------*/
|
/*----------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* An edge triggered threshold.
|
||||||
|
*/
|
||||||
|
struct threshold {
|
||||||
|
bool threshold_set;
|
||||||
|
bool value_set;
|
||||||
|
dm_block_t threshold;
|
||||||
|
dm_block_t current_value;
|
||||||
|
dm_sm_threshold_fn fn;
|
||||||
|
void *context;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void threshold_init(struct threshold *t)
|
||||||
|
{
|
||||||
|
t->threshold_set = false;
|
||||||
|
t->value_set = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_threshold(struct threshold *t, dm_block_t value,
|
||||||
|
dm_sm_threshold_fn fn, void *context)
|
||||||
|
{
|
||||||
|
t->threshold_set = true;
|
||||||
|
t->threshold = value;
|
||||||
|
t->fn = fn;
|
||||||
|
t->context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool below_threshold(struct threshold *t, dm_block_t value)
|
||||||
|
{
|
||||||
|
return t->threshold_set && value <= t->threshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool threshold_already_triggered(struct threshold *t)
|
||||||
|
{
|
||||||
|
return t->value_set && below_threshold(t, t->current_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void check_threshold(struct threshold *t, dm_block_t value)
|
||||||
|
{
|
||||||
|
if (below_threshold(t, value) &&
|
||||||
|
!threshold_already_triggered(t))
|
||||||
|
t->fn(t->context);
|
||||||
|
|
||||||
|
t->value_set = true;
|
||||||
|
t->current_value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Space map interface.
|
* Space map interface.
|
||||||
*
|
*
|
||||||
|
@ -54,6 +103,8 @@ struct sm_metadata {
|
||||||
unsigned allocated_this_transaction;
|
unsigned allocated_this_transaction;
|
||||||
unsigned nr_uncommitted;
|
unsigned nr_uncommitted;
|
||||||
struct block_op uncommitted[MAX_RECURSIVE_ALLOCATIONS];
|
struct block_op uncommitted[MAX_RECURSIVE_ALLOCATIONS];
|
||||||
|
|
||||||
|
struct threshold threshold;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int add_bop(struct sm_metadata *smm, enum block_op_type type, dm_block_t b)
|
static int add_bop(struct sm_metadata *smm, enum block_op_type type, dm_block_t b)
|
||||||
|
@ -329,9 +380,19 @@ static int sm_metadata_new_block_(struct dm_space_map *sm, dm_block_t *b)
|
||||||
|
|
||||||
static int sm_metadata_new_block(struct dm_space_map *sm, dm_block_t *b)
|
static int sm_metadata_new_block(struct dm_space_map *sm, dm_block_t *b)
|
||||||
{
|
{
|
||||||
|
dm_block_t count;
|
||||||
|
struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
|
||||||
|
|
||||||
int r = sm_metadata_new_block_(sm, b);
|
int r = sm_metadata_new_block_(sm, b);
|
||||||
if (r)
|
if (r)
|
||||||
DMERR("unable to allocate new metadata block");
|
DMERR("unable to allocate new metadata block");
|
||||||
|
|
||||||
|
r = sm_metadata_get_nr_free(sm, &count);
|
||||||
|
if (r)
|
||||||
|
DMERR("couldn't get free block count");
|
||||||
|
|
||||||
|
check_threshold(&smm->threshold, count);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,6 +412,18 @@ static int sm_metadata_commit(struct dm_space_map *sm)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int sm_metadata_register_threshold_callback(struct dm_space_map *sm,
|
||||||
|
dm_block_t threshold,
|
||||||
|
dm_sm_threshold_fn fn,
|
||||||
|
void *context)
|
||||||
|
{
|
||||||
|
struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
|
||||||
|
|
||||||
|
set_threshold(&smm->threshold, threshold, fn, context);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int sm_metadata_root_size(struct dm_space_map *sm, size_t *result)
|
static int sm_metadata_root_size(struct dm_space_map *sm, size_t *result)
|
||||||
{
|
{
|
||||||
*result = sizeof(struct disk_sm_root);
|
*result = sizeof(struct disk_sm_root);
|
||||||
|
@ -392,7 +465,7 @@ static struct dm_space_map ops = {
|
||||||
.commit = sm_metadata_commit,
|
.commit = sm_metadata_commit,
|
||||||
.root_size = sm_metadata_root_size,
|
.root_size = sm_metadata_root_size,
|
||||||
.copy_root = sm_metadata_copy_root,
|
.copy_root = sm_metadata_copy_root,
|
||||||
.register_threshold_callback = NULL
|
.register_threshold_callback = sm_metadata_register_threshold_callback
|
||||||
};
|
};
|
||||||
|
|
||||||
/*----------------------------------------------------------------*/
|
/*----------------------------------------------------------------*/
|
||||||
|
@ -577,6 +650,7 @@ int dm_sm_metadata_create(struct dm_space_map *sm,
|
||||||
smm->recursion_count = 0;
|
smm->recursion_count = 0;
|
||||||
smm->allocated_this_transaction = 0;
|
smm->allocated_this_transaction = 0;
|
||||||
smm->nr_uncommitted = 0;
|
smm->nr_uncommitted = 0;
|
||||||
|
threshold_init(&smm->threshold);
|
||||||
|
|
||||||
memcpy(&smm->sm, &bootstrap_ops, sizeof(smm->sm));
|
memcpy(&smm->sm, &bootstrap_ops, sizeof(smm->sm));
|
||||||
|
|
||||||
|
@ -618,6 +692,7 @@ int dm_sm_metadata_open(struct dm_space_map *sm,
|
||||||
smm->recursion_count = 0;
|
smm->recursion_count = 0;
|
||||||
smm->allocated_this_transaction = 0;
|
smm->allocated_this_transaction = 0;
|
||||||
smm->nr_uncommitted = 0;
|
smm->nr_uncommitted = 0;
|
||||||
|
threshold_init(&smm->threshold);
|
||||||
|
|
||||||
memcpy(&smm->old_ll, &smm->ll, sizeof(smm->old_ll));
|
memcpy(&smm->old_ll, &smm->ll, sizeof(smm->old_ll));
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in a new issue