bcachefs: DARRAY_PREALLOCATED()
authorKent Overstreet <kent.overstreet@linux.dev>
Sat, 30 Dec 2023 19:38:29 +0000 (14:38 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Mon, 1 Jan 2024 16:46:52 +0000 (11:46 -0500)
Add support to darray for preallocating some number of elements.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/darray.c
fs/bcachefs/darray.h

index 4c900c8532688fd7be902585ce531a822577804f..ac35b8b705ae1c076e780af570bd824d87c28ab2 100644 (file)
@@ -4,7 +4,7 @@
 #include <linux/slab.h>
 #include "darray.h"
 
-int __bch2_darray_resize(darray_void *d, size_t element_size, size_t new_size, gfp_t gfp)
+int __bch2_darray_resize(darray_char *d, size_t element_size, size_t new_size, gfp_t gfp)
 {
        if (new_size > d->size) {
                new_size = roundup_pow_of_two(new_size);
@@ -14,7 +14,8 @@ int __bch2_darray_resize(darray_void *d, size_t element_size, size_t new_size, g
                        return -ENOMEM;
 
                memcpy(data, d->data, d->size * element_size);
-               kvfree(d->data);
+               if (d->data != d->preallocated)
+                       kvfree(d->data);
                d->data = data;
                d->size = new_size;
        }
index 6157c53d5bf044516f2373c972275b5df215d26b..e367c625f057c2bf9bfc497f29a28bd5ce2b78b8 100644 (file)
 
 #include <linux/slab.h>
 
-#define DARRAY(type)                                                   \
+#define DARRAY_PREALLOCATED(_type, _nr)                                        \
 struct {                                                               \
        size_t nr, size;                                                \
-       type *data;                                                     \
+       _type *data;                                                    \
+       _type preallocated[_nr];                                        \
 }
 
-typedef DARRAY(void) darray_void;
+#define DARRAY(_type) DARRAY_PREALLOCATED(_type, 0)
 
-int __bch2_darray_resize(darray_void *, size_t, size_t, gfp_t);
+typedef DARRAY(char)   darray_char;
 
-static inline int __darray_resize(darray_void *d, size_t element_size,
+int __bch2_darray_resize(darray_char *, size_t, size_t, gfp_t);
+
+static inline int __darray_resize(darray_char *d, size_t element_size,
                                  size_t new_size, gfp_t gfp)
 {
        return unlikely(new_size > d->size)
@@ -29,18 +32,18 @@ static inline int __darray_resize(darray_void *d, size_t element_size,
 }
 
 #define darray_resize_gfp(_d, _new_size, _gfp)                         \
-       __darray_resize((darray_void *) (_d), sizeof((_d)->data[0]), (_new_size), _gfp)
+       unlikely(__darray_resize((darray_char *) (_d), sizeof((_d)->data[0]), (_new_size), _gfp))
 
 #define darray_resize(_d, _new_size)                                   \
        darray_resize_gfp(_d, _new_size, GFP_KERNEL)
 
-static inline int __darray_make_room(darray_void *d, size_t t_size, size_t more, gfp_t gfp)
+static inline int __darray_make_room(darray_char *d, size_t t_size, size_t more, gfp_t gfp)
 {
        return __darray_resize(d, t_size, d->nr + more, gfp);
 }
 
 #define darray_make_room_gfp(_d, _more, _gfp)                          \
-       __darray_make_room((darray_void *) (_d), sizeof((_d)->data[0]), (_more), _gfp)
+       __darray_make_room((darray_char *) (_d), sizeof((_d)->data[0]), (_more), _gfp)
 
 #define darray_make_room(_d, _more)                                    \
        darray_make_room_gfp(_d, _more, GFP_KERNEL)
@@ -86,13 +89,16 @@ static inline int __darray_make_room(darray_void *d, size_t t_size, size_t more,
 
 #define darray_init(_d)                                                        \
 do {                                                                   \
-       (_d)->data = NULL;                                              \
-       (_d)->nr = (_d)->size = 0;                                      \
+       (_d)->nr = 0;                                                   \
+       (_d)->size = ARRAY_SIZE((_d)->preallocated);                    \
+       (_d)->data = (_d)->size ? (_d)->preallocated : NULL;            \
 } while (0)
 
 #define darray_exit(_d)                                                        \
 do {                                                                   \
-       kvfree((_d)->data);                                             \
+       if (!ARRAY_SIZE((_d)->preallocated) ||                          \
+           (_d)->data != (_d)->preallocated)                           \
+               kvfree((_d)->data);                                     \
        darray_init(_d);                                                \
 } while (0)