Loading fs/bcachefs/bcachefs.h +1 −0 Original line number Diff line number Diff line Loading @@ -797,6 +797,7 @@ struct bch_fs { u64 features; u64 compat; unsigned long errors_silent[BITS_TO_LONGS(BCH_SB_ERR_MAX)]; u64 btrees_lost_data; } sb; Loading fs/bcachefs/bcachefs_format.h +1 −0 Original line number Diff line number Diff line Loading @@ -818,6 +818,7 @@ struct bch_sb_field_ext { struct bch_sb_field field; __le64 recovery_passes_required[2]; __le64 errors_silent[8]; __le64 btrees_lost_data; }; struct bch_sb_field_downgrade_entry { Loading fs/bcachefs/btree_io.c +9 −4 Original line number Diff line number Diff line Loading @@ -1264,10 +1264,12 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct bch_dev *ca, return retry_read; fsck_err: if (ret == -BCH_ERR_btree_node_read_err_want_retry || ret == -BCH_ERR_btree_node_read_err_must_retry) ret == -BCH_ERR_btree_node_read_err_must_retry) { retry_read = 1; else } else { set_btree_node_read_error(b); bch2_btree_lost_data(c, b->c.btree_id); } goto out; } Loading Loading @@ -1328,6 +1330,7 @@ static void btree_node_read_work(struct work_struct *work) if (!can_retry) { set_btree_node_read_error(b); bch2_btree_lost_data(c, b->c.btree_id); break; } } Loading Loading @@ -1527,9 +1530,10 @@ static CLOSURE_CALLBACK(btree_node_read_all_replicas_done) ret = -1; } if (ret) if (ret) { set_btree_node_read_error(b); else if (*saw_error) bch2_btree_lost_data(c, b->c.btree_id); } else if (*saw_error) bch2_btree_node_rewrite_async(c, b); for (i = 0; i < ra->nr; i++) { Loading Loading @@ -1665,6 +1669,7 @@ void bch2_btree_node_read(struct btree_trans *trans, struct btree *b, bch2_fatal_error(c); set_btree_node_read_error(b); bch2_btree_lost_data(c, b->c.btree_id); clear_btree_node_read_in_flight(b); wake_up_bit(&b->flags, BTREE_NODE_read_in_flight); printbuf_exit(&buf); Loading fs/bcachefs/recovery.c +23 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,20 @@ #define QSTR(n) { { { .len = strlen(n) } }, .name = n } void bch2_btree_lost_data(struct bch_fs *c, enum btree_id btree) { u64 b = BIT_ULL(btree); if (!(c->sb.btrees_lost_data & b)) { bch_err(c, "flagging btree %s lost data", bch2_btree_id_str(btree)); mutex_lock(&c->sb_lock); bch2_sb_field_get(c->disk_sb.sb, ext)->btrees_lost_data |= cpu_to_le64(b); bch2_write_super(c); mutex_unlock(&c->sb_lock); } } static bool btree_id_is_alloc(enum btree_id id) { switch (id) { Loading Loading @@ -470,6 +484,7 @@ static int read_btree_roots(struct bch_fs *c) } ret = 0; bch2_btree_lost_data(c, i); } } Loading Loading @@ -848,6 +863,14 @@ int bch2_fs_recovery(struct bch_fs *c) write_sb = true; } if (c->opts.fsck && !test_bit(BCH_FS_error, &c->flags) && c->recovery_pass_done == BCH_RECOVERY_PASS_NR - 1 && ext->btrees_lost_data) { ext->btrees_lost_data = 0; write_sb = true; } if (c->opts.fsck && !test_bit(BCH_FS_error, &c->flags) && !test_bit(BCH_FS_errors_not_fixed, &c->flags)) { Loading fs/bcachefs/recovery.h +2 −0 Original line number Diff line number Diff line Loading @@ -2,6 +2,8 @@ #ifndef _BCACHEFS_RECOVERY_H #define _BCACHEFS_RECOVERY_H void bch2_btree_lost_data(struct bch_fs *, enum btree_id); int bch2_journal_replay(struct bch_fs *); int bch2_fs_recovery(struct bch_fs *); Loading Loading
fs/bcachefs/bcachefs.h +1 −0 Original line number Diff line number Diff line Loading @@ -797,6 +797,7 @@ struct bch_fs { u64 features; u64 compat; unsigned long errors_silent[BITS_TO_LONGS(BCH_SB_ERR_MAX)]; u64 btrees_lost_data; } sb; Loading
fs/bcachefs/bcachefs_format.h +1 −0 Original line number Diff line number Diff line Loading @@ -818,6 +818,7 @@ struct bch_sb_field_ext { struct bch_sb_field field; __le64 recovery_passes_required[2]; __le64 errors_silent[8]; __le64 btrees_lost_data; }; struct bch_sb_field_downgrade_entry { Loading
fs/bcachefs/btree_io.c +9 −4 Original line number Diff line number Diff line Loading @@ -1264,10 +1264,12 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct bch_dev *ca, return retry_read; fsck_err: if (ret == -BCH_ERR_btree_node_read_err_want_retry || ret == -BCH_ERR_btree_node_read_err_must_retry) ret == -BCH_ERR_btree_node_read_err_must_retry) { retry_read = 1; else } else { set_btree_node_read_error(b); bch2_btree_lost_data(c, b->c.btree_id); } goto out; } Loading Loading @@ -1328,6 +1330,7 @@ static void btree_node_read_work(struct work_struct *work) if (!can_retry) { set_btree_node_read_error(b); bch2_btree_lost_data(c, b->c.btree_id); break; } } Loading Loading @@ -1527,9 +1530,10 @@ static CLOSURE_CALLBACK(btree_node_read_all_replicas_done) ret = -1; } if (ret) if (ret) { set_btree_node_read_error(b); else if (*saw_error) bch2_btree_lost_data(c, b->c.btree_id); } else if (*saw_error) bch2_btree_node_rewrite_async(c, b); for (i = 0; i < ra->nr; i++) { Loading Loading @@ -1665,6 +1669,7 @@ void bch2_btree_node_read(struct btree_trans *trans, struct btree *b, bch2_fatal_error(c); set_btree_node_read_error(b); bch2_btree_lost_data(c, b->c.btree_id); clear_btree_node_read_in_flight(b); wake_up_bit(&b->flags, BTREE_NODE_read_in_flight); printbuf_exit(&buf); Loading
fs/bcachefs/recovery.c +23 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,20 @@ #define QSTR(n) { { { .len = strlen(n) } }, .name = n } void bch2_btree_lost_data(struct bch_fs *c, enum btree_id btree) { u64 b = BIT_ULL(btree); if (!(c->sb.btrees_lost_data & b)) { bch_err(c, "flagging btree %s lost data", bch2_btree_id_str(btree)); mutex_lock(&c->sb_lock); bch2_sb_field_get(c->disk_sb.sb, ext)->btrees_lost_data |= cpu_to_le64(b); bch2_write_super(c); mutex_unlock(&c->sb_lock); } } static bool btree_id_is_alloc(enum btree_id id) { switch (id) { Loading Loading @@ -470,6 +484,7 @@ static int read_btree_roots(struct bch_fs *c) } ret = 0; bch2_btree_lost_data(c, i); } } Loading Loading @@ -848,6 +863,14 @@ int bch2_fs_recovery(struct bch_fs *c) write_sb = true; } if (c->opts.fsck && !test_bit(BCH_FS_error, &c->flags) && c->recovery_pass_done == BCH_RECOVERY_PASS_NR - 1 && ext->btrees_lost_data) { ext->btrees_lost_data = 0; write_sb = true; } if (c->opts.fsck && !test_bit(BCH_FS_error, &c->flags) && !test_bit(BCH_FS_errors_not_fixed, &c->flags)) { Loading
fs/bcachefs/recovery.h +2 −0 Original line number Diff line number Diff line Loading @@ -2,6 +2,8 @@ #ifndef _BCACHEFS_RECOVERY_H #define _BCACHEFS_RECOVERY_H void bch2_btree_lost_data(struct bch_fs *, enum btree_id); int bch2_journal_replay(struct bch_fs *); int bch2_fs_recovery(struct bch_fs *); Loading