Skip to content

Commit 2c6a7bf

Browse files
author
Kent Overstreet
committed
bcachefs: Switch gc bucket array to a genradix
A user with a 30 tb device is overflowing the INT_MAX limit on vmalloc allocations... Signed-off-by: Kent Overstreet <[email protected]>
1 parent a803fa5 commit 2c6a7bf

File tree

4 files changed

+6
-37
lines changed

4 files changed

+6
-37
lines changed

fs/bcachefs/bcachefs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,7 @@ struct bch_dev {
542542
* gc_gens_lock, for device resize - holding any is sufficient for
543543
* access: Or rcu_read_lock(), but only for dev_ptr_stale():
544544
*/
545-
struct bucket_array __rcu *buckets_gc;
545+
GENRADIX(struct bucket) buckets_gc;
546546
struct bucket_gens __rcu *bucket_gens;
547547
u8 *oldest_gen;
548548
unsigned long *buckets_nouse;

fs/bcachefs/btree_gc.c

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -753,10 +753,8 @@ static void bch2_gc_free(struct bch_fs *c)
753753
genradix_free(&c->reflink_gc_table);
754754
genradix_free(&c->gc_stripes);
755755

756-
for_each_member_device(c, ca) {
757-
kvfree(rcu_dereference_protected(ca->buckets_gc, 1));
758-
ca->buckets_gc = NULL;
759-
}
756+
for_each_member_device(c, ca)
757+
genradix_free(&ca->buckets_gc);
760758
}
761759

762760
static int bch2_gc_start(struct bch_fs *c)
@@ -910,20 +908,12 @@ static int bch2_gc_alloc_start(struct bch_fs *c)
910908
int ret = 0;
911909

912910
for_each_member_device(c, ca) {
913-
struct bucket_array *buckets = kvmalloc(sizeof(struct bucket_array) +
914-
ca->mi.nbuckets * sizeof(struct bucket),
915-
GFP_KERNEL|__GFP_ZERO);
916-
if (!buckets) {
911+
ret = genradix_prealloc(&ca->buckets_gc, ca->mi.nbuckets, GFP_KERNEL);
912+
if (ret) {
917913
bch2_dev_put(ca);
918914
ret = -BCH_ERR_ENOMEM_gc_alloc_start;
919915
break;
920916
}
921-
922-
buckets->first_bucket = ca->mi.first_bucket;
923-
buckets->nbuckets = ca->mi.nbuckets;
924-
buckets->nbuckets_minus_first =
925-
buckets->nbuckets - buckets->first_bucket;
926-
rcu_assign_pointer(ca->buckets_gc, buckets);
927917
}
928918

929919
bch_err_fn(c, ret);

fs/bcachefs/buckets.h

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -80,22 +80,9 @@ static inline void bucket_lock(struct bucket *b)
8080
TASK_UNINTERRUPTIBLE);
8181
}
8282

83-
static inline struct bucket_array *gc_bucket_array(struct bch_dev *ca)
84-
{
85-
return rcu_dereference_check(ca->buckets_gc,
86-
!ca->fs ||
87-
percpu_rwsem_is_held(&ca->fs->mark_lock) ||
88-
lockdep_is_held(&ca->fs->state_lock) ||
89-
lockdep_is_held(&ca->bucket_lock));
90-
}
91-
9283
static inline struct bucket *gc_bucket(struct bch_dev *ca, size_t b)
9384
{
94-
struct bucket_array *buckets = gc_bucket_array(ca);
95-
96-
if (b - buckets->first_bucket >= buckets->nbuckets_minus_first)
97-
return NULL;
98-
return buckets->b + b;
85+
return genradix_ptr(&ca->buckets_gc, b);
9986
}
10087

10188
static inline struct bucket_gens *bucket_gens(struct bch_dev *ca)

fs/bcachefs/buckets_types.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,6 @@ struct bucket {
1919
u32 stripe_sectors;
2020
} __aligned(sizeof(long));
2121

22-
struct bucket_array {
23-
struct rcu_head rcu;
24-
u16 first_bucket;
25-
size_t nbuckets;
26-
size_t nbuckets_minus_first;
27-
struct bucket b[] __counted_by(nbuckets);
28-
};
29-
3022
struct bucket_gens {
3123
struct rcu_head rcu;
3224
u16 first_bucket;

0 commit comments

Comments
 (0)