Commit 01db5e5f authored by Kent Overstreet's avatar Kent Overstreet

bcachefs: Fix insufficient disk reservation with compression + snapshots

When overwriting and splitting existing extents, we weren't correctly
accounting for a 3 way split of a compressed extent.
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent b0c279ff
...@@ -186,8 +186,11 @@ int bch2_trans_update_extent_overwrite(struct btree_trans *trans, ...@@ -186,8 +186,11 @@ int bch2_trans_update_extent_overwrite(struct btree_trans *trans,
enum btree_id btree_id = iter->btree_id; enum btree_id btree_id = iter->btree_id;
struct bkey_i *update; struct bkey_i *update;
struct bpos new_start = bkey_start_pos(new.k); struct bpos new_start = bkey_start_pos(new.k);
bool front_split = bkey_lt(bkey_start_pos(old.k), new_start); unsigned front_split = bkey_lt(bkey_start_pos(old.k), new_start);
bool back_split = bkey_gt(old.k->p, new.k->p); unsigned back_split = bkey_gt(old.k->p, new.k->p);
unsigned middle_split = (front_split || back_split) &&
old.k->p.snapshot != new.k->p.snapshot;
unsigned nr_splits = front_split + back_split + middle_split;
int ret = 0, compressed_sectors; int ret = 0, compressed_sectors;
/* /*
...@@ -195,10 +198,9 @@ int bch2_trans_update_extent_overwrite(struct btree_trans *trans, ...@@ -195,10 +198,9 @@ int bch2_trans_update_extent_overwrite(struct btree_trans *trans,
* so that __bch2_trans_commit() can increase our disk * so that __bch2_trans_commit() can increase our disk
* reservation: * reservation:
*/ */
if (((front_split && back_split) || if (nr_splits > 1 &&
((front_split || back_split) && old.k->p.snapshot != new.k->p.snapshot)) &&
(compressed_sectors = bch2_bkey_sectors_compressed(old))) (compressed_sectors = bch2_bkey_sectors_compressed(old)))
trans->extra_journal_res += compressed_sectors; trans->extra_journal_res += compressed_sectors * (nr_splits - 1);
if (front_split) { if (front_split) {
update = bch2_bkey_make_mut_noupdate(trans, old); update = bch2_bkey_make_mut_noupdate(trans, old);
...@@ -216,8 +218,7 @@ int bch2_trans_update_extent_overwrite(struct btree_trans *trans, ...@@ -216,8 +218,7 @@ int bch2_trans_update_extent_overwrite(struct btree_trans *trans,
} }
/* If we're overwriting in a different snapshot - middle split: */ /* If we're overwriting in a different snapshot - middle split: */
if (old.k->p.snapshot != new.k->p.snapshot && if (middle_split) {
(front_split || back_split)) {
update = bch2_bkey_make_mut_noupdate(trans, old); update = bch2_bkey_make_mut_noupdate(trans, old);
if ((ret = PTR_ERR_OR_ZERO(update))) if ((ret = PTR_ERR_OR_ZERO(update)))
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment