Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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