Commit a5860368 authored by Kent Overstreet's avatar Kent Overstreet
Browse files

bcachefs: Don't corrupt journal keys gap buffer when dropping alloc info

parent f3589bfa
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1338,7 +1338,7 @@ static void btree_node_read_work(struct work_struct *work)
	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);
+5 −1
Original line number Diff line number Diff line
@@ -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
+3 −0
Original line number Diff line number Diff line
@@ -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;						\