bcachefs: bch2_kvmalloc()
authorKent Overstreet <kent.overstreet@linux.dev>
Fri, 20 Dec 2024 10:20:01 +0000 (05:20 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Fri, 10 Jan 2025 04:38:41 +0000 (23:38 -0500)
Add a version of kvmalloc() that doesn't have the INT_MAX limit; large
filesystems do hit this.

We'll want to get rid of the in-memory bucket gens array, but we're not
there quite yet.

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

index 56d3e3800a8901dc6844e2f03fcba9832cb8486c..345b117a4a4a64e9b7618ea5037e1f84b71f41fe 100644 (file)
@@ -1258,7 +1258,7 @@ int bch2_buckets_nouse_alloc(struct bch_fs *c)
        for_each_member_device(c, ca) {
                BUG_ON(ca->buckets_nouse);
 
-               ca->buckets_nouse = kvmalloc(BITS_TO_LONGS(ca->mi.nbuckets) *
+               ca->buckets_nouse = bch2_kvmalloc(BITS_TO_LONGS(ca->mi.nbuckets) *
                                            sizeof(unsigned long),
                                            GFP_KERNEL|__GFP_ZERO);
                if (!ca->buckets_nouse) {
@@ -1290,8 +1290,8 @@ int bch2_dev_buckets_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets)
        if (resize && ca->buckets_nouse)
                return -BCH_ERR_no_resize_with_buckets_nouse;
 
-       bucket_gens = kvmalloc(struct_size(bucket_gens, b, nbuckets),
-                              GFP_KERNEL|__GFP_ZERO);
+       bucket_gens = bch2_kvmalloc(struct_size(bucket_gens, b, nbuckets),
+                                   GFP_KERNEL|__GFP_ZERO);
        if (!bucket_gens) {
                ret = -BCH_ERR_ENOMEM_bucket_gens;
                goto err;
index c292b9ce82406bb3d5857db78b681a04eb7459dc..1a1720116071ce849165d21c26a2de201c905a88 100644 (file)
@@ -55,6 +55,16 @@ static inline size_t buf_pages(void *p, size_t len)
                            PAGE_SIZE);
 }
 
+static inline void *bch2_kvmalloc(size_t n, gfp_t flags)
+{
+       void *p = unlikely(n >= INT_MAX)
+               ? vmalloc(n)
+               : kvmalloc(n, flags & ~__GFP_ZERO);
+       if (p && (flags & __GFP_ZERO))
+               memset(p, 0, n);
+       return p;
+}
+
 #define init_heap(heap, _size, gfp)                                    \
 ({                                                                     \
        (heap)->nr = 0;                                         \