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