Skip to content

Commit 2fc4802

Browse files
jthornberkergon
authored andcommitted
dm persistent metadata: add space map threshold callback
Add a threshold callback to dm persistent data space maps. Signed-off-by: Joe Thornber <[email protected]> Signed-off-by: Alasdair G Kergon <[email protected]>
1 parent 7c3d3f2 commit 2fc4802

File tree

1 file changed

+76
-1
lines changed

1 file changed

+76
-1
lines changed

drivers/md/persistent-data/dm-space-map-metadata.c

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,55 @@
1616

1717
/*----------------------------------------------------------------*/
1818

19+
/*
20+
* An edge triggered threshold.
21+
*/
22+
struct threshold {
23+
bool threshold_set;
24+
bool value_set;
25+
dm_block_t threshold;
26+
dm_block_t current_value;
27+
dm_sm_threshold_fn fn;
28+
void *context;
29+
};
30+
31+
static void threshold_init(struct threshold *t)
32+
{
33+
t->threshold_set = false;
34+
t->value_set = false;
35+
}
36+
37+
static void set_threshold(struct threshold *t, dm_block_t value,
38+
dm_sm_threshold_fn fn, void *context)
39+
{
40+
t->threshold_set = true;
41+
t->threshold = value;
42+
t->fn = fn;
43+
t->context = context;
44+
}
45+
46+
static bool below_threshold(struct threshold *t, dm_block_t value)
47+
{
48+
return t->threshold_set && value <= t->threshold;
49+
}
50+
51+
static bool threshold_already_triggered(struct threshold *t)
52+
{
53+
return t->value_set && below_threshold(t, t->current_value);
54+
}
55+
56+
static void check_threshold(struct threshold *t, dm_block_t value)
57+
{
58+
if (below_threshold(t, value) &&
59+
!threshold_already_triggered(t))
60+
t->fn(t->context);
61+
62+
t->value_set = true;
63+
t->current_value = value;
64+
}
65+
66+
/*----------------------------------------------------------------*/
67+
1968
/*
2069
* Space map interface.
2170
*
@@ -54,6 +103,8 @@ struct sm_metadata {
54103
unsigned allocated_this_transaction;
55104
unsigned nr_uncommitted;
56105
struct block_op uncommitted[MAX_RECURSIVE_ALLOCATIONS];
106+
107+
struct threshold threshold;
57108
};
58109

59110
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)
329380

330381
static int sm_metadata_new_block(struct dm_space_map *sm, dm_block_t *b)
331382
{
383+
dm_block_t count;
384+
struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
385+
332386
int r = sm_metadata_new_block_(sm, b);
333387
if (r)
334388
DMERR("unable to allocate new metadata block");
389+
390+
r = sm_metadata_get_nr_free(sm, &count);
391+
if (r)
392+
DMERR("couldn't get free block count");
393+
394+
check_threshold(&smm->threshold, count);
395+
335396
return r;
336397
}
337398

@@ -351,6 +412,18 @@ static int sm_metadata_commit(struct dm_space_map *sm)
351412
return 0;
352413
}
353414

415+
static int sm_metadata_register_threshold_callback(struct dm_space_map *sm,
416+
dm_block_t threshold,
417+
dm_sm_threshold_fn fn,
418+
void *context)
419+
{
420+
struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
421+
422+
set_threshold(&smm->threshold, threshold, fn, context);
423+
424+
return 0;
425+
}
426+
354427
static int sm_metadata_root_size(struct dm_space_map *sm, size_t *result)
355428
{
356429
*result = sizeof(struct disk_sm_root);
@@ -392,7 +465,7 @@ static struct dm_space_map ops = {
392465
.commit = sm_metadata_commit,
393466
.root_size = sm_metadata_root_size,
394467
.copy_root = sm_metadata_copy_root,
395-
.register_threshold_callback = NULL
468+
.register_threshold_callback = sm_metadata_register_threshold_callback
396469
};
397470

398471
/*----------------------------------------------------------------*/
@@ -577,6 +650,7 @@ int dm_sm_metadata_create(struct dm_space_map *sm,
577650
smm->recursion_count = 0;
578651
smm->allocated_this_transaction = 0;
579652
smm->nr_uncommitted = 0;
653+
threshold_init(&smm->threshold);
580654

581655
memcpy(&smm->sm, &bootstrap_ops, sizeof(smm->sm));
582656

@@ -618,6 +692,7 @@ int dm_sm_metadata_open(struct dm_space_map *sm,
618692
smm->recursion_count = 0;
619693
smm->allocated_this_transaction = 0;
620694
smm->nr_uncommitted = 0;
695+
threshold_init(&smm->threshold);
621696

622697
memcpy(&smm->old_ll, &smm->ll, sizeof(smm->old_ll));
623698
return 0;

0 commit comments

Comments
 (0)