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

bcachefs: Make bkey_fsck_err() a wrapper around fsck_err()



bkey_fsck_err() was added as an interface that looks like fsck_err(),
but previously all it did was ensure that the appropriate error counter
was incremented in the superblock.

This is a cleanup and bugfix patch that converts it to a wrapper around
fsck_err(). This is needed to fix an issue with the upgrade path to
disk_accounting_v3, where the "silent fix" error list now includes
bkey_fsck errors; fsck_err() handles this in a unified way, and since we
need to change printing of bkey fsck errors from the caller to the inner
bkey_fsck_err() calls, this ends up being a pretty big change.

Als,, rename .invalid() methods to .validate(), for clarity, while we're
changing the function signature anyways (to drop the printbuf argument).

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent c9947102
Loading
Loading
Loading
Loading
+29 −34
Original line number Diff line number Diff line
@@ -196,75 +196,71 @@ static unsigned bch_alloc_v1_val_u64s(const struct bch_alloc *a)
	return DIV_ROUND_UP(bytes, sizeof(u64));
}

int bch2_alloc_v1_invalid(struct bch_fs *c, struct bkey_s_c k,
			  enum bch_validate_flags flags,
			  struct printbuf *err)
int bch2_alloc_v1_validate(struct bch_fs *c, struct bkey_s_c k,
			   enum bch_validate_flags flags)
{
	struct bkey_s_c_alloc a = bkey_s_c_to_alloc(k);
	int ret = 0;

	/* allow for unknown fields */
	bkey_fsck_err_on(bkey_val_u64s(a.k) < bch_alloc_v1_val_u64s(a.v), c, err,
			 alloc_v1_val_size_bad,
	bkey_fsck_err_on(bkey_val_u64s(a.k) < bch_alloc_v1_val_u64s(a.v),
			 c, alloc_v1_val_size_bad,
			 "incorrect value size (%zu < %u)",
			 bkey_val_u64s(a.k), bch_alloc_v1_val_u64s(a.v));
fsck_err:
	return ret;
}

int bch2_alloc_v2_invalid(struct bch_fs *c, struct bkey_s_c k,
			  enum bch_validate_flags flags,
			  struct printbuf *err)
int bch2_alloc_v2_validate(struct bch_fs *c, struct bkey_s_c k,
			   enum bch_validate_flags flags)
{
	struct bkey_alloc_unpacked u;
	int ret = 0;

	bkey_fsck_err_on(bch2_alloc_unpack_v2(&u, k), c, err,
			 alloc_v2_unpack_error,
	bkey_fsck_err_on(bch2_alloc_unpack_v2(&u, k),
			 c, alloc_v2_unpack_error,
			 "unpack error");
fsck_err:
	return ret;
}

int bch2_alloc_v3_invalid(struct bch_fs *c, struct bkey_s_c k,
			  enum bch_validate_flags flags,
			  struct printbuf *err)
int bch2_alloc_v3_validate(struct bch_fs *c, struct bkey_s_c k,
			   enum bch_validate_flags flags)
{
	struct bkey_alloc_unpacked u;
	int ret = 0;

	bkey_fsck_err_on(bch2_alloc_unpack_v3(&u, k), c, err,
			 alloc_v2_unpack_error,
	bkey_fsck_err_on(bch2_alloc_unpack_v3(&u, k),
			 c, alloc_v2_unpack_error,
			 "unpack error");
fsck_err:
	return ret;
}

int bch2_alloc_v4_invalid(struct bch_fs *c, struct bkey_s_c k,
			  enum bch_validate_flags flags, struct printbuf *err)
int bch2_alloc_v4_validate(struct bch_fs *c, struct bkey_s_c k,
			   enum bch_validate_flags flags)
{
	struct bkey_s_c_alloc_v4 a = bkey_s_c_to_alloc_v4(k);
	int ret = 0;

