-#ifndef _BCACHE_UTIL_H
-#define _BCACHE_UTIL_H
+#ifndef _BCACHEFS_UTIL_H
+#define _BCACHEFS_UTIL_H
#include <linux/bio.h>
#include <linux/blkdev.h>
#define atomic64_sub_bug(i, v) BUG_ON(atomic64_sub_return(i, v) < 0)
#define atomic64_add_bug(i, v) BUG_ON(atomic64_add_return(i, v) < 0)
-#define memcpy(_dst, _src, _len) \
-do { \
+#define memcpy(dst, src, len) \
+({ \
+ void *_dst = (dst); \
+ const void *_src = (src); \
+ size_t _len = (len); \
+ \
BUG_ON(!((void *) (_dst) >= (void *) (_src) + (_len) || \
(void *) (_dst) + (_len) <= (void *) (_src))); \
memcpy(_dst, _src, _len); \
-} while (0)
+})
#else /* DEBUG */
(__builtin_types_compatible_p(typeof(_val), _type) || \
__builtin_types_compatible_p(typeof(_val), const _type))
-static inline void kvpfree(void *p, size_t size)
+static inline void vpfree(void *p, size_t size)
{
- if (size < PAGE_SIZE)
- kfree(p);
- else if (is_vmalloc_addr(p))
+ if (is_vmalloc_addr(p))
vfree(p);
else
free_pages((unsigned long) p, get_order(size));
+}
+static inline void *vpmalloc(size_t size, gfp_t gfp_mask)
+{
+ return (void *) __get_free_pages(gfp_mask|__GFP_NOWARN,
+ get_order(size)) ?:
+ __vmalloc(size, gfp_mask, PAGE_KERNEL);
+}
+
+static inline void kvpfree(void *p, size_t size)
+{
+ if (size < PAGE_SIZE)
+ kfree(p);
+ else
+ vpfree(p, size);
}
static inline void *kvpmalloc(size_t size, gfp_t gfp_mask)
{
- return size < PAGE_SIZE ? kmalloc(size, gfp_mask)
- : (void *) __get_free_pages(gfp_mask|__GFP_NOWARN,
- get_order(size))
- ?: __vmalloc(size, gfp_mask, PAGE_KERNEL);
+ return size < PAGE_SIZE
+ ? kmalloc(size, gfp_mask)
+ : vpmalloc(size, gfp_mask);
+}
+
+void mempool_free_vp(void *element, void *pool_data);
+void *mempool_alloc_vp(gfp_t gfp_mask, void *pool_data);
+
+static inline int mempool_init_vp_pool(mempool_t *pool, int min_nr, size_t size)
+{
+ return mempool_init(pool, min_nr, mempool_alloc_vp,
+ mempool_free_vp, (void *) size);
}
#define HEAP(type) \
bool bch2_is_zero(const void *, size_t);
-ssize_t bch2_snprint_string_list(char *buf, size_t size, const char * const list[],
- size_t selected);
+ssize_t bch2_scnprint_string_list(char *, size_t, const char * const[], size_t);
-ssize_t bch2_read_string_list(const char *buf, const char * const list[]);
+ssize_t bch2_read_string_list(const char *, const char * const[]);
+
+ssize_t bch2_scnprint_flag_list(char *, size_t, const char * const[], u64);
+u64 bch2_read_flag_list(char *, const char * const[]);
struct time_stats {
spinlock_t lock;
size_t bch_scnmemcpy(char *, size_t, const char *, size_t);
-#endif /* _BCACHE_UTIL_H */
+void sort_cmp_size(void *base, size_t num, size_t size,
+ int (*cmp_func)(const void *, const void *, size_t),
+ void (*swap_func)(void *, void *, size_t));
+
+/* just the memmove, doesn't update @_nr */
+#define __array_insert_item(_array, _nr, _pos) \
+ memmove(&(_array)[(_pos) + 1], \
+ &(_array)[(_pos)], \
+ sizeof((_array)[0]) * ((_nr) - (_pos)))
+
+#define array_insert_item(_array, _nr, _pos, _new_item) \
+do { \
+ __array_insert_item(_array, _nr, _pos); \
+ (_nr)++; \
+ (_array)[(_pos)] = (_new_item); \
+} while (0)
+
+#define array_remove_items(_array, _nr, _pos, _nr_to_remove) \
+do { \
+ (_nr) -= (_nr_to_remove); \
+ memmove(&(_array)[(_pos)], \
+ &(_array)[(_pos) + (_nr_to_remove)], \
+ sizeof((_array)[0]) * ((_nr) - (_pos))); \
+} while (0)
+
+#define array_remove_item(_array, _nr, _pos) \
+ array_remove_items(_array, _nr, _pos, 1)
+
+#define bubble_sort(_base, _nr, _cmp) \
+do { \
+ ssize_t _i, _end; \
+ bool _swapped = true; \
+ \
+ for (_end = (ssize_t) (_nr) - 1; _end > 0 && _swapped; --_end) {\
+ _swapped = false; \
+ for (_i = 0; _i < _end; _i++) \
+ if (_cmp((_base)[_i], (_base)[_i + 1]) > 0) { \
+ swap((_base)[_i], (_base)[_i + 1]); \
+ _swapped = true; \
+ } \
+ } \
+} while (0)
+
+#endif /* _BCACHEFS_UTIL_H */