Commit 67199a47 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'bcachefs-2024-04-01' of https://evilpiepirate.org/git/bcachefs

Pull bcachefs fixes from Kent Overstreet:
 "Lots of fixes for situations with extreme filesystem damage.

  One fix ("Fix journal pins in btree write buffer") applicable to
  normal usage; also a dio performance fix.

  New repair/construction code is in the final stages, should be ready
  in about a week. Anyone that lost btree interior nodes (or a variety
  of other damage) as a result of the splitbrain bug will be able to
  repair then"

* tag 'bcachefs-2024-04-01' of https://evilpiepirate.org/git/bcachefs: (32 commits)
  bcachefs: On emergency shutdown, print out current journal sequence number
  bcachefs: Fix overlapping extent repair
  bcachefs: Fix remove_dirent()
  bcachefs: Logged op errors should be ignored
  bcachefs: Improve -o norecovery; opts.recovery_pass_limit
  bcachefs: bch2_run_explicit_recovery_pass_persistent()
  bcachefs: Ensure bch_sb_field_ext always exists
  bcachefs: Flush journal immediately after replay if we did early repair
  bcachefs: Resume logged ops after fsck
  bcachefs: Add error messages to logged ops fns
  bcachefs: Split out recovery_passes.c
  bcachefs: fix backpointer for missing alloc key msg
  bcachefs: Fix bch2_btree_increase_depth()
  bcachefs: Kill bch2_bkey_ptr_data_type()
  bcachefs: Fix use after free in check_root_trans()
  bcachefs: Fix repair path for missing indirect extents
  bcachefs: Fix use after free in bch2_check_fix_ptrs()
  bcachefs: Fix btree node keys accounting in topology repair path
  bcachefs: Check btree ptr min_key in .invalid
  bcachefs: add REQ_SYNC and REQ_IDLE in write dio
  ...
parents 026e680b b3c7fd35
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -67,6 +67,7 @@ bcachefs-y := \
	quota.o			\
	rebalance.o		\
	recovery.o		\
	recovery_passes.o	\
	reflink.o		\
	replicas.o		\
	sb-clean.o		\
+8 −5
Original line number Diff line number Diff line
@@ -29,8 +29,7 @@ static bool extent_matches_bp(struct bch_fs *c,
		if (p.ptr.cached)
			continue;

		bch2_extent_ptr_to_bp(c, btree_id, level, k, p,
				      &bucket2, &bp2);
		bch2_extent_ptr_to_bp(c, btree_id, level, k, p, entry, &bucket2, &bp2);
		if (bpos_eq(bucket, bucket2) &&
		    !memcmp(&bp, &bp2, sizeof(bp)))
			return true;
@@ -44,6 +43,11 @@ int bch2_backpointer_invalid(struct bch_fs *c, struct bkey_s_c k,
			     struct printbuf *err)
{
	struct bkey_s_c_backpointer bp = bkey_s_c_to_backpointer(k);

	/* these will be caught by fsck */
	if (!bch2_dev_exists2(c, bp.k->p.inode))
		return 0;

	struct bpos bucket = bp_pos_to_bucket(c, bp.k->p);
	int ret = 0;

@@ -378,7 +382,7 @@ static int bch2_check_btree_backpointer(struct btree_trans *trans, struct btree_
			backpointer_to_missing_alloc,
			"backpointer for nonexistent alloc key: %llu:%llu:0\n%s",
			alloc_iter.pos.inode, alloc_iter.pos.offset,
			(bch2_bkey_val_to_text(&buf, c, alloc_k), buf.buf))) {
			(bch2_bkey_val_to_text(&buf, c, k), buf.buf))) {
		ret = bch2_btree_delete_at(trans, bp_iter, 0);
		goto out;
	}
