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

bcachefs: Finish bch2_account_io_completion() conversions



More prep work for automatically kicking devices out after too many IO
errors.

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 3526bca3
Loading
Loading
Loading
Loading
+22 −16
Original line number Diff line number Diff line
@@ -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);
@@ -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)
@@ -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);
}
@@ -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);
+9 −3
Original line number Diff line number Diff line
@@ -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;
+9 −6
Original line number Diff line number Diff line
@@ -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;
};

@@ -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) {
@@ -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;
+1 −0
Original line number Diff line number Diff line
@@ -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)		\
+9 −24
Original line number Diff line number Diff line
@@ -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)
@@ -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