diff options
-rw-r--r-- | fs/bcachefs/errcode.h | 9 | ||||
-rw-r--r-- | fs/bcachefs/io_read.c | 38 | ||||
-rw-r--r-- | fs/bcachefs/trace.h | 19 |
3 files changed, 48 insertions, 18 deletions
diff --git a/fs/bcachefs/errcode.h b/fs/bcachefs/errcode.h index 379d9d7ed333..56b6ce278648 100644 --- a/fs/bcachefs/errcode.h +++ b/fs/bcachefs/errcode.h @@ -218,7 +218,14 @@ 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(BCH_ERR_btree_node_read_err, btree_node_read_err_incompatible) \ + x(0, nopromote) \ + x(BCH_ERR_nopromote, nopromote_may_not) \ + x(BCH_ERR_nopromote, nopromote_already_promoted) \ + x(BCH_ERR_nopromote, nopromote_unwritten) \ + x(BCH_ERR_nopromote, nopromote_congested) \ + x(BCH_ERR_nopromote, nopromote_in_flight) \ + x(BCH_ERR_nopromote, nopromote_enomem) enum bch_errcode { BCH_ERR_START = 2048, diff --git a/fs/bcachefs/io_read.c b/fs/bcachefs/io_read.c index cd62bf730396..5ff430e1e244 100644 --- a/fs/bcachefs/io_read.c +++ b/fs/bcachefs/io_read.c @@ -87,33 +87,30 @@ static const struct rhashtable_params bch_promote_params = { .key_len = sizeof(struct bpos), }; -static inline bool should_promote(struct bch_fs *c, struct bkey_s_c k, +static inline int should_promote(struct bch_fs *c, struct bkey_s_c k, struct bpos pos, struct bch_io_opts opts, unsigned flags) { - if (!(flags & BCH_READ_MAY_PROMOTE)) - return false; + BUG_ON(!opts.promote_target); - if (!opts.promote_target) - return false; + if (!(flags & BCH_READ_MAY_PROMOTE)) + return -BCH_ERR_nopromote_may_not; if (bch2_bkey_has_target(c, k, opts.promote_target)) - return false; + return -BCH_ERR_nopromote_already_promoted; if (bkey_extent_is_unwritten(k)) - return false; + return -BCH_ERR_nopromote_unwritten; - if (bch2_target_congested(c, opts.promote_target)) { - /* XXX trace this */ - return false; - } + if (bch2_target_congested(c, opts.promote_target)) + return -BCH_ERR_nopromote_congested; if (rhashtable_lookup_fast(&c->promote_table, &pos, bch_promote_params)) - return false; + return -BCH_ERR_nopromote_in_flight; - return true; + return 0; } static void promote_free(struct bch_fs *c, struct promote_op *op) @@ -264,21 +261,28 @@ static struct promote_op *promote_alloc(struct btree_trans *trans, ? bkey_start_pos(k.k) : POS(k.k->p.inode, iter.bi_sector); struct promote_op *promote; + int ret; - if (!should_promote(c, k, pos, opts, flags)) - return NULL; + ret = should_promote(c, k, pos, opts, flags); + if (ret) + goto nopromote; promote = __promote_alloc(trans, k.k->type == KEY_TYPE_reflink_v ? BTREE_ID_reflink : BTREE_ID_extents, k, pos, pick, opts, sectors, rbio); - if (!promote) - return NULL; + if (!promote) { + ret = -BCH_ERR_nopromote_enomem; + goto nopromote; + } *bounce = true; *read_full = promote_full; return promote; +nopromote: + trace_read_nopromote(c, ret); + return NULL; } /* Read */ diff --git a/fs/bcachefs/trace.h b/fs/bcachefs/trace.h index 97fe774237d0..19264492151b 100644 --- a/fs/bcachefs/trace.h +++ b/fs/bcachefs/trace.h @@ -137,6 +137,25 @@ DEFINE_EVENT(bio, read_promote, TP_ARGS(bio) ); +TRACE_EVENT(read_nopromote, + TP_PROTO(struct bch_fs *c, int ret), + TP_ARGS(c, ret), + + TP_STRUCT__entry( + __field(dev_t, dev ) + __array(char, ret, 32 ) + ), + + TP_fast_assign( + __entry->dev = c->dev; + strscpy(__entry->ret, bch2_err_str(ret), sizeof(__entry->ret)); + ), + + TP_printk("%d,%d ret %s", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ret) +); + DEFINE_EVENT(bio, read_bounce, TP_PROTO(struct bio *bio), TP_ARGS(bio) |