@@ -502,8 +506,7 @@ static int check_extent_to_backpointers(struct btree_trans *trans,
		if (p.ptr.cached)
			continue;

		bch2_extent_ptr_to_bp(c, btree, level,
				      k, p, &bucket_pos, &bp);
		bch2_extent_ptr_to_bp(c, btree, level, k, p, entry, &bucket_pos, &bp);

		ret = check_bp_exists(trans, s, bucket_pos, bp, k);
		if (ret)
+26 −6
Original line number Diff line number Diff line
@@ -90,20 +90,40 @@ static inline int bch2_bucket_backpointer_mod(struct btree_trans *trans,
	return bch2_trans_update_buffered(trans, BTREE_ID_backpointers, &bp_k.k_i);
}

static inline enum bch_data_type bkey_ptr_data_type(enum btree_id btree_id, unsigned level,
						    struct bkey_s_c k, struct extent_ptr_decoded p)
static inline enum bch_data_type bch2_bkey_ptr_data_type(struct bkey_s_c k,
							 struct extent_ptr_decoded p,
							 const union bch_extent_entry *entry)
{
	return  level		? BCH_DATA_btree :
		p.has_ec	? BCH_DATA_stripe :
				  BCH_DATA_user;
	switch (k.k->type) {
	case KEY_TYPE_btree_ptr:
	case KEY_TYPE_btree_ptr_v2:
		return BCH_DATA_btree;
	case KEY_TYPE_extent:
	case KEY_TYPE_reflink_v:
		return p.has_ec ? BCH_DATA_stripe : BCH_DATA_user;
	case KEY_TYPE_stripe: {
		const struct bch_extent_ptr *ptr = &entry->ptr;
		struct bkey_s_c_stripe s = bkey_s_c_to_stripe(k);

		BUG_ON(ptr < s.v->ptrs ||
		       ptr >= s.v->ptrs + s.v->nr_blocks);

		return ptr >= s.v->ptrs + s.v->nr_blocks - s.v->nr_redundant
			? BCH_DATA_parity
			: BCH_DATA_user;
	}
	default:
		BUG();
	}
}

static inline void bch2_extent_ptr_to_bp(struct bch_fs *c,
			   enum btree_id btree_id, unsigned level,
			   struct bkey_s_c k, struct extent_ptr_decoded p,
			   const union bch_extent_entry *entry,
			   struct bpos *bucket_pos, struct bch_backpointer *bp)
{
	enum bch_data_type data_type = bkey_ptr_data_type(btree_id, level, k, p);
	enum bch_data_type data_type = bch2_bkey_ptr_data_type(k, p, entry);
	s64 sectors = level ? btree_sectors(c) : k.k->size;
	u32 bucket_offset;

+1 −2
Original line number Diff line number Diff line
@@ -209,7 +209,7 @@
#include "fifo.h"
#include "nocow_locking_types.h"
#include "opts.h"
#include "recovery_types.h"
#include "recovery_passes_types.h"
#include "sb-errors_types.h"
#include "seqmutex.h"
#include "time_stats.h"
@@ -810,7 +810,6 @@ struct bch_fs {

	/* snapshot.c: */
	struct snapshot_table __rcu *snapshots;
	size_t			snapshot_table_size;
	struct mutex		snapshot_table_lock;
	struct rw_semaphore	snapshot_create_lock;

+10 −4
Original line number Diff line number Diff line
@@ -134,18 +134,24 @@ void bch2_dump_btree_node_iter(struct btree *b,
	printbuf_exit(&buf);
}

#ifdef CONFIG_BCACHEFS_DEBUG

void __bch2_verify_btree_nr_keys(struct btree *b)
struct btree_nr_keys bch2_btree_node_count_keys(struct btree *b)
{
	struct bset_tree *t;
	struct bkey_packed *k;
	struct btree_nr_keys nr = { 0 };
	struct btree_nr_keys nr = {};

	for_each_bset(b, t)
		bset_tree_for_each_key(b, t, k)
			if (!bkey_deleted(k))
				btree_keys_account_key_add(&nr, t - b->set, k);
	return nr;
}

#ifdef CONFIG_BCACHEFS_DEBUG

void __bch2_verify_btree_nr_keys(struct btree *b)
{
	struct btree_nr_keys nr = bch2_btree_node_count_keys(b);

	BUG_ON(memcmp(&nr, &b->nr, sizeof(nr)));
}
Loading