Update bcachefs sources to 656fe6ab62bd bcachefs: kill silly gcc warning
Some checks failed
build / bcachefs-tools-msrv (push) Has been cancelled
.deb build orchestrator / source-only (push) Has been cancelled
.deb build orchestrator / obs (push) Has been cancelled
.deb build orchestrator / buildd (map[name:debian version:forky], map[build-arch:amd64 host-arch:amd64 machine-arch:amd64 runs-on:ubuntu-24.04]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:debian version:forky], map[build-arch:amd64 host-arch:ppc64el machine-arch:amd64 runs-on:ubuntu-24.04]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:debian version:forky], map[build-arch:arm64 host-arch:arm64 machine-arch:arm64 runs-on:ubuntu-24.04-arm]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:debian version:trixie], map[build-arch:amd64 host-arch:amd64 machine-arch:amd64 runs-on:ubuntu-24.04]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:debian version:trixie], map[build-arch:amd64 host-arch:ppc64el machine-arch:amd64 runs-on:ubuntu-24.04]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:debian version:trixie], map[build-arch:arm64 host-arch:arm64 machine-arch:arm64 runs-on:ubuntu-24.04-arm]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:debian version:unstable], map[build-arch:amd64 host-arch:amd64 machine-arch:amd64 runs-on:ubuntu-24.04]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:debian version:unstable], map[build-arch:amd64 host-arch:ppc64el machine-arch:amd64 runs-on:ubuntu-24.04]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:debian version:unstable], map[build-arch:arm64 host-arch:arm64 machine-arch:arm64 runs-on:ubuntu-24.04-arm]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:ubuntu version:plucky], map[build-arch:amd64 host-arch:amd64 machine-arch:amd64 runs-on:ubuntu-24.04]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:ubuntu version:plucky], map[build-arch:arm64 host-arch:arm64 machine-arch:arm64 runs-on:ubuntu-24.04-arm]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:ubuntu version:questing], map[build-arch:amd64 host-arch:amd64 machine-arch:amd64 runs-on:ubuntu-24.04]) (push) Has been cancelled
.deb build orchestrator / buildd (map[name:ubuntu version:questing], map[build-arch:arm64 host-arch:arm64 machine-arch:arm64 runs-on:ubuntu-24.04-arm]) (push) Has been cancelled
.deb build orchestrator / reprotest (push) Has been cancelled
.deb build orchestrator / publish (push) Has been cancelled
Nix Flake actions / nix-matrix (push) Has been cancelled
Nix Flake actions / ${{ matrix.name }} (${{ matrix.system }}) (push) Has been cancelled

This commit is contained in:
Kent Overstreet 2025-12-04 12:27:23 -05:00
parent 9694ddaba1
commit b33db73147
12 changed files with 134 additions and 197 deletions

View File

@ -1 +1 @@
92092a7729703f2285902b56aacaae199a3517eb 656fe6ab62bd41321e90e1567e6bf9c3ea058633

View File

@ -95,21 +95,10 @@ void bch2_btree_node_wait_on_write(struct btree *b)
TASK_UNINTERRUPTIBLE); TASK_UNINTERRUPTIBLE);
} }
static void btree_err_msg(struct printbuf *out, struct bch_fs *c, static void btree_err_msg(struct printbuf *out, struct bch_fs *c, struct bch_dev *ca,
struct bch_dev *ca,
bool print_pos,
struct btree *b, struct bset *i, struct bkey_packed *k, struct btree *b, struct bset *i, struct bkey_packed *k,
unsigned offset, int rw) const char *fmt, va_list args)
{ {
if (print_pos) {
prt_str(out, rw == READ
? "error validating btree node "
: "corrupt btree node before write ");
prt_printf(out, "at btree ");
bch2_btree_pos_to_text(out, c, b);
prt_newline(out);
}
if (ca) if (ca)
prt_printf(out, "%s ", ca->name); prt_printf(out, "%s ", ca->name);
@ -122,10 +111,13 @@ static void btree_err_msg(struct printbuf *out, struct bch_fs *c,
(unsigned long)(void *)k - (unsigned long)(void *)k -
((unsigned long)(void *)i & ~511UL)); ((unsigned long)(void *)i & ~511UL));
prt_str(out, ": "); prt_str(out, ": ");
prt_vprintf(out, fmt, args);
prt_newline(out);
} }
__printf(11, 12) __printf(11, 12)
static int __btree_err(int ret, static int __btree_err(enum bch_fsck_flags flags,
struct bch_fs *c, struct bch_fs *c,
struct bch_dev *ca, struct bch_dev *ca,
struct btree *b, struct btree *b,
@ -138,99 +130,47 @@ static int __btree_err(int ret,
const char *fmt, ...) const char *fmt, ...)
{ {
if (c->recovery.curr_pass == BCH_RECOVERY_PASS_scan_for_btree_nodes) if (c->recovery.curr_pass == BCH_RECOVERY_PASS_scan_for_btree_nodes)
return ret == -BCH_ERR_btree_node_read_err_fixable return flags & FSCK_CAN_FIX
? bch_err_throw(c, fsck_fix) ? bch_err_throw(c, fsck_fix)
: ret; : bch_err_throw(c, btree_node_validate_err);
bool have_retry = false; bch2_sb_error_count(c, err_type);
int ret2;
if (rw == READ) {
va_list args;
va_start(args, fmt);
btree_err_msg(err_msg, c, ca, b, i, k, fmt, args);
va_end(args);
if (ca) {
bch2_dev_io_failures_mut(failed, ca->dev_idx)->errcode = bch2_dev_io_failures_mut(failed, ca->dev_idx)->errcode =
bch_err_throw(c, btree_node_validate_err); bch_err_throw(c, btree_node_validate_err);
struct extent_ptr_decoded pick; struct extent_ptr_decoded pick;
have_retry = bch2_bkey_pick_read_device(c, bool have_retry = bch2_bkey_pick_read_device(c,
bkey_i_to_s_c(&b->key), bkey_i_to_s_c(&b->key),
failed, &pick, -1) == 1; failed, &pick, -1) == 1;
return !have_retry &&
(flags & FSCK_CAN_FIX) &&
bch2_fsck_err_opt(c, FSCK_CAN_FIX, err_type) == -BCH_ERR_fsck_fix
? bch_err_throw(c, fsck_fix)
: bch_err_throw(c, btree_node_validate_err);
} else {
CLASS(bch_log_msg, msg)(c);
prt_str(&msg.m, "corrupt btree node before write at btree ");
bch2_btree_pos_to_text(&msg.m, c, b);
prt_newline(&msg.m);
va_list args;
va_start(args, fmt);
btree_err_msg(&msg.m, c, NULL, b, i, k, fmt, args);
va_end(args);
bch2_fs_emergency_read_only2(c, &msg.m);
return bch_err_throw(c, fsck_errors_not_fixed);
} }
if (!have_retry && ret == -BCH_ERR_btree_node_read_err_want_retry)
ret = bch_err_throw(c, btree_node_read_err_fixable);
if (!have_retry && ret == -BCH_ERR_btree_node_read_err_must_retry)
ret = bch_err_throw(c, btree_node_read_err_bad_node);
bch2_sb_error_count(c, err_type);
bool print_deferred = err_msg &&
rw == READ &&
!(test_bit(BCH_FS_in_fsck, &c->flags) &&
c->opts.fix_errors == FSCK_FIX_ask);
CLASS(printbuf, out)();
bch2_log_msg_start(c, &out);
if (!print_deferred)
err_msg = &out;
btree_err_msg(err_msg, c, ca, !print_deferred, b, i, k, b->written, rw);
va_list args;
va_start(args, fmt);
prt_vprintf(err_msg, fmt, args);
va_end(args);
if (print_deferred) {
prt_newline(err_msg);
switch (ret) {
case -BCH_ERR_btree_node_read_err_fixable:
ret2 = bch2_fsck_err_opt(c, FSCK_CAN_FIX, err_type);
if (!bch2_err_matches(ret2, BCH_ERR_fsck_fix) &&
!bch2_err_matches(ret2, BCH_ERR_fsck_ignore)) {
ret = ret2;
goto fsck_err;
}
if (!have_retry)
ret = bch_err_throw(c, fsck_fix);
return ret;
case -BCH_ERR_btree_node_read_err_bad_node:
prt_str(&out, ", ");
break;
}
return ret;
}
if (rw == WRITE) {
prt_str(&out, ", ");
ret = __bch2_inconsistent_error(c, &out)
? -BCH_ERR_fsck_errors_not_fixed
: 0;
goto print;
}
switch (ret) {
case -BCH_ERR_btree_node_read_err_fixable:
ret2 = __bch2_fsck_err(c, NULL, FSCK_CAN_FIX, err_type, "%s", out.buf);
if (!bch2_err_matches(ret2, BCH_ERR_fsck_fix) &&
!bch2_err_matches(ret2, BCH_ERR_fsck_ignore)) {
ret = ret2;
goto fsck_err;
}
if (!have_retry)
ret = bch_err_throw(c, fsck_fix);
return ret;
case -BCH_ERR_btree_node_read_err_bad_node:
prt_str(&out, ", ");
break;
}
print:
bch2_print_str(c, KERN_ERR, out.buf);
fsck_err:
return ret;
} }
#define btree_err(type, c, ca, b, i, k, _err_type, msg, ...) \ #define btree_err(type, c, ca, b, i, k, _err_type, msg, ...) \
@ -313,7 +253,7 @@ int bch2_validate_bset(struct bch_fs *c, struct bch_dev *ca,
int ret = 0; int ret = 0;
btree_err_on(!bch2_version_compatible(version), btree_err_on(!bch2_version_compatible(version),
-BCH_ERR_btree_node_read_err_incompatible, 0,
c, ca, b, i, NULL, c, ca, b, i, NULL,
btree_node_unsupported_version, btree_node_unsupported_version,
"unsupported bset version %u.%u", "unsupported bset version %u.%u",
@ -322,8 +262,8 @@ int bch2_validate_bset(struct bch_fs *c, struct bch_dev *ca,
if (c->recovery.curr_pass != BCH_RECOVERY_PASS_scan_for_btree_nodes && if (c->recovery.curr_pass != BCH_RECOVERY_PASS_scan_for_btree_nodes &&
btree_err_on(version < c->sb.version_min, btree_err_on(version < c->sb.version_min,
-BCH_ERR_btree_node_read_err_fixable, FSCK_CAN_FIX,
c, NULL, b, i, NULL, c, ca, b, i, NULL,
btree_node_bset_older_than_sb_min, btree_node_bset_older_than_sb_min,
"bset version %u older than superblock version_min %u", "bset version %u older than superblock version_min %u",
version, c->sb.version_min)) { version, c->sb.version_min)) {
@ -339,8 +279,8 @@ int bch2_validate_bset(struct bch_fs *c, struct bch_dev *ca,
if (btree_err_on(BCH_VERSION_MAJOR(version) > if (btree_err_on(BCH_VERSION_MAJOR(version) >
BCH_VERSION_MAJOR(c->sb.version), BCH_VERSION_MAJOR(c->sb.version),
-BCH_ERR_btree_node_read_err_fixable, FSCK_CAN_FIX,
c, NULL, b, i, NULL, c, ca, b, i, NULL,
btree_node_bset_newer_than_sb, btree_node_bset_newer_than_sb,
"bset version %u newer than superblock version %u", "bset version %u newer than superblock version %u",
version, c->sb.version)) { version, c->sb.version)) {
@ -350,19 +290,19 @@ int bch2_validate_bset(struct bch_fs *c, struct bch_dev *ca,
} }
btree_err_on(BSET_SEPARATE_WHITEOUTS(i), btree_err_on(BSET_SEPARATE_WHITEOUTS(i),
-BCH_ERR_btree_node_read_err_incompatible, 0,
c, ca, b, i, NULL, c, ca, b, i, NULL,
btree_node_unsupported_version, btree_node_unsupported_version,
"BSET_SEPARATE_WHITEOUTS no longer supported"); "BSET_SEPARATE_WHITEOUTS no longer supported");
btree_err_on(offset && !i->u64s, btree_err_on(offset && !i->u64s,
-BCH_ERR_btree_node_read_err_fixable, FSCK_CAN_FIX,
c, ca, b, i, NULL, c, ca, b, i, NULL,
bset_empty, bset_empty,
"empty bset"); "empty bset");
btree_err_on(BSET_OFFSET(i) && BSET_OFFSET(i) != offset, btree_err_on(BSET_OFFSET(i) && BSET_OFFSET(i) != offset,
-BCH_ERR_btree_node_read_err_want_retry, FSCK_CAN_FIX,
c, ca, b, i, NULL, c, ca, b, i, NULL,
bset_wrong_sector_offset, bset_wrong_sector_offset,
"bset at wrong sector offset"); "bset at wrong sector offset");
@ -378,20 +318,20 @@ int bch2_validate_bset(struct bch_fs *c, struct bch_dev *ca,
/* XXX endianness */ /* XXX endianness */
btree_err_on(bp->seq != bn->keys.seq, btree_err_on(bp->seq != bn->keys.seq,
-BCH_ERR_btree_node_read_err_must_retry, 0,
c, ca, b, NULL, NULL, c, ca, b, NULL, NULL,
bset_bad_seq, bset_bad_seq,
"incorrect sequence number (wrong btree node)"); "incorrect sequence number (wrong btree node)");
} }
btree_err_on(BTREE_NODE_ID(bn) != b->c.btree_id, btree_err_on(BTREE_NODE_ID(bn) != b->c.btree_id,
-BCH_ERR_btree_node_read_err_must_retry, 0,
c, ca, b, i, NULL, c, ca, b, i, NULL,
btree_node_bad_btree, btree_node_bad_btree,
"incorrect btree id"); "incorrect btree id");
btree_err_on(BTREE_NODE_LEVEL(bn) != b->c.level, btree_err_on(BTREE_NODE_LEVEL(bn) != b->c.level,
-BCH_ERR_btree_node_read_err_must_retry, 0,
c, ca, b, i, NULL, c, ca, b, i, NULL,
btree_node_bad_level, btree_node_bad_level,
"incorrect level"); "incorrect level");
@ -410,7 +350,7 @@ int bch2_validate_bset(struct bch_fs *c, struct bch_dev *ca,
} }
btree_err_on(!bpos_eq(b->data->min_key, bp->min_key), btree_err_on(!bpos_eq(b->data->min_key, bp->min_key),
-BCH_ERR_btree_node_read_err_must_retry, 0,
c, ca, b, NULL, NULL, c, ca, b, NULL, NULL,
btree_node_bad_min_key, btree_node_bad_min_key,
"incorrect min_key: got %s should be %s", "incorrect min_key: got %s should be %s",
@ -421,7 +361,7 @@ int bch2_validate_bset(struct bch_fs *c, struct bch_dev *ca,
} }
btree_err_on(!bpos_eq(bn->max_key, b->key.k.p), btree_err_on(!bpos_eq(bn->max_key, b->key.k.p),
-BCH_ERR_btree_node_read_err_must_retry, 0,
c, ca, b, i, NULL, c, ca, b, i, NULL,
btree_node_bad_max_key, btree_node_bad_max_key,
"incorrect max key %s", "incorrect max key %s",
@ -433,7 +373,7 @@ int bch2_validate_bset(struct bch_fs *c, struct bch_dev *ca,
BSET_BIG_ENDIAN(i), write, bn); BSET_BIG_ENDIAN(i), write, bn);
btree_err_on(bch2_bkey_format_invalid(c, &bn->format, write, &buf1), btree_err_on(bch2_bkey_format_invalid(c, &bn->format, write, &buf1),
-BCH_ERR_btree_node_read_err_bad_node, 0,
c, ca, b, i, NULL, c, ca, b, i, NULL,
btree_node_bad_format, btree_node_bad_format,
"invalid bkey format: %s\n%s", buf1.buf, "invalid bkey format: %s\n%s", buf1.buf,
@ -508,7 +448,9 @@ static inline int btree_node_read_bkey_cmp(const struct btree *b,
?: (int) bkey_deleted(r) - (int) bkey_deleted(l); ?: (int) bkey_deleted(r) - (int) bkey_deleted(l);
} }
int bch2_validate_bset_keys(struct bch_fs *c, struct btree *b, int bch2_validate_bset_keys(struct bch_fs *c,
struct bch_dev *ca,
struct btree *b,
struct bset *i, int write, struct bset *i, int write,
struct bch_io_failures *failed, struct bch_io_failures *failed,
struct printbuf *err_msg) struct printbuf *err_msg)
@ -527,8 +469,8 @@ int bch2_validate_bset_keys(struct bch_fs *c, struct btree *b,
unsigned next_good_key; unsigned next_good_key;
if (btree_err_on(bkey_p_next(k) > vstruct_last(i), if (btree_err_on(bkey_p_next(k) > vstruct_last(i),
-BCH_ERR_btree_node_read_err_fixable, FSCK_CAN_FIX,
c, NULL, b, i, k, c, ca, b, i, k,
btree_node_bkey_past_bset_end, btree_node_bkey_past_bset_end,
"key extends past end of bset")) { "key extends past end of bset")) {
i->u64s = cpu_to_le16((u64 *) k - i->_data); i->u64s = cpu_to_le16((u64 *) k - i->_data);
@ -536,15 +478,15 @@ int bch2_validate_bset_keys(struct bch_fs *c, struct btree *b,
} }
if (btree_err_on(k->format > KEY_FORMAT_CURRENT, if (btree_err_on(k->format > KEY_FORMAT_CURRENT,
-BCH_ERR_btree_node_read_err_fixable, FSCK_CAN_FIX,
c, NULL, b, i, k, c, ca, b, i, k,
btree_node_bkey_bad_format, btree_node_bkey_bad_format,
"invalid bkey format %u", k->format)) "invalid bkey format %u", k->format))
goto drop_this_key; goto drop_this_key;
if (btree_err_on(!bkeyp_u64s_valid(&b->format, k), if (btree_err_on(!bkeyp_u64s_valid(&b->format, k),
-BCH_ERR_btree_node_read_err_fixable, FSCK_CAN_FIX,
c, NULL, b, i, k, c, ca, b, i, k,
btree_node_bkey_bad_u64s, btree_node_bkey_bad_u64s,
"bad k->u64s %u (min %u max %zu)", k->u64s, "bad k->u64s %u (min %u max %zu)", k->u64s,
bkeyp_key_u64s(&b->format, k), bkeyp_key_u64s(&b->format, k),
@ -578,8 +520,8 @@ int bch2_validate_bset_keys(struct bch_fs *c, struct btree *b,
prt_printf(&buf, " > "); prt_printf(&buf, " > ");
bch2_bkey_to_text(&buf, u.k); bch2_bkey_to_text(&buf, u.k);
if (btree_err(-BCH_ERR_btree_node_read_err_fixable, if (btree_err(FSCK_CAN_FIX,
c, NULL, b, i, k, c, ca, b, i, k,
btree_node_bkey_out_of_order, btree_node_bkey_out_of_order,
"%s", buf.buf)) "%s", buf.buf))
goto drop_this_key; goto drop_this_key;
@ -665,13 +607,13 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct bch_dev *ca,
sort_iter_init(iter, b, (btree_blocks(c) + 1) * 2); sort_iter_init(iter, b, (btree_blocks(c) + 1) * 2);
if (bch2_meta_read_fault("btree")) if (bch2_meta_read_fault("btree"))
btree_err(-BCH_ERR_btree_node_read_err_must_retry, btree_err(0,
c, ca, b, NULL, NULL, c, ca, b, NULL, NULL,
btree_node_fault_injected, btree_node_fault_injected,
"dynamic fault"); "dynamic fault");
btree_err_on(le64_to_cpu(b->data->magic) != bset_magic(c), btree_err_on(le64_to_cpu(b->data->magic) != bset_magic(c),
-BCH_ERR_btree_node_read_err_must_retry, 0,
c, ca, b, NULL, NULL, c, ca, b, NULL, NULL,
btree_node_bad_magic, btree_node_bad_magic,
"bad magic: want %llx, got %llx", "bad magic: want %llx, got %llx",
@ -697,8 +639,8 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct bch_dev *ca,
btree_err_on(!good_csum_type, btree_err_on(!good_csum_type,
bch2_csum_type_is_encryption(BSET_CSUM_TYPE(i)) bch2_csum_type_is_encryption(BSET_CSUM_TYPE(i))
? -BCH_ERR_btree_node_read_err_must_retry ? 0
: -BCH_ERR_btree_node_read_err_want_retry, : FSCK_CAN_FIX,
c, ca, b, i, NULL, c, ca, b, i, NULL,
bset_unknown_csum, bset_unknown_csum,
"unknown checksum type %llu", BSET_CSUM_TYPE(i)); "unknown checksum type %llu", BSET_CSUM_TYPE(i));
@ -706,7 +648,7 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct bch_dev *ca,
if (first) { if (first) {
sectors = vstruct_sectors(b->data, c->block_bits); sectors = vstruct_sectors(b->data, c->block_bits);
if (btree_err_on(b->written + sectors > (ptr_written ?: btree_sectors(c)), if (btree_err_on(b->written + sectors > (ptr_written ?: btree_sectors(c)),
-BCH_ERR_btree_node_read_err_fixable, FSCK_CAN_FIX,
c, ca, b, i, NULL, c, ca, b, i, NULL,
bset_past_end_of_btree_node, bset_past_end_of_btree_node,
"bset past end of btree node (offset %u len %u but written %zu)", "bset past end of btree node (offset %u len %u but written %zu)",
@ -719,7 +661,7 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct bch_dev *ca,
bch2_io_error(ca, BCH_MEMBER_ERROR_checksum); bch2_io_error(ca, BCH_MEMBER_ERROR_checksum);
btree_err_on(csum_bad, btree_err_on(csum_bad,
-BCH_ERR_btree_node_read_err_want_retry, FSCK_CAN_FIX,
c, ca, b, i, NULL, c, ca, b, i, NULL,
bset_bad_csum, bset_bad_csum,
"%s", "%s",
@ -742,7 +684,7 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct bch_dev *ca,
bch2_bpos_to_text(&buf, b->data->max_key); bch2_bpos_to_text(&buf, b->data->max_key);
btree_err_on(b->data->keys.seq != bp->seq, btree_err_on(b->data->keys.seq != bp->seq,
-BCH_ERR_btree_node_read_err_must_retry, 0,
c, ca, b, NULL, NULL, c, ca, b, NULL, NULL,
btree_node_bad_seq, btree_node_bad_seq,
"got wrong btree node: got\n%s", "got wrong btree node: got\n%s",
@ -752,7 +694,7 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct bch_dev *ca,
buf.buf)); buf.buf));
} else { } else {
btree_err_on(!b->data->keys.seq, btree_err_on(!b->data->keys.seq,
-BCH_ERR_btree_node_read_err_must_retry, 0,
c, ca, b, NULL, NULL, c, ca, b, NULL, NULL,
btree_node_bad_seq, btree_node_bad_seq,
"bad btree header: seq 0\n%s", "bad btree header: seq 0\n%s",
@ -763,14 +705,14 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct bch_dev *ca,
btree_err_on(btree_node_type_is_extents(btree_node_type(b)) && btree_err_on(btree_node_type_is_extents(btree_node_type(b)) &&
!BTREE_NODE_NEW_EXTENT_OVERWRITE(b->data), !BTREE_NODE_NEW_EXTENT_OVERWRITE(b->data),
-BCH_ERR_btree_node_read_err_incompatible, 0,
c, NULL, b, NULL, NULL, c, ca, b, NULL, NULL,
btree_node_unsupported_version, btree_node_unsupported_version,
"btree node does not have NEW_EXTENT_OVERWRITE set"); "btree node does not have NEW_EXTENT_OVERWRITE set");
} else { } else {
sectors = vstruct_sectors(bne, c->block_bits); sectors = vstruct_sectors(bne, c->block_bits);
if (btree_err_on(b->written + sectors > (ptr_written ?: btree_sectors(c)), if (btree_err_on(b->written + sectors > (ptr_written ?: btree_sectors(c)),
-BCH_ERR_btree_node_read_err_fixable, FSCK_CAN_FIX,
c, ca, b, i, NULL, c, ca, b, i, NULL,
bset_past_end_of_btree_node, bset_past_end_of_btree_node,
"bset past end of btree node (offset %u len %u but written %zu)", "bset past end of btree node (offset %u len %u but written %zu)",
@ -783,7 +725,7 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct bch_dev *ca,
bch2_io_error(ca, BCH_MEMBER_ERROR_checksum); bch2_io_error(ca, BCH_MEMBER_ERROR_checksum);
btree_err_on(csum_bad, btree_err_on(csum_bad,
-BCH_ERR_btree_node_read_err_want_retry, FSCK_CAN_FIX,
c, ca, b, i, NULL, c, ca, b, i, NULL,
bset_bad_csum, bset_bad_csum,
"%s", "%s",
@ -808,7 +750,7 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct bch_dev *ca,
if (!b->written) if (!b->written)
btree_node_set_format(b, b->data->format); btree_node_set_format(b, b->data->format);
ret = bch2_validate_bset_keys(c, b, i, READ, failed, err_msg); ret = bch2_validate_bset_keys(c, ca, b, i, READ, failed, err_msg);
if (ret) if (ret)
goto fsck_err; goto fsck_err;
@ -819,14 +761,14 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct bch_dev *ca,
true); true);
btree_err_on(blacklisted && first, btree_err_on(blacklisted && first,
-BCH_ERR_btree_node_read_err_fixable, FSCK_CAN_FIX,
c, ca, b, i, NULL, c, ca, b, i, NULL,
bset_blacklisted_journal_seq, bset_blacklisted_journal_seq,
"first btree node btree/bset.has blacklisted journal seq (%llu)", "first btree node btree/bset.has blacklisted journal seq (%llu)",
le64_to_cpu(i->journal_seq)); le64_to_cpu(i->journal_seq));
btree_err_on(blacklisted && ptr_written, btree_err_on(blacklisted && ptr_written,
-BCH_ERR_btree_node_read_err_fixable, FSCK_CAN_FIX,
c, ca, b, i, NULL, c, ca, b, i, NULL,
first_bset_blacklisted_journal_seq, first_bset_blacklisted_journal_seq,
"found blacklisted bset (journal seq %llu) in btree node at offset %u-%u/%u", "found blacklisted bset (journal seq %llu) in btree node at offset %u-%u/%u",
@ -847,7 +789,7 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct bch_dev *ca,
if (ptr_written) { if (ptr_written) {
btree_err_on(b->written < ptr_written, btree_err_on(b->written < ptr_written,
-BCH_ERR_btree_node_read_err_want_retry, FSCK_CAN_FIX,
c, ca, b, NULL, NULL, c, ca, b, NULL, NULL,
btree_node_data_missing, btree_node_data_missing,
"btree node data missing: expected %u sectors, found %u", "btree node data missing: expected %u sectors, found %u",
@ -860,7 +802,7 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct bch_dev *ca,
!bch2_journal_seq_is_blacklisted(c, !bch2_journal_seq_is_blacklisted(c,
le64_to_cpu(bne->keys.journal_seq), le64_to_cpu(bne->keys.journal_seq),
true), true),
-BCH_ERR_btree_node_read_err_want_retry, FSCK_CAN_FIX,
c, ca, b, NULL, NULL, c, ca, b, NULL, NULL,
btree_node_bset_after_end, btree_node_bset_after_end,
"found bset signature after last bset"); "found bset signature after last bset");
@ -955,12 +897,29 @@ static void btree_node_read_work(struct work_struct *work)
bch2_btree_pos_to_text(&buf, c, b); bch2_btree_pos_to_text(&buf, c, b);
prt_newline(&buf); prt_newline(&buf);
goto start;
while (1) { while (1) {
ret = bch2_bkey_pick_read_device(c, if (rb->have_ioref)
bkey_i_to_s_c(&b->key), enumerated_ref_put(&ca->io_ref[READ], BCH_DEV_READ_REF_btree_node_read);
&failed, &rb->pick, -1); rb->have_ioref = false;
if (ret <= 0)
if (!bio->bi_status) {
memset(&bio->bi_iter, 0, sizeof(bio->bi_iter));
bio->bi_iter.bi_size = btree_buf_bytes(b);
if (bch2_btree_read_corrupt_device == rb->pick.ptr.dev ||
bch2_btree_read_corrupt_device < 0)
bch2_maybe_corrupt_bio(bio, bch2_btree_read_corrupt_ratio);
ret = bch2_btree_node_read_done(c, ca, b, &failed, &buf);
} else {
ret = __bch2_err_throw(c, -blk_status_to_bch_err(bio->bi_status));
bch2_mark_io_failure(&failed, &rb->pick, ret);
}
if (!ret ||
bch2_bkey_pick_read_device(c,
bkey_i_to_s_c(&b->key),
&failed, &rb->pick, -1) <= 0)
break; break;
ca = bch2_dev_get_ioref(c, rb->pick.ptr.dev, READ, BCH_DEV_READ_REF_btree_node_read); ca = bch2_dev_get_ioref(c, rb->pick.ptr.dev, READ, BCH_DEV_READ_REF_btree_node_read);
@ -979,29 +938,6 @@ static void btree_node_read_work(struct work_struct *work)
bch2_account_io_completion(ca, BCH_MEMBER_ERROR_read, bch2_account_io_completion(ca, BCH_MEMBER_ERROR_read,
rb->start_time, !bio->bi_status); rb->start_time, !bio->bi_status);
start:
if (rb->have_ioref)
enumerated_ref_put(&ca->io_ref[READ], BCH_DEV_READ_REF_btree_node_read);
rb->have_ioref = false;
if (bio->bi_status) {
bch2_mark_io_failure(&failed, &rb->pick,
__bch2_err_throw(c, -blk_status_to_bch_err(bio->bi_status)));
continue;
}
memset(&bio->bi_iter, 0, sizeof(bio->bi_iter));
bio->bi_iter.bi_size = btree_buf_bytes(b);
if (bch2_btree_read_corrupt_device == rb->pick.ptr.dev ||
bch2_btree_read_corrupt_device < 0)
bch2_maybe_corrupt_bio(bio, bch2_btree_read_corrupt_ratio);
ret = bch2_btree_node_read_done(c, ca, b, &failed, &buf);
if (ret != -BCH_ERR_btree_node_read_err_want_retry &&
ret != -BCH_ERR_btree_node_read_err_must_retry &&
!bch2_err_matches(ret, BCH_ERR_blockdev_io_error))
break;
} }
bch2_io_failures_to_text(&buf, c, &failed); bch2_io_failures_to_text(&buf, c, &failed);
@ -1019,7 +955,7 @@ start:
set_btree_node_read_error(b); set_btree_node_read_error(b);
bch2_btree_lost_data(c, &buf, b->c.btree_id); bch2_btree_lost_data(c, &buf, b->c.btree_id);
prt_printf(&buf, "ret %s", bch2_err_str(ret)); prt_printf(&buf, "error %s\n", bch2_err_str(ret));
} else if (failed.nr) { } else if (failed.nr) {
/* Separate ratelimit states for soft vs. hard errors */ /* Separate ratelimit states for soft vs. hard errors */
buf.suppress = !__bch2_ratelimit(c, &c->btree.read_errors_soft); buf.suppress = !__bch2_ratelimit(c, &c->btree.read_errors_soft);
@ -1028,19 +964,18 @@ start:
prt_printf(&buf, "retry success"); prt_printf(&buf, "retry success");
else else
prt_printf(&buf, "repair success"); prt_printf(&buf, "repair success");
if ((failed.nr || btree_node_need_rewrite(b)) &&
c->recovery.curr_pass != BCH_RECOVERY_PASS_scan_for_btree_nodes) {
prt_printf(&buf, " (rewriting node)");
bch2_btree_node_rewrite_async(c, b);
}
prt_newline(&buf);
} else { } else {
buf.suppress = true; buf.suppress = true;
} }
if ((failed.nr ||
btree_node_need_rewrite(b)) &&
!btree_node_read_error(b) &&
c->recovery.curr_pass != BCH_RECOVERY_PASS_scan_for_btree_nodes) {
prt_printf(&buf, " (rewriting node)");
bch2_btree_node_rewrite_async(c, b);
}
prt_newline(&buf);
if (!buf.suppress) if (!buf.suppress)
bch2_print_str(c, ret ? KERN_ERR : KERN_NOTICE, buf.buf); bch2_print_str(c, ret ? KERN_ERR : KERN_NOTICE, buf.buf);

View File

@ -76,8 +76,8 @@ static inline int bset_encrypt(struct bch_fs *c, struct bset *i, unsigned offset
void bch2_btree_node_drop_keys_outside_node(struct btree *); void bch2_btree_node_drop_keys_outside_node(struct btree *);
int bch2_validate_bset_keys(struct bch_fs *, struct btree *, int bch2_validate_bset_keys(struct bch_fs *, struct bch_dev *,
struct bset *, int, struct btree *, struct bset *, int,
struct bch_io_failures *, struct bch_io_failures *,
struct printbuf *); struct printbuf *);
int bch2_validate_bset(struct bch_fs *, struct bch_dev *, int bch2_validate_bset(struct bch_fs *, struct bch_dev *,

View File

@ -173,7 +173,7 @@ static void btree_node_write_work(struct work_struct *work)
bch2_devs_list_to_text(&msg.m, c, &d); bch2_devs_list_to_text(&msg.m, c, &d);
prt_newline(&msg.m); prt_newline(&msg.m);
} else { } else {
prt_printf(&msg.m, "%s\n", bch2_err_str(ret)); prt_printf(&msg.m, "error %s\n", bch2_err_str(ret));
bch2_fs_emergency_read_only2(c, &msg.m); bch2_fs_emergency_read_only2(c, &msg.m);
} }
} }
@ -241,7 +241,7 @@ static int validate_bset_for_write(struct bch_fs *c, struct btree *b,
return ret; return ret;
} }
ret = bch2_validate_bset_keys(c, b, i, WRITE, NULL, NULL) ?: ret = bch2_validate_bset_keys(c, NULL, b, i, WRITE, NULL, NULL) ?:
bch2_validate_bset(c, NULL, b, i, b->written, WRITE, NULL, NULL); bch2_validate_bset(c, NULL, b, i, b->written, WRITE, NULL, NULL);
if (ret) { if (ret) {
bch2_inconsistent_error(c); bch2_inconsistent_error(c);

View File

@ -738,7 +738,7 @@ static void bch2_rbio_retry(struct work_struct *work)
if (rbio->self_healing) if (rbio->self_healing)
prt_str(&msg.m, ", self healing"); prt_str(&msg.m, ", self healing");
} else } else
prt_str(&msg.m, bch2_err_str(ret)); prt_printf(&msg.m, "error %s", bch2_err_str(ret));
prt_newline(&msg.m); prt_newline(&msg.m);
if (!bkey_deleted(&sk.k->k)) { if (!bkey_deleted(&sk.k->k)) {

View File

@ -610,7 +610,7 @@ static void __bch2_write_index(struct bch_write_op *op)
bch2_devs_list_to_text(&msg.m, c, &d); bch2_devs_list_to_text(&msg.m, c, &d);
prt_newline(&msg.m); prt_newline(&msg.m);
} else { } else {
prt_printf(&msg.m, "all replicated writes failed\n"); prt_printf(&msg.m, "error %s\n", bch2_err_str(ret));
} }
if (ret) if (ret)

View File

@ -395,11 +395,6 @@
x(BCH_ERR_data_read, data_read_buffer_too_small) \ x(BCH_ERR_data_read, data_read_buffer_too_small) \
x(BCH_ERR_data_read, data_read_key_overwritten) \ x(BCH_ERR_data_read, data_read_key_overwritten) \
x(0, rbio_narrow_crcs_fail) \ x(0, rbio_narrow_crcs_fail) \
x(BCH_ERR_btree_node_read_err, btree_node_read_err_fixable) \
x(BCH_ERR_btree_node_read_err, btree_node_read_err_want_retry) \
x(BCH_ERR_btree_node_read_err, btree_node_read_err_must_retry) \
x(BCH_ERR_btree_node_read_err, btree_node_read_err_bad_node) \
x(BCH_ERR_btree_node_read_err, btree_node_read_err_incompatible) \
x(0, nopromote) \ x(0, nopromote) \
x(BCH_ERR_nopromote, nopromote_may_not) \ x(BCH_ERR_nopromote, nopromote_may_not) \
x(BCH_ERR_nopromote, nopromote_no_rewrites) \ x(BCH_ERR_nopromote, nopromote_no_rewrites) \

View File

@ -117,6 +117,19 @@ static unsigned loglevel_opt(struct bch_fs *c)
void bch2_print_str_loglevel(struct bch_fs *c, int loglevel, const char *str) void bch2_print_str_loglevel(struct bch_fs *c, int loglevel, const char *str)
{ {
unsigned len = strlen(str);
/*
* printbufs leave extra spaces from indent level after the last
* newline; strip them
*/
unsigned l = len;
while (l && str[l - 1] == ' ')
--l;
if (!l || str[l - 1] == '\n')
len = l;
if (!len)
return;
if (loglevel < 0) if (loglevel < 0)
loglevel = c->prev_loglevel; loglevel = c->prev_loglevel;
else else
@ -145,7 +158,7 @@ void bch2_print_str_loglevel(struct bch_fs *c, int loglevel, const char *str)
struct stdio_redirect *stdio = bch2_fs_stdio_redirect(c); struct stdio_redirect *stdio = bch2_fs_stdio_redirect(c);
if (unlikely(stdio)) { if (unlikely(stdio)) {
bch2_stdio_redirect_write(stdio, true, str, strlen(str)); bch2_stdio_redirect_write(stdio, true, str, len);
return; return;
} }
#endif #endif

View File

@ -249,12 +249,7 @@ static CLOSURE_CALLBACK(journal_write_done)
bch2_devs_list_to_text(&msg.m, c, &w->devs_written); bch2_devs_list_to_text(&msg.m, c, &w->devs_written);
prt_newline(&msg.m); prt_newline(&msg.m);
} else { } else {
if (err == -BCH_ERR_journal_write_err) prt_printf(&msg.m, "error %s\n", bch2_err_str(err));
prt_printf(&msg.m, "unable to write journal to sufficient devices\n");
else
prt_printf(&msg.m, "journal write error marking replicas: %s\n",
bch2_err_str(err));
bch2_fs_emergency_read_only2(c, &msg.m); bch2_fs_emergency_read_only2(c, &msg.m);
} }
} }

View File

@ -152,7 +152,7 @@ static void __printbuf_do_indent(struct printbuf *out, unsigned pos)
static inline void printbuf_do_indent(struct printbuf *out, unsigned pos) static inline void printbuf_do_indent(struct printbuf *out, unsigned pos)
{ {
if (out->has_indent_or_tabstops && !out->suppress_indent_tabstop_handling) if (out->has_indent_or_tabstops)
__printbuf_do_indent(out, pos); __printbuf_do_indent(out, pos);
} }

View File

@ -91,7 +91,6 @@ struct printbuf {
enum printbuf_si si_units:1; enum printbuf_si si_units:1;
bool human_readable_units:1; bool human_readable_units:1;
bool has_indent_or_tabstops:1; bool has_indent_or_tabstops:1;
bool suppress_indent_tabstop_handling:1;
u8 nr_tabstops; u8 nr_tabstops;
/* /*

View File

@ -402,7 +402,7 @@ static long bch2_ioctl_subvolume_destroy(struct bch_fs *c, struct file *filp,
CLASS(printbuf, err)(); CLASS(printbuf, err)();
long ret = __bch2_ioctl_subvolume_destroy(c, filp, arg_v2, &err); long ret = __bch2_ioctl_subvolume_destroy(c, filp, arg_v2, &err);
if (ret) if (ret && err.buf)
bch_err_msg(c, ret, "%s", err.buf); bch_err_msg(c, ret, "%s", err.buf);
return ret; return ret;
} }