1 /* 2 * Copyright (C) 2012 Red Hat, Inc. 3 * 4 * This file is released under the GPL. 5 */ 6 #ifndef _LINUX_DM_BITSET_H 7 #define _LINUX_DM_BITSET_H 8 9 #include "dm-array.h" 10 11 /*----------------------------------------------------------------*/ 12 13 /* 14 * This bitset type is a thin wrapper round a dm_array of 64bit words. It 15 * uses a tiny, one word cache to reduce the number of array lookups and so 16 * increase performance. 17 * 18 * Like the dm-array that it's based on, the caller needs to keep track of 19 * the size of the bitset separately. The underlying dm-array implicitly 20 * knows how many words it's storing and will return -ENODATA if you try 21 * and access an out of bounds word. However, an out of bounds bit in the 22 * final word will _not_ be detected, you have been warned. 23 * 24 * Bits are indexed from zero. 25 26 * Typical use: 27 * 28 * a) Initialise a dm_disk_bitset structure with dm_disk_bitset_init(). 29 * This describes the bitset and includes the cache. It's not called it 30 * dm_bitset_info in line with other data structures because it does 31 * include instance data. 32 * 33 * b) Get yourself a root. The root is the index of a block of data on the 34 * disk that holds a particular instance of an bitset. You may have a 35 * pre existing root in your metadata that you wish to use, or you may 36 * want to create a brand new, empty bitset with dm_bitset_empty(). 37 * 38 * Like the other data structures in this library, dm_bitset objects are 39 * immutable between transactions. Update functions will return you the 40 * root for a _new_ array. If you've incremented the old root, via 41 * dm_tm_inc(), before calling the update function you may continue to use 42 * it in parallel with the new root. 43 * 44 * Even read operations may trigger the cache to be flushed and as such 45 * return a root for a new, updated bitset. 46 * 47 * c) resize a bitset with dm_bitset_resize(). 48 * 49 * d) Set a bit with dm_bitset_set_bit(). 50 * 51 * e) Clear a bit with dm_bitset_clear_bit(). 52 * 53 * f) Test a bit with dm_bitset_test_bit(). 54 * 55 * g) Flush all updates from the cache with dm_bitset_flush(). 56 * 57 * h) Destroy the bitset with dm_bitset_del(). This tells the transaction 58 * manager that you're no longer using this data structure so it can 59 * recycle it's blocks. (dm_bitset_dec() would be a better name for it, 60 * but del is in keeping with dm_btree_del()). 61 */ 62 63 /* 64 * Opaque object. Unlike dm_array_info, you should have one of these per 65 * bitset. Initialise with dm_disk_bitset_init(). 66 */ 67 struct dm_disk_bitset { 68 struct dm_array_info array_info; 69 70 uint32_t current_index; 71 uint64_t current_bits; 72 73 bool current_index_set:1; 74 }; 75 76 /* 77 * Sets up a dm_disk_bitset structure. You don't need to do anything with 78 * this structure when you finish using it. 79 * 80 * tm - the transaction manager that should supervise this structure 81 * info - the structure being initialised 82 */ 83 void dm_disk_bitset_init(struct dm_transaction_manager *tm, 84 struct dm_disk_bitset *info); 85 86 /* 87 * Create an empty, zero length bitset. 88 * 89 * info - describes the bitset 90 * new_root - on success, points to the new root block 91 */ 92 int dm_bitset_empty(struct dm_disk_bitset *info, dm_block_t *new_root); 93 94 /* 95 * Resize the bitset. 96 * 97 * info - describes the bitset 98 * old_root - the root block of the array on disk 99 * old_nr_entries - the number of bits in the old bitset 100 * new_nr_entries - the number of bits you want in the new bitset 101 * default_value - the value for any new bits 102 * new_root - on success, points to the new root block 103 */ 104 int dm_bitset_resize(struct dm_disk_bitset *info, dm_block_t old_root, 105 uint32_t old_nr_entries, uint32_t new_nr_entries, 106 bool default_value, dm_block_t *new_root); 107 108 /* 109 * Frees the bitset. 110 */ 111 int dm_bitset_del(struct dm_disk_bitset *info, dm_block_t root); 112 113 /* 114 * Set a bit. 115 * 116 * info - describes the bitset 117 * root - the root block of the bitset 118 * index - the bit index 119 * new_root - on success, points to the new root block 120 * 121 * -ENODATA will be returned if the index is out of bounds. 122 */ 123 int dm_bitset_set_bit(struct dm_disk_bitset *info, dm_block_t root, 124 uint32_t index, dm_block_t *new_root); 125 126 /* 127 * Clears a bit. 128 * 129 * info - describes the bitset 130 * root - the root block of the bitset 131 * index - the bit index 132 * new_root - on success, points to the new root block 133 * 134 * -ENODATA will be returned if the index is out of bounds. 135 */ 136 int dm_bitset_clear_bit(struct dm_disk_bitset *info, dm_block_t root, 137 uint32_t index, dm_block_t *new_root); 138 139 /* 140 * Tests a bit. 141 * 142 * info - describes the bitset 143 * root - the root block of the bitset 144 * index - the bit index 145 * new_root - on success, points to the new root block (cached values may have been written) 146 * result - the bit value you're after 147 * 148 * -ENODATA will be returned if the index is out of bounds. 149 */ 150 int dm_bitset_test_bit(struct dm_disk_bitset *info, dm_block_t root, 151 uint32_t index, dm_block_t *new_root, bool *result); 152 153 /* 154 * Flush any cached changes to disk. 155 * 156 * info - describes the bitset 157 * root - the root block of the bitset 158 * new_root - on success, points to the new root block 159 */ 160 int dm_bitset_flush(struct dm_disk_bitset *info, dm_block_t root, 161 dm_block_t *new_root); 162 163 /*----------------------------------------------------------------*/ 164 165 #endif /* _LINUX_DM_BITSET_H */ 166