	bkey_fsck_err_on(alloc_v4_u64s_noerror(a.v) > bkey_val_u64s(k.k), c, err,
			 alloc_v4_val_size_bad,
	bkey_fsck_err_on(alloc_v4_u64s_noerror(a.v) > bkey_val_u64s(k.k),
			 c, alloc_v4_val_size_bad,
			 "bad val size (%u > %zu)",
			 alloc_v4_u64s_noerror(a.v), bkey_val_u64s(k.k));

	bkey_fsck_err_on(!BCH_ALLOC_V4_BACKPOINTERS_START(a.v) &&
			 BCH_ALLOC_V4_NR_BACKPOINTERS(a.v), c, err,
			 alloc_v4_backpointers_start_bad,
			 BCH_ALLOC_V4_NR_BACKPOINTERS(a.v),
			 c, alloc_v4_backpointers_start_bad,
			 "invalid backpointers_start");

	bkey_fsck_err_on(alloc_data_type(*a.v, a.v->data_type) != a.v->data_type, c, err,
			 alloc_key_data_type_bad,
	bkey_fsck_err_on(alloc_data_type(*a.v, a.v->data_type) != a.v->data_type,
			 c, alloc_key_data_type_bad,
			 "invalid data type (got %u should be %u)",
			 a.v->data_type, alloc_data_type(*a.v, a.v->data_type));

	for (unsigned i = 0; i < 2; i++)
		bkey_fsck_err_on(a.v->io_time[i] > LRU_TIME_MAX,
				 c, err,
				 alloc_key_io_time_bad,
				 c, alloc_key_io_time_bad,
				 "invalid io_time[%s]: %llu, max %llu",
				 i == READ ? "read" : "write",
				 a.v->io_time[i], LRU_TIME_MAX);
@@ -282,7 +278,7 @@ int bch2_alloc_v4_invalid(struct bch_fs *c, struct bkey_s_c k,
				 a.v->dirty_sectors ||
				 a.v->cached_sectors ||
				 a.v->stripe,
				 c, err, alloc_key_empty_but_have_data,
				 c, alloc_key_empty_but_have_data,
				 "empty data type free but have data %u.%u.%u %u",
				 stripe_sectors,
				 a.v->dirty_sectors,
@@ -296,7 +292,7 @@ int bch2_alloc_v4_invalid(struct bch_fs *c, struct bkey_s_c k,
	case BCH_DATA_parity:
		bkey_fsck_err_on(!a.v->dirty_sectors &&
				 !stripe_sectors,
				 c, err, alloc_key_dirty_sectors_0,
				 c, alloc_key_dirty_sectors_0,
				 "data_type %s but dirty_sectors==0",
				 bch2_data_type_str(a.v->data_type));
		break;
@@ -305,12 +301,12 @@ int bch2_alloc_v4_invalid(struct bch_fs *c, struct bkey_s_c k,
				 a.v->dirty_sectors ||
				 stripe_sectors ||
				 a.v->stripe,
				 c, err, alloc_key_cached_inconsistency,
				 c, alloc_key_cached_inconsistency,
				 "data type inconsistency");

		bkey_fsck_err_on(!a.v->io_time[READ] &&
				 c->curr_recovery_pass > BCH_RECOVERY_PASS_check_alloc_to_lru_refs,
				 c, err, alloc_key_cached_but_read_time_zero,
				 c, alloc_key_cached_but_read_time_zero,
				 "cached bucket with read_time == 0");
		break;
	case BCH_DATA_stripe:
@@ -513,14 +509,13 @@ static unsigned alloc_gen(struct bkey_s_c k, unsigned offset)
		: 0;
}

int bch2_bucket_gens_invalid(struct bch_fs *c, struct bkey_s_c k,
			     enum bch_validate_flags flags,
			     struct printbuf *err)
int bch2_bucket_gens_validate(struct bch_fs *c, struct bkey_s_c k,
			     enum bch_validate_flags flags)
{
	int ret = 0;

	bkey_fsck_err_on(bkey_val_bytes(k.k) != sizeof(struct bch_bucket_gens), c, err,
			 bucket_gens_val_size_bad,
	bkey_fsck_err_on(bkey_val_bytes(k.k) != sizeof(struct bch_bucket_gens),
			 c, bucket_gens_val_size_bad,
			 "bad val size (%zu != %zu)",
			 bkey_val_bytes(k.k), sizeof(struct bch_bucket_gens));
fsck_err:
+11 −15
Original line number Diff line number Diff line
@@ -240,52 +240,48 @@ struct bkey_i_alloc_v4 *bch2_alloc_to_v4_mut(struct btree_trans *, struct bkey_s

int bch2_bucket_io_time_reset(struct btree_trans *, unsigned, size_t, int);

int bch2_alloc_v1_invalid(struct bch_fs *, struct bkey_s_c,
			  enum bch_validate_flags, struct printbuf *);
int bch2_alloc_v2_invalid(struct bch_fs *, struct bkey_s_c,
			  enum bch_validate_flags, struct printbuf *);
int bch2_alloc_v3_invalid(struct bch_fs *, struct bkey_s_c,
			  enum bch_validate_flags, struct printbuf *);
int bch2_alloc_v4_invalid(struct bch_fs *, struct bkey_s_c,
			  enum bch_validate_flags, struct printbuf *);
int bch2_alloc_v1_validate(struct bch_fs *, struct bkey_s_c, enum bch_validate_flags);
int bch2_alloc_v2_validate(struct bch_fs *, struct bkey_s_c, enum bch_validate_flags);
int bch2_alloc_v3_validate(struct bch_fs *, struct bkey_s_c, enum bch_validate_flags);
int bch2_alloc_v4_validate(struct bch_fs *, struct bkey_s_c, enum bch_validate_flags);
void bch2_alloc_v4_swab(struct bkey_s);
void bch2_alloc_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);

#define bch2_bkey_ops_alloc ((struct bkey_ops) {	\
	.key_invalid	= bch2_alloc_v1_invalid,	\
	.key_validate	= bch2_alloc_v1_validate,	\
	.val_to_text	= bch2_alloc_to_text,		\
	.trigger	= bch2_trigger_alloc,		\
	.min_val_size	= 8,				\
})

#define bch2_bkey_ops_alloc_v2 ((struct bkey_ops) {	\
	.key_invalid	= bch2_alloc_v2_invalid,	\
	.key_validate	= bch2_alloc_v2_validate,	\
	.val_to_text	= bch2_alloc_to_text,		\
	.trigger	= bch2_trigger_alloc,		\
	.min_val_size	= 8,				\
})

#define bch2_bkey_ops_alloc_v3 ((struct bkey_ops) {	\
	.key_invalid	= bch2_alloc_v3_invalid,	\
	.key_validate	= bch2_alloc_v3_validate,	\
	.val_to_text	= bch2_alloc_to_text,		\
	.trigger	= bch2_trigger_alloc,		\
	.min_val_size	= 16,				\
})

#define bch2_bkey_ops_alloc_v4 ((struct bkey_ops) {	\
	.key_invalid	= bch2_alloc_v4_invalid,	\
	.key_validate	= bch2_alloc_v4_validate,	\
	.val_to_text	= bch2_alloc_to_text,		\
	.swab		= bch2_alloc_v4_swab,		\
	.trigger	= bch2_trigger_alloc,		\
	.min_val_size	= 48,				\
})

int bch2_bucket_gens_invalid(struct bch_fs *, struct bkey_s_c,
			     enum bch_validate_flags, struct printbuf *);
int bch2_bucket_gens_validate(struct bch_fs *, struct bkey_s_c,
			     enum bch_validate_flags);
void bch2_bucket_gens_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);

