summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2024-03-16 21:22:47 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2024-03-17 21:17:38 -0400
commita58603684195ea892da5612580762fd3151b2a7b (patch)
treec716679279dfab8d1f758e542da8e86c0d5aef96 /fs
parentf3589bfa7ee4aff118908e910d05ba96b1858633 (diff)
bcachefs: Don't corrupt journal keys gap buffer when dropping alloc info
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs')
-rw-r--r--fs/bcachefs/btree_io.c2
-rw-r--r--fs/bcachefs/recovery.c6
-rw-r--r--fs/bcachefs/util.h3
3 files changed, 9 insertions, 2 deletions
diff --git a/fs/bcachefs/btree_io.c b/fs/bcachefs/btree_io.c
index 624c8287deb4..44856f018adf 100644
--- a/fs/bcachefs/btree_io.c
+++ b/fs/bcachefs/btree_io.c
@@ -1338,7 +1338,7 @@ start:
if (saw_error && !btree_node_read_error(b)) {
printbuf_reset(&buf);
bch2_bpos_to_text(&buf, b->key.k.p);
- bch_info(c, "%s: rewriting btree node at btree=%s level=%u %s due to error",
+ bch_err_ratelimited(c, "%s: rewriting btree node at btree=%s level=%u %s due to error",
__func__, bch2_btree_id_str(b->c.btree_id), b->c.level, buf.buf);
bch2_btree_node_rewrite_async(c, b);
diff --git a/fs/bcachefs/recovery.c b/fs/bcachefs/recovery.c
index 2af219aedfdb..03f9d6afe467 100644
--- a/fs/bcachefs/recovery.c
+++ b/fs/bcachefs/recovery.c
@@ -90,10 +90,12 @@ static void do_reconstruct_alloc(struct bch_fs *c)
struct journal_keys *keys = &c->journal_keys;
size_t src, dst;
+ move_gap(keys, keys->nr);
+
for (src = 0, dst = 0; src < keys->nr; src++)
if (!btree_id_is_alloc(keys->data[src].btree_id))
keys->data[dst++] = keys->data[src];
- keys->nr = dst;
+ keys->nr = keys->gap = dst;
}
/*
@@ -203,6 +205,8 @@ static int bch2_journal_replay(struct bch_fs *c)
BUG_ON(!atomic_read(&keys->ref));
+ move_gap(keys, keys->nr);
+
/*
* First, attempt to replay keys in sorted order. This is more
* efficient - better locality of btree access - but some might fail if
diff --git a/fs/bcachefs/util.h b/fs/bcachefs/util.h
index 7ffbddb80400..175aee3074c7 100644
--- a/fs/bcachefs/util.h
+++ b/fs/bcachefs/util.h
@@ -683,6 +683,9 @@ static inline void __move_gap(void *array, size_t element_size,
/* Move the gap in a gap buffer: */
#define move_gap(_d, _new_gap) \
do { \
+ BUG_ON(_new_gap > (_d)->nr); \
+ BUG_ON((_d)->gap > (_d)->nr); \
+ \
__move_gap((_d)->data, sizeof((_d)->data[0]), \
(_d)->nr, (_d)->size, (_d)->gap, _new_gap); \
(_d)->gap = _new_gap; \