]> Git Repo - linux.git/blob - fs/bcachefs/darray.h
Linux 6.14-rc3
[linux.git] / fs / bcachefs / darray.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _BCACHEFS_DARRAY_H
3 #define _BCACHEFS_DARRAY_H
4
5 /*
6  * Dynamic arrays:
7  *
8  * Inspired by CCAN's darray
9  */
10
11 #include <linux/slab.h>
12
13 #define DARRAY_PREALLOCATED(_type, _nr)                                 \
14 struct {                                                                \
15         size_t nr, size;                                                \
16         _type *data;                                                    \
17         _type preallocated[_nr];                                        \
18 }
19
20 #define DARRAY(_type) DARRAY_PREALLOCATED(_type, 0)
21
22 typedef DARRAY(char)    darray_char;
23 typedef DARRAY(char *) darray_str;
24
25 int __bch2_darray_resize_noprof(darray_char *, size_t, size_t, gfp_t);
26
27 #define __bch2_darray_resize(...)       alloc_hooks(__bch2_darray_resize_noprof(__VA_ARGS__))
28
29 #define __darray_resize(_d, _element_size, _new_size, _gfp)             \
30         (unlikely((_new_size) > (_d)->size)                             \
31          ? __bch2_darray_resize((_d), (_element_size), (_new_size), (_gfp))\
32          : 0)
33
34 #define darray_resize_gfp(_d, _new_size, _gfp)                          \
35         __darray_resize((darray_char *) (_d), sizeof((_d)->data[0]), (_new_size), _gfp)
36
37 #define darray_resize(_d, _new_size)                                    \
38         darray_resize_gfp(_d, _new_size, GFP_KERNEL)
39
40 #define darray_make_room_gfp(_d, _more, _gfp)                           \
41         darray_resize_gfp((_d), (_d)->nr + (_more), _gfp)
42
43 #define darray_make_room(_d, _more)                                     \
44         darray_make_room_gfp(_d, _more, GFP_KERNEL)
45
46 #define darray_room(_d)         ((_d).size - (_d).nr)
47
48 #define darray_top(_d)          ((_d).data[(_d).nr])
49
50 #define darray_push_gfp(_d, _item, _gfp)                                \
51 ({                                                                      \
52         int _ret = darray_make_room_gfp((_d), 1, _gfp);                 \
53                                                                         \
54         if (!_ret)                                                      \
55                 (_d)->data[(_d)->nr++] = (_item);                       \
56         _ret;                                                           \
57 })
58
59 #define darray_push(_d, _item)  darray_push_gfp(_d, _item, GFP_KERNEL)
60
61 #define darray_pop(_d)          ((_d)->data[--(_d)->nr])
62
63 #define darray_first(_d)        ((_d).data[0])
64 #define darray_last(_d)         ((_d).data[(_d).nr - 1])
65
66 #define darray_insert_item(_d, pos, _item)                              \
67 ({                                                                      \
68         size_t _pos = (pos);                                            \
69         int _ret = darray_make_room((_d), 1);                           \
70                                                                         \
71         if (!_ret)                                                      \
72                 array_insert_item((_d)->data, (_d)->nr, _pos, (_item)); \
73         _ret;                                                           \
74 })
75
76 #define darray_remove_item(_d, _pos)                                    \
77         array_remove_item((_d)->data, (_d)->nr, (_pos) - (_d)->data)
78
79 #define __darray_for_each(_d, _i)                                               \
80         for ((_i) = (_d).data; _i < (_d).data + (_d).nr; _i++)
81
82 #define darray_for_each(_d, _i)                                         \
83         for (typeof(&(_d).data[0]) _i = (_d).data; _i < (_d).data + (_d).nr; _i++)
84
85 #define darray_for_each_reverse(_d, _i)                                 \
86         for (typeof(&(_d).data[0]) _i = (_d).data + (_d).nr - 1; _i >= (_d).data && (_d).nr; --_i)
87
88 #define darray_init(_d)                                                 \
89 do {                                                                    \
90         (_d)->nr = 0;                                                   \
91         (_d)->size = ARRAY_SIZE((_d)->preallocated);                    \
92         (_d)->data = (_d)->size ? (_d)->preallocated : NULL;            \
93 } while (0)
94
95 #define darray_exit(_d)                                                 \
96 do {                                                                    \
97         if (!ARRAY_SIZE((_d)->preallocated) ||                          \
98             (_d)->data != (_d)->preallocated)                           \
99                 kvfree((_d)->data);                                     \
100         darray_init(_d);                                                \
101 } while (0)
102
103 #endif /* _BCACHEFS_DARRAY_H */
This page took 0.037292 seconds and 4 git commands to generate.