Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bcachefs: DARRAY_PREALLOCATED()

Add support to darray for preallocating some number of elements.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>

+20 -13
+3 -2
fs/bcachefs/darray.c
··· 4 4 #include <linux/slab.h> 5 5 #include "darray.h" 6 6 7 - int __bch2_darray_resize(darray_void *d, size_t element_size, size_t new_size, gfp_t gfp) 7 + int __bch2_darray_resize(darray_char *d, size_t element_size, size_t new_size, gfp_t gfp) 8 8 { 9 9 if (new_size > d->size) { 10 10 new_size = roundup_pow_of_two(new_size); ··· 14 14 return -ENOMEM; 15 15 16 16 memcpy(data, d->data, d->size * element_size); 17 - kvfree(d->data); 17 + if (d->data != d->preallocated) 18 + kvfree(d->data); 18 19 d->data = data; 19 20 d->size = new_size; 20 21 }
+17 -11
fs/bcachefs/darray.h
··· 10 10 11 11 #include <linux/slab.h> 12 12 13 - #define DARRAY(type) \ 13 + #define DARRAY_PREALLOCATED(_type, _nr) \ 14 14 struct { \ 15 15 size_t nr, size; \ 16 - type *data; \ 16 + _type *data; \ 17 + _type preallocated[_nr]; \ 17 18 } 18 19 19 - typedef DARRAY(void) darray_void; 20 + #define DARRAY(_type) DARRAY_PREALLOCATED(_type, 0) 20 21 21 - int __bch2_darray_resize(darray_void *, size_t, size_t, gfp_t); 22 + typedef DARRAY(char) darray_char; 22 23 23 - static inline int __darray_resize(darray_void *d, size_t element_size, 24 + int __bch2_darray_resize(darray_char *, size_t, size_t, gfp_t); 25 + 26 + static inline int __darray_resize(darray_char *d, size_t element_size, 24 27 size_t new_size, gfp_t gfp) 25 28 { 26 29 return unlikely(new_size > d->size) ··· 32 29 } 33 30 34 31 #define darray_resize_gfp(_d, _new_size, _gfp) \ 35 - __darray_resize((darray_void *) (_d), sizeof((_d)->data[0]), (_new_size), _gfp) 32 + unlikely(__darray_resize((darray_char *) (_d), sizeof((_d)->data[0]), (_new_size), _gfp)) 36 33 37 34 #define darray_resize(_d, _new_size) \ 38 35 darray_resize_gfp(_d, _new_size, GFP_KERNEL) 39 36 40 - static inline int __darray_make_room(darray_void *d, size_t t_size, size_t more, gfp_t gfp) 37 + static inline int __darray_make_room(darray_char *d, size_t t_size, size_t more, gfp_t gfp) 41 38 { 42 39 return __darray_resize(d, t_size, d->nr + more, gfp); 43 40 } 44 41 45 42 #define darray_make_room_gfp(_d, _more, _gfp) \ 46 - __darray_make_room((darray_void *) (_d), sizeof((_d)->data[0]), (_more), _gfp) 43 + __darray_make_room((darray_char *) (_d), sizeof((_d)->data[0]), (_more), _gfp) 47 44 48 45 #define darray_make_room(_d, _more) \ 49 46 darray_make_room_gfp(_d, _more, GFP_KERNEL) ··· 89 86 90 87 #define darray_init(_d) \ 91 88 do { \ 92 - (_d)->data = NULL; \ 93 - (_d)->nr = (_d)->size = 0; \ 89 + (_d)->nr = 0; \ 90 + (_d)->size = ARRAY_SIZE((_d)->preallocated); \ 91 + (_d)->data = (_d)->size ? (_d)->preallocated : NULL; \ 94 92 } while (0) 95 93 96 94 #define darray_exit(_d) \ 97 95 do { \ 98 - kvfree((_d)->data); \ 96 + if (!ARRAY_SIZE((_d)->preallocated) || \ 97 + (_d)->data != (_d)->preallocated) \ 98 + kvfree((_d)->data); \ 99 99 darray_init(_d); \ 100 100 } while (0) 101 101