Loading fs/bcachefs/btree_io.c +22 −16 Original line number Diff line number Diff line Loading @@ -1329,6 +1329,7 @@ static void btree_node_read_work(struct work_struct *work) bch_info(c, "retrying read"); ca = bch2_dev_get_ioref(c, rb->pick.ptr.dev, READ); rb->have_ioref = ca != NULL; rb->start_time = local_clock(); bio_reset(bio, NULL, REQ_OP_READ|REQ_SYNC|REQ_META); bio->bi_iter.bi_sector = rb->pick.ptr.offset; bio->bi_iter.bi_size = btree_buf_bytes(b); Loading @@ -1339,10 +1340,15 @@ static void btree_node_read_work(struct work_struct *work) } else { bio->bi_status = BLK_STS_REMOVED; } bch2_account_io_completion(ca, BCH_MEMBER_ERROR_read, rb->start_time, !bio->bi_status); start: printbuf_reset(&buf); bch2_btree_pos_to_text(&buf, c, b); bch2_dev_io_err_on(ca && bio->bi_status, ca, BCH_MEMBER_ERROR_read, if (ca && bio->bi_status) bch_err_dev_ratelimited(ca, "btree read error %s for %s", bch2_blk_status_to_str(bio->bi_status), buf.buf); if (rb->have_ioref) Loading Loading @@ -1401,12 +1407,11 @@ static void btree_node_read_endio(struct bio *bio) struct btree_read_bio *rb = container_of(bio, struct btree_read_bio, bio); struct bch_fs *c = rb->c; struct bch_dev *ca = rb->have_ioref ? bch2_dev_have_ref(c, rb->pick.ptr.dev) : NULL; if (rb->have_ioref) { struct bch_dev *ca = bch2_dev_have_ref(c, rb->pick.ptr.dev); bch2_latency_acct(ca, rb->start_time, READ); } bch2_account_io_completion(ca, BCH_MEMBER_ERROR_read, rb->start_time, !bio->bi_status); queue_work(c->btree_read_complete_wq, &rb->work); } Loading Loading @@ -2126,16 +2131,17 @@ static void btree_node_write_endio(struct bio *bio) struct bch_fs *c = wbio->c; struct btree *b = wbio->bio.bi_private; struct bch_dev *ca = wbio->have_ioref ? bch2_dev_have_ref(c, wbio->dev) : NULL; unsigned long flags; if (wbio->have_ioref) bch2_latency_acct(ca, wbio->submit_time, WRITE); bch2_account_io_completion(ca, BCH_MEMBER_ERROR_write, wbio->submit_time, !bio->bi_status); if (!ca || bch2_dev_io_err_on(bio->bi_status, ca, BCH_MEMBER_ERROR_write, if (ca && bio->bi_status) bch_err_dev_ratelimited(ca, "btree write error: %s", bch2_blk_status_to_str(bio->bi_status)) || bch2_meta_write_fault("btree")) { bch2_blk_status_to_str(bio->bi_status)); if (bio->bi_status) { unsigned long flags; spin_lock_irqsave(&c->btree_write_error_lock, flags); bch2_dev_list_add_dev(&orig->failed, wbio->dev); spin_unlock_irqrestore(&c->btree_write_error_lock, flags); Loading fs/bcachefs/btree_node_scan.c +9 −3 Original line number Diff line number Diff line Loading @@ -166,11 +166,17 @@ static void try_read_btree_node(struct find_btree_nodes *f, struct bch_dev *ca, bio->bi_iter.bi_sector = offset; bch2_bio_map(bio, bn, PAGE_SIZE); u64 submit_time = local_clock(); submit_bio_wait(bio); if (bch2_dev_io_err_on(bio->bi_status, ca, BCH_MEMBER_ERROR_read, bch2_account_io_completion(ca, BCH_MEMBER_ERROR_read, submit_time, !bio->bi_status); if (bio->bi_status) { bch_err_dev_ratelimited(ca, "IO error in try_read_btree_node() at %llu: %s", offset, bch2_blk_status_to_str(bio->bi_status))) offset, bch2_blk_status_to_str(bio->bi_status)); return; } if (le64_to_cpu(bn->magic) != bset_magic(c)) return; Loading fs/bcachefs/ec.c +9 −6 Original line number Diff line number Diff line Loading @@ -105,6 +105,7 @@ struct ec_bio { struct bch_dev *ca; struct ec_stripe_buf *buf; size_t idx; u64 submit_time; struct bio bio; }; Loading Loading @@ -748,14 +749,15 @@ static void ec_block_endio(struct bio *bio) struct bch_dev *ca = ec_bio->ca; struct closure *cl = bio->bi_private; if (bch2_dev_io_err_on(bio->bi_status, ca, bio_data_dir(bio) ? BCH_MEMBER_ERROR_write : BCH_MEMBER_ERROR_read, "erasure coding %s error: %s", bch2_account_io_completion(ca, bio_data_dir(bio), ec_bio->submit_time, !bio->bi_status); if (bio->bi_status) { bch_err_dev_ratelimited(ca, "erasure coding %s error: %s", str_write_read(bio_data_dir(bio)), bch2_blk_status_to_str(bio->bi_status))) bch2_blk_status_to_str(bio->bi_status)); clear_bit(ec_bio->idx, ec_bio->buf->valid); } int stale = dev_ptr_stale(ca, ptr); if (stale) { Loading Loading @@ -818,6 +820,7 @@ static void ec_block_io(struct bch_fs *c, struct ec_stripe_buf *buf, ec_bio->ca = ca; ec_bio->buf = buf; ec_bio->idx = idx; ec_bio->submit_time = local_clock(); ec_bio->bio.bi_iter.bi_sector = ptr->offset + buf->offset + (offset >> 9); ec_bio->bio.bi_end_io = ec_block_endio; Loading fs/bcachefs/errcode.h +1 −0 Original line number Diff line number Diff line Loading @@ -279,6 +279,7 @@ x(EIO, no_encryption_key) \ x(EIO, insufficient_journal_devices) \ x(EIO, device_offline) \ x(EIO, EIO_fault_injected) \ 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) \ Loading fs/bcachefs/error.h +9 −24 Original line number Diff line number Diff line Loading @@ -222,6 +222,14 @@ void bch2_latency_acct(struct bch_dev *, u64, int); static inline void bch2_latency_acct(struct bch_dev *ca, u64 submit_time, int rw) {} #endif static inline void bch2_account_io_success_fail(struct bch_dev *ca, enum bch_member_error_type type, bool success) { if (!success) bch2_io_error(ca, type); } static inline void bch2_account_io_completion(struct bch_dev *ca, enum bch_member_error_type type, u64 submit_time, bool success) Loading @@ -232,32 +240,9 @@ static inline void bch2_account_io_completion(struct bch_dev *ca, if (type != BCH_MEMBER_ERROR_checksum) bch2_latency_acct(ca, submit_time, type); if (!success) bch2_io_error(ca, type); bch2_account_io_success_fail(ca, type, success); } #define bch2_dev_io_err_on(cond, ca, _type, ...) \ ({ \ bool _ret = (cond); \ \ if (_ret) { \ bch_err_dev_ratelimited(ca, __VA_ARGS__); \ bch2_io_error(ca, _type); \ } \ _ret; \ }) #define bch2_dev_inum_io_err_on(cond, ca, _type, ...) \ ({ \ bool _ret = (cond); \ \ if (_ret) { \ bch_err_inum_offset_ratelimited(ca, __VA_ARGS__); \ bch2_io_error(ca, _type); \ } \ _ret; \ }) int bch2_inum_offset_err_msg_trans(struct btree_trans *, struct printbuf *, subvol_inum, u64); void bch2_inum_offset_err_msg(struct bch_fs *, struct printbuf *, subvol_inum, u64); Loading Loading
fs/bcachefs/btree_io.c +22 −16 Original line number Diff line number Diff line Loading @@ -1329,6 +1329,7 @@ static void btree_node_read_work(struct work_struct *work) bch_info(c, "retrying read"); ca = bch2_dev_get_ioref(c, rb->pick.ptr.dev, READ); rb->have_ioref = ca != NULL; rb->start_time = local_clock(); bio_reset(bio, NULL, REQ_OP_READ|REQ_SYNC|REQ_META); bio->bi_iter.bi_sector = rb->pick.ptr.offset; bio->bi_iter.bi_size = btree_buf_bytes(b); Loading @@ -1339,10 +1340,15 @@ static void btree_node_read_work(struct work_struct *work) } else { bio->bi_status = BLK_STS_REMOVED; } bch2_account_io_completion(ca, BCH_MEMBER_ERROR_read, rb->start_time, !bio->bi_status); start: printbuf_reset(&buf); bch2_btree_pos_to_text(&buf, c, b); bch2_dev_io_err_on(ca && bio->bi_status, ca, BCH_MEMBER_ERROR_read, if (ca && bio->bi_status) bch_err_dev_ratelimited(ca, "btree read error %s for %s", bch2_blk_status_to_str(bio->bi_status), buf.buf); if (rb->have_ioref) Loading Loading @@ -1401,12 +1407,11 @@ static void btree_node_read_endio(struct bio *bio) struct btree_read_bio *rb = container_of(bio, struct btree_read_bio, bio); struct bch_fs *c = rb->c; struct bch_dev *ca = rb->have_ioref ? bch2_dev_have_ref(c, rb->pick.ptr.dev) : NULL; if (rb->have_ioref) { struct bch_dev *ca = bch2_dev_have_ref(c, rb->pick.ptr.dev); bch2_latency_acct(ca, rb->start_time, READ); } bch2_account_io_completion(ca, BCH_MEMBER_ERROR_read, rb->start_time, !bio->bi_status); queue_work(c->btree_read_complete_wq, &rb->work); } Loading Loading @@ -2126,16 +2131,17 @@ static void btree_node_write_endio(struct bio *bio) struct bch_fs *c = wbio->c; struct btree *b = wbio->bio.bi_private; struct bch_dev *ca = wbio->have_ioref ? bch2_dev_have_ref(c, wbio->dev) : NULL; unsigned long flags; if (wbio->have_ioref) bch2_latency_acct(ca, wbio->submit_time, WRITE); bch2_account_io_completion(ca, BCH_MEMBER_ERROR_write, wbio->submit_time, !bio->bi_status); if (!ca || bch2_dev_io_err_on(bio->bi_status, ca, BCH_MEMBER_ERROR_write, if (ca && bio->bi_status) bch_err_dev_ratelimited(ca, "btree write error: %s", bch2_blk_status_to_str(bio->bi_status)) || bch2_meta_write_fault("btree")) { bch2_blk_status_to_str(bio->bi_status)); if (bio->bi_status) { unsigned long flags; spin_lock_irqsave(&c->btree_write_error_lock, flags); bch2_dev_list_add_dev(&orig->failed, wbio->dev); spin_unlock_irqrestore(&c->btree_write_error_lock, flags); Loading
fs/bcachefs/btree_node_scan.c +9 −3 Original line number Diff line number Diff line Loading @@ -166,11 +166,17 @@ static void try_read_btree_node(struct find_btree_nodes *f, struct bch_dev *ca, bio->bi_iter.bi_sector = offset; bch2_bio_map(bio, bn, PAGE_SIZE); u64 submit_time = local_clock(); submit_bio_wait(bio); if (bch2_dev_io_err_on(bio->bi_status, ca, BCH_MEMBER_ERROR_read, bch2_account_io_completion(ca, BCH_MEMBER_ERROR_read, submit_time, !bio->bi_status); if (bio->bi_status) { bch_err_dev_ratelimited(ca, "IO error in try_read_btree_node() at %llu: %s", offset, bch2_blk_status_to_str(bio->bi_status))) offset, bch2_blk_status_to_str(bio->bi_status)); return; } if (le64_to_cpu(bn->magic) != bset_magic(c)) return; Loading
fs/bcachefs/ec.c +9 −6 Original line number Diff line number Diff line Loading @@ -105,6 +105,7 @@ struct ec_bio { struct bch_dev *ca; struct ec_stripe_buf *buf; size_t idx; u64 submit_time; struct bio bio; }; Loading Loading @@ -748,14 +749,15 @@ static void ec_block_endio(struct bio *bio) struct bch_dev *ca = ec_bio->ca; struct closure *cl = bio->bi_private; if (bch2_dev_io_err_on(bio->bi_status, ca, bio_data_dir(bio) ? BCH_MEMBER_ERROR_write : BCH_MEMBER_ERROR_read, "erasure coding %s error: %s", bch2_account_io_completion(ca, bio_data_dir(bio), ec_bio->submit_time, !bio->bi_status); if (bio->bi_status) { bch_err_dev_ratelimited(ca, "erasure coding %s error: %s", str_write_read(bio_data_dir(bio)), bch2_blk_status_to_str(bio->bi_status))) bch2_blk_status_to_str(bio->bi_status)); clear_bit(ec_bio->idx, ec_bio->buf->valid); } int stale = dev_ptr_stale(ca, ptr); if (stale) { Loading Loading @@ -818,6 +820,7 @@ static void ec_block_io(struct bch_fs *c, struct ec_stripe_buf *buf, ec_bio->ca = ca; ec_bio->buf = buf; ec_bio->idx = idx; ec_bio->submit_time = local_clock(); ec_bio->bio.bi_iter.bi_sector = ptr->offset + buf->offset + (offset >> 9); ec_bio->bio.bi_end_io = ec_block_endio; Loading
fs/bcachefs/errcode.h +1 −0 Original line number Diff line number Diff line Loading @@ -279,6 +279,7 @@ x(EIO, no_encryption_key) \ x(EIO, insufficient_journal_devices) \ x(EIO, device_offline) \ x(EIO, EIO_fault_injected) \ 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) \ Loading
fs/bcachefs/error.h +9 −24 Original line number Diff line number Diff line Loading @@ -222,6 +222,14 @@ void bch2_latency_acct(struct bch_dev *, u64, int); static inline void bch2_latency_acct(struct bch_dev *ca, u64 submit_time, int rw) {} #endif static inline void bch2_account_io_success_fail(struct bch_dev *ca, enum bch_member_error_type type, bool success) { if (!success) bch2_io_error(ca, type); } static inline void bch2_account_io_completion(struct bch_dev *ca, enum bch_member_error_type type, u64 submit_time, bool success) Loading @@ -232,32 +240,9 @@ static inline void bch2_account_io_completion(struct bch_dev *ca, if (type != BCH_MEMBER_ERROR_checksum) bch2_latency_acct(ca, submit_time, type); if (!success) bch2_io_error(ca, type); bch2_account_io_success_fail(ca, type, success); } #define bch2_dev_io_err_on(cond, ca, _type, ...) \ ({ \ bool _ret = (cond); \ \ if (_ret) { \ bch_err_dev_ratelimited(ca, __VA_ARGS__); \ bch2_io_error(ca, _type); \ } \ _ret; \ }) #define bch2_dev_inum_io_err_on(cond, ca, _type, ...) \ ({ \ bool _ret = (cond); \ \ if (_ret) { \ bch_err_inum_offset_ratelimited(ca, __VA_ARGS__); \ bch2_io_error(ca, _type); \ } \ _ret; \ }) int bch2_inum_offset_err_msg_trans(struct btree_trans *, struct printbuf *, subvol_inum, u64); void bch2_inum_offset_err_msg(struct bch_fs *, struct printbuf *, subvol_inum, u64); Loading