summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/bcachefs/alloc.c28
-rw-r--r--fs/bcachefs/bcachefs_format.h1
-rw-r--r--fs/bcachefs/opts.h5
3 files changed, 17 insertions, 17 deletions
diff --git a/fs/bcachefs/alloc.c b/fs/bcachefs/alloc.c
index bde22df25134..e6aeab0b47c7 100644
--- a/fs/bcachefs/alloc.c
+++ b/fs/bcachefs/alloc.c
@@ -1711,7 +1711,7 @@ void bch2_alloc_sectors_done(struct bch_fs *c, struct write_point *wp)
void bch2_recalc_capacity(struct bch_fs *c)
{
struct bch_dev *ca;
- u64 capacity = 0, reserved_sectors = 0;
+ u64 capacity = 0, reserved_sectors = 0, gc_reserve;
unsigned long ra_pages = 0;
unsigned i, j;
@@ -1726,7 +1726,7 @@ void bch2_recalc_capacity(struct bch_fs *c)
bch2_set_ra_pages(c, ra_pages);
for_each_rw_member(ca, c, i) {
- u64 dev_capacity, dev_reserve = 0;
+ u64 dev_reserve = 0;
/*
* We need to reserve buckets (from the number
@@ -1758,25 +1758,21 @@ void bch2_recalc_capacity(struct bch_fs *c)
dev_reserve *= ca->mi.bucket_size;
- dev_reserve *= 2;
+ ca->copygc_threshold = dev_reserve;
- dev_capacity = bucket_to_sector(ca, ca->mi.nbuckets -
- ca->mi.first_bucket);
+ capacity += bucket_to_sector(ca, ca->mi.nbuckets -
+ ca->mi.first_bucket);
- ca->copygc_threshold =
- max(div64_u64(dev_capacity *
- c->opts.gc_reserve_percent, 100),
- dev_reserve) / 2;
-
- capacity += dev_capacity;
- reserved_sectors += dev_reserve;
+ reserved_sectors += dev_reserve * 2;
}
- reserved_sectors = max(div64_u64(capacity *
- c->opts.gc_reserve_percent, 100),
- reserved_sectors);
+ gc_reserve = c->opts.gc_reserve_bytes
+ ? c->opts.gc_reserve_bytes >> 9
+ : div64_u64(capacity * c->opts.gc_reserve_percent, 100);
+
+ reserved_sectors = max(gc_reserve, reserved_sectors);
- BUG_ON(reserved_sectors > capacity);
+ reserved_sectors = min(reserved_sectors, capacity);
c->capacity = capacity - reserved_sectors;
diff --git a/fs/bcachefs/bcachefs_format.h b/fs/bcachefs/bcachefs_format.h
index eb14dba87402..ac0c7d6a07fb 100644
--- a/fs/bcachefs/bcachefs_format.h
+++ b/fs/bcachefs/bcachefs_format.h
@@ -1221,6 +1221,7 @@ LE64_BITMASK(BCH_SB_BACKGROUND_TARGET, struct bch_sb, flags[1], 52, 64);
LE64_BITMASK(BCH_SB_BACKGROUND_COMPRESSION_TYPE,
struct bch_sb, flags[2], 0, 4);
+LE64_BITMASK(BCH_SB_GC_RESERVE_BYTES, struct bch_sb, flags[2], 4, 64);
/* Features: */
enum bch_sb_features {
diff --git a/fs/bcachefs/opts.h b/fs/bcachefs/opts.h
index 3b5eddbf56bf..01f1cb53eb5f 100644
--- a/fs/bcachefs/opts.h
+++ b/fs/bcachefs/opts.h
@@ -114,9 +114,12 @@ enum opt_type {
BCH_OPT(inodes_32bit, u8, OPT_RUNTIME, \
OPT_BOOL(), \
BCH_SB_INODE_32BIT, false) \
- BCH_OPT(gc_reserve_percent, u8, OPT_MOUNT, \
+ BCH_OPT(gc_reserve_percent, u8, OPT_RUNTIME, \
OPT_UINT(5, 21), \
BCH_SB_GC_RESERVE, 8) \
+ BCH_OPT(gc_reserve_bytes, u64, OPT_RUNTIME, \
+ OPT_UINT(0, U64_MAX), \
+ BCH_SB_GC_RESERVE_BYTES, 0) \
BCH_OPT(root_reserve_percent, u8, OPT_MOUNT, \
OPT_UINT(0, 100), \
BCH_SB_ROOT_RESERVE, 0) \