diff options
Diffstat (limited to 'drivers/md/persistent-data/dm-bitset.c')
-rw-r--r-- | drivers/md/persistent-data/dm-bitset.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/drivers/md/persistent-data/dm-bitset.c b/drivers/md/persistent-data/dm-bitset.c index 7cb28516cc19..fbf8d9bc4d15 100644 --- a/drivers/md/persistent-data/dm-bitset.c +++ b/drivers/md/persistent-data/dm-bitset.c | |||
@@ -39,6 +39,48 @@ int dm_bitset_empty(struct dm_disk_bitset *info, dm_block_t *root) | |||
39 | } | 39 | } |
40 | EXPORT_SYMBOL_GPL(dm_bitset_empty); | 40 | EXPORT_SYMBOL_GPL(dm_bitset_empty); |
41 | 41 | ||
42 | struct packer_context { | ||
43 | bit_value_fn fn; | ||
44 | unsigned nr_bits; | ||
45 | void *context; | ||
46 | }; | ||
47 | |||
48 | static int pack_bits(uint32_t index, void *value, void *context) | ||
49 | { | ||
50 | int r; | ||
51 | struct packer_context *p = context; | ||
52 | unsigned bit, nr = min(64u, p->nr_bits - (index * 64)); | ||
53 | uint64_t word = 0; | ||
54 | bool bv; | ||
55 | |||
56 | for (bit = 0; bit < nr; bit++) { | ||
57 | r = p->fn(index * 64 + bit, &bv, p->context); | ||
58 | if (r) | ||
59 | return r; | ||
60 | |||
61 | if (bv) | ||
62 | set_bit(bit, (unsigned long *) &word); | ||
63 | else | ||
64 | clear_bit(bit, (unsigned long *) &word); | ||
65 | } | ||
66 | |||
67 | *((__le64 *) value) = cpu_to_le64(word); | ||
68 | |||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | int dm_bitset_new(struct dm_disk_bitset *info, dm_block_t *root, | ||
73 | uint32_t size, bit_value_fn fn, void *context) | ||
74 | { | ||
75 | struct packer_context p; | ||
76 | p.fn = fn; | ||
77 | p.nr_bits = size; | ||
78 | p.context = context; | ||
79 | |||
80 | return dm_array_new(&info->array_info, root, dm_div_up(size, 64), pack_bits, &p); | ||
81 | } | ||
82 | EXPORT_SYMBOL_GPL(dm_bitset_new); | ||
83 | |||
42 | int dm_bitset_resize(struct dm_disk_bitset *info, dm_block_t root, | 84 | int dm_bitset_resize(struct dm_disk_bitset *info, dm_block_t root, |
43 | uint32_t old_nr_entries, uint32_t new_nr_entries, | 85 | uint32_t old_nr_entries, uint32_t new_nr_entries, |
44 | bool default_value, dm_block_t *new_root) | 86 | bool default_value, dm_block_t *new_root) |