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;
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
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;
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) \