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_ARRAY_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #define _LINUX_DM_ARRAY_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include "dm-btree.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)  * The dm-array is a persistent version of an array.  It packs the data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  * more efficiently than a btree which will result in less disk space use,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  * and a performance boost.  The element get and set operations are still
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  * O(ln(n)), but with a much smaller constant.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  * The value type structure is reused from the btree type to support proper
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  * reference counting of values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  * The arrays implicitly know their length, and bounds are checked for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * lookups and updated.  It doesn't store this in an accessible place
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  * because it would waste a whole metadata block.  Make sure you store the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  * size along with the array root in your encompassing data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  * Array entries are indexed via an unsigned integer starting from zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  * Arrays are not sparse; if you resize an array to have 'n' entries then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  * 'n - 1' will be the last valid index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  * Typical use:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  * a) initialise a dm_array_info structure.  This describes the array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  *    values and ties it into a specific transaction manager.  It holds no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  *    instance data; the same info can be used for many similar arrays if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  *    you wish.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  * 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  39)  *    disk that holds a particular instance of an array.  You may have a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  *    pre existing root in your metadata that you wish to use, or you may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  *    want to create a brand new, empty array with dm_array_empty().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)  * Like the other data structures in this library, dm_array objects are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44)  * immutable between transactions.  Update functions will return you the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45)  * root for a _new_ array.  If you've incremented the old root, via
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46)  * dm_tm_inc(), before calling the update function you may continue to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47)  * it in parallel with the new root.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)  * c) resize an array with dm_array_resize().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51)  * d) Get a value from the array with dm_array_get_value().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)  * e) Set a value in the array with dm_array_set_value().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  * f) Walk an array of values in index order with dm_array_walk().  More
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)  *    efficient than making many calls to dm_array_get_value().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58)  * g) Destroy the array with dm_array_del().  This tells the transaction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)  *    manager that you're no longer using this data structure so it can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60)  *    recycle it's blocks.  (dm_array_dec() would be a better name for it,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61)  *    but del is in keeping with dm_btree_del()).
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65)  * Describes an array.  Don't initialise this structure yourself, use the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66)  * init function below.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) struct dm_array_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	struct dm_transaction_manager *tm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	struct dm_btree_value_type value_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	struct dm_btree_info btree_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75)  * Sets up a dm_array_info structure.  You don't need to do anything with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76)  * this structure when you finish using it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78)  * info - the structure being filled in.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79)  * tm   - the transaction manager that should supervise this structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80)  * vt   - describes the leaf values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) void dm_array_info_init(struct dm_array_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 			struct dm_transaction_manager *tm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 			struct dm_btree_value_type *vt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87)  * Create an empty, zero length array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)  * info - describes the array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)  * root - on success this will be filled out with the root block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) int dm_array_empty(struct dm_array_info *info, dm_block_t *root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95)  * Resizes the array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97)  * info - describes the array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98)  * root - the root block of the array on disk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99)  * old_size - the caller is responsible for remembering the size of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)  *            the array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)  * new_size - can be bigger or smaller than old_size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)  * value - if we're growing the array the new entries will have this value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)  * new_root - on success, points to the new root block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)  * If growing the inc function for 'value' will be called the appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)  * number of times.  So if the caller is holding a reference they may want
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)  * to drop it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) int dm_array_resize(struct dm_array_info *info, dm_block_t root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		    uint32_t old_size, uint32_t new_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		    const void *value, dm_block_t *new_root)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	__dm_written_to_disk(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)  * Creates a new array populated with values provided by a callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)  * function.  This is more efficient than creating an empty array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)  * resizing, and then setting values since that process incurs a lot of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)  * copying.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)  * Assumes 32bit values for now since it's only used by the cache hint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)  * array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)  * info - describes the array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)  * root - the root block of the array on disk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)  * size - the number of entries in the array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)  * fn - the callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)  * context - passed to the callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) typedef int (*value_fn)(uint32_t index, void *value_le, void *context);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) int dm_array_new(struct dm_array_info *info, dm_block_t *root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		 uint32_t size, value_fn fn, void *context);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)  * Frees a whole array.  The value_type's decrement operation will be called
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)  * for all values in the array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) int dm_array_del(struct dm_array_info *info, dm_block_t root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)  * Lookup a value in the array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)  * info - describes the array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)  * root - root block of the array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)  * index - array index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)  * value - the value to be read.  Will be in on-disk format of course.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)  * -ENODATA will be returned if the index is out of bounds.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) int dm_array_get_value(struct dm_array_info *info, dm_block_t root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		       uint32_t index, void *value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)  * Set an entry in the array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)  * info - describes the array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)  * root - root block of the array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)  * index - array index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)  * value - value to be written to disk.  Make sure you confirm the value is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)  *         in on-disk format with__dm_bless_for_disk() before calling.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)  * new_root - the new root block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)  * The old value being overwritten will be decremented, the new value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)  * incremented.
^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_array_set_value(struct dm_array_info *info, dm_block_t root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		       uint32_t index, const void *value, dm_block_t *new_root)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	__dm_written_to_disk(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)  * Walk through all the entries in an array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)  * info - describes the array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)  * root - root block of the array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)  * fn - called back for every element
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)  * context - passed to the callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) int dm_array_walk(struct dm_array_info *info, dm_block_t root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 		  int (*fn)(void *context, uint64_t key, void *leaf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		  void *context);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /*----------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)  * Cursor api.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)  * This lets you iterate through all the entries in an array efficiently
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)  * (it will preload metadata).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)  * I'm using a cursor, rather than a walk function with a callback because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)  * the cache target needs to iterate both the mapping and hint arrays in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)  * unison.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) struct dm_array_cursor {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	struct dm_array_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	struct dm_btree_cursor cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	struct dm_block *block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	struct array_block *ab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	unsigned index;
^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) int dm_array_cursor_begin(struct dm_array_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 			  dm_block_t root, struct dm_array_cursor *c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) void dm_array_cursor_end(struct dm_array_cursor *c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) uint32_t dm_array_cursor_index(struct dm_array_cursor *c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) int dm_array_cursor_next(struct dm_array_cursor *c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) int dm_array_cursor_skip(struct dm_array_cursor *c, uint32_t count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)  * value_le is only valid while the cursor points at the current value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) void dm_array_cursor_get_value(struct dm_array_cursor *c, void **value_le);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /*----------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) #endif	/* _LINUX_DM_ARRAY_H */