16
16
17
17
/*----------------------------------------------------------------*/
18
18
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
+
19
68
/*
20
69
* Space map interface.
21
70
*
@@ -54,6 +103,8 @@ struct sm_metadata {
54
103
unsigned allocated_this_transaction ;
55
104
unsigned nr_uncommitted ;
56
105
struct block_op uncommitted [MAX_RECURSIVE_ALLOCATIONS ];
106
+
107
+ struct threshold threshold ;
57
108
};
58
109
59
110
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)
329
380
330
381
static int sm_metadata_new_block (struct dm_space_map * sm , dm_block_t * b )
331
382
{
383
+ dm_block_t count ;
384
+ struct sm_metadata * smm = container_of (sm , struct sm_metadata , sm );
385
+
332
386
int r = sm_metadata_new_block_ (sm , b );
333
387
if (r )
334
388
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
+
335
396
return r ;
336
397
}
337
398
@@ -351,6 +412,18 @@ static int sm_metadata_commit(struct dm_space_map *sm)
351
412
return 0 ;
352
413
}
353
414
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
+
354
427
static int sm_metadata_root_size (struct dm_space_map * sm , size_t * result )
355
428
{
356
429
* result = sizeof (struct disk_sm_root );
@@ -392,7 +465,7 @@ static struct dm_space_map ops = {
392
465
.commit = sm_metadata_commit ,
393
466
.root_size = sm_metadata_root_size ,
394
467
.copy_root = sm_metadata_copy_root ,
395
- .register_threshold_callback = NULL
468
+ .register_threshold_callback = sm_metadata_register_threshold_callback
396
469
};
397
470
398
471
/*----------------------------------------------------------------*/
@@ -577,6 +650,7 @@ int dm_sm_metadata_create(struct dm_space_map *sm,
577
650
smm -> recursion_count = 0 ;
578
651
smm -> allocated_this_transaction = 0 ;
579
652
smm -> nr_uncommitted = 0 ;
653
+ threshold_init (& smm -> threshold );
580
654
581
655
memcpy (& smm -> sm , & bootstrap_ops , sizeof (smm -> sm ));
582
656
@@ -618,6 +692,7 @@ int dm_sm_metadata_open(struct dm_space_map *sm,
618
692
smm -> recursion_count = 0 ;
619
693
smm -> allocated_this_transaction = 0 ;
620
694
smm -> nr_uncommitted = 0 ;
695
+ threshold_init (& smm -> threshold );
621
696
622
697
memcpy (& smm -> old_ll , & smm -> ll , sizeof (smm -> old_ll ));
623
698
return 0 ;
0 commit comments