#define bch2_bkey_ops_bucket_gens ((struct bkey_ops) {	\
	.key_invalid	= bch2_bucket_gens_invalid,	\
	.key_validate	= bch2_bucket_gens_validate,	\
	.val_to_text	= bch2_bucket_gens_to_text,	\
})

+3 −5
Original line number Diff line number Diff line
@@ -47,9 +47,8 @@ static bool extent_matches_bp(struct bch_fs *c,
	return false;
}

int bch2_backpointer_invalid(struct bch_fs *c, struct bkey_s_c k,
			     enum bch_validate_flags flags,
			     struct printbuf *err)
int bch2_backpointer_validate(struct bch_fs *c, struct bkey_s_c k,
			      enum bch_validate_flags flags)
{
	struct bkey_s_c_backpointer bp = bkey_s_c_to_backpointer(k);

@@ -68,8 +67,7 @@ int bch2_backpointer_invalid(struct bch_fs *c, struct bkey_s_c k,

	bkey_fsck_err_on((bp.v->bucket_offset >> MAX_EXTENT_COMPRESS_RATIO_SHIFT) >= ca->mi.bucket_size ||
			 !bpos_eq(bp.k->p, bp_pos),
			 c, err,
			 backpointer_bucket_offset_wrong,
			 c, backpointer_bucket_offset_wrong,
			 "backpointer bucket_offset wrong");
fsck_err:
	return ret;
+2 −3
Original line number Diff line number Diff line
@@ -18,14 +18,13 @@ static inline u64 swab40(u64 x)
		((x & 0xff00000000ULL) >> 32));
}

int bch2_backpointer_invalid(struct bch_fs *, struct bkey_s_c k,
			     enum bch_validate_flags, struct printbuf *);
int bch2_backpointer_validate(struct bch_fs *, struct bkey_s_c k, enum bch_validate_flags);
void bch2_backpointer_to_text(struct printbuf *, const struct bch_backpointer *);
void bch2_backpointer_k_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
void bch2_backpointer_swab(struct bkey_s);

#define bch2_bkey_ops_backpointer ((struct bkey_ops) {	\
	.key_invalid	= bch2_backpointer_invalid,	\
	.key_validate	= bch2_backpointer_validate,	\
	.val_to_text	= bch2_backpointer_k_to_text,	\
	.swab		= bch2_backpointer_swab,	\
	.min_val_size	= 32,				\
+4 −3
Original line number Diff line number Diff line
@@ -10,9 +10,10 @@
#include "vstructs.h"

enum bch_validate_flags {
	BCH_VALIDATE_write		= (1U << 0),
	BCH_VALIDATE_commit		= (1U << 1),
	BCH_VALIDATE_journal		= (1U << 2),
	BCH_VALIDATE_write		= BIT(0),
	BCH_VALIDATE_commit		= BIT(1),
	BCH_VALIDATE_journal		= BIT(2),
	BCH_VALIDATE_silent		= BIT(3),
};

#if 0
Loading