summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.bcachefs_revision2
-rw-r--r--libbcachefs/btree_update_interior.c34
-rw-r--r--libbcachefs/btree_update_interior.h12
-rw-r--r--libbcachefs/data_update.c13
-rw-r--r--libbcachefs/extents.c12
-rw-r--r--libbcachefs/extents.h1
-rw-r--r--libbcachefs/io_read.c11
-rw-r--r--libbcachefs/journal.c13
-rw-r--r--libbcachefs/journal_reclaim.c6
-rw-r--r--libbcachefs/recovery_passes.c2
-rw-r--r--libbcachefs/sb-counters_format.h1
-rw-r--r--libbcachefs/trace.h25
12 files changed, 91 insertions, 41 deletions
diff --git a/.bcachefs_revision b/.bcachefs_revision
index ff4da657..62bf4007 100644
--- a/.bcachefs_revision
+++ b/.bcachefs_revision
@@ -1 +1 @@
-b47c5ba55d592855bdfc77883f41207bdad56248
+4e917bf40142dc75c838d42f787189b06c23ffa3
diff --git a/libbcachefs/btree_update_interior.c b/libbcachefs/btree_update_interior.c
index 8e3d3db2..ebdb4d2f 100644
--- a/libbcachefs/btree_update_interior.c
+++ b/libbcachefs/btree_update_interior.c
@@ -285,7 +285,7 @@ static struct btree *__bch2_btree_node_alloc(struct btree_trans *trans,
struct closure *cl,
bool interior_node,
unsigned target,
- unsigned flags)
+ enum bch_trans_commit_flags flags)
{
struct bch_fs *c = trans->c;
struct write_point *wp;
@@ -305,13 +305,18 @@ static struct btree *__bch2_btree_node_alloc(struct btree_trans *trans,
mutex_lock(&c->btree_reserve_cache_lock);
if (c->btree_reserve_cache_nr > nr_reserve) {
- struct btree_alloc *a =
- &c->btree_reserve_cache[--c->btree_reserve_cache_nr];
-
- bkey_copy(&b->key, &a->k);
- b->ob = a->ob;
- mutex_unlock(&c->btree_reserve_cache_lock);
- goto out;
+ for (struct btree_alloc *a = c->btree_reserve_cache;
+ a < c->btree_reserve_cache + c->btree_reserve_cache_nr;
+ a++) {
+ if (target && !bch2_bkey_in_target(c, bkey_i_to_s_c(&a->k), target))
+ continue;
+
+ bkey_copy(&b->key, &a->k);
+ b->ob = a->ob;
+ *a = c->btree_reserve_cache[--c->btree_reserve_cache_nr];
+ mutex_unlock(&c->btree_reserve_cache_lock);
+ goto out;
+ }
}
mutex_unlock(&c->btree_reserve_cache_lock);
retry:
@@ -1139,7 +1144,8 @@ static const char * const btree_node_reawrite_reason_strs[] = {
static struct btree_update *
bch2_btree_update_start(struct btree_trans *trans, struct btree_path *path,
unsigned level_start, bool split,
- unsigned target, unsigned flags)
+ unsigned target,
+ enum bch_trans_commit_flags flags)
{
struct bch_fs *c = trans->c;
struct btree_update *as;
@@ -2222,7 +2228,7 @@ int bch2_btree_node_rewrite(struct btree_trans *trans,
struct btree_iter *iter,
struct btree *b,
unsigned target,
- unsigned flags)
+ enum bch_trans_commit_flags flags)
{
struct bch_fs *c = trans->c;
struct btree *n, *parent;
@@ -2287,7 +2293,8 @@ err:
int bch2_btree_node_rewrite_key(struct btree_trans *trans,
enum btree_id btree, unsigned level,
- struct bkey_i *k, unsigned flags)
+ struct bkey_i *k,
+ enum bch_trans_commit_flags flags)
{
struct btree_iter iter;
bch2_trans_node_iter_init(trans, &iter,
@@ -2311,7 +2318,7 @@ int bch2_btree_node_rewrite_pos(struct btree_trans *trans,
enum btree_id btree, unsigned level,
struct bpos pos,
unsigned target,
- unsigned flags)
+ enum bch_trans_commit_flags flags)
{
BUG_ON(!level);
@@ -2330,7 +2337,8 @@ err:
}
int bch2_btree_node_rewrite_key_get_iter(struct btree_trans *trans,
- struct btree *b, unsigned flags)
+ struct btree *b,
+ enum bch_trans_commit_flags flags)
{
struct btree_iter iter;
int ret = get_iter_to_node(trans, &iter, b);
diff --git a/libbcachefs/btree_update_interior.h b/libbcachefs/btree_update_interior.h
index ac04e45a..6ed049f1 100644
--- a/libbcachefs/btree_update_interior.h
+++ b/libbcachefs/btree_update_interior.h
@@ -175,15 +175,19 @@ static inline int bch2_foreground_maybe_merge(struct btree_trans *trans,
}
int bch2_btree_node_rewrite(struct btree_trans *, struct btree_iter *,
- struct btree *, unsigned, unsigned);
+ struct btree *, unsigned,
+ enum bch_trans_commit_flags);
int bch2_btree_node_rewrite_key(struct btree_trans *,
enum btree_id, unsigned,
- struct bkey_i *, unsigned);
+ struct bkey_i *,
+ enum bch_trans_commit_flags);
int bch2_btree_node_rewrite_pos(struct btree_trans *,
enum btree_id, unsigned,
- struct bpos, unsigned, unsigned);
+ struct bpos, unsigned,
+ enum bch_trans_commit_flags);
int bch2_btree_node_rewrite_key_get_iter(struct btree_trans *,
- struct btree *, unsigned);
+ struct btree *,
+ enum bch_trans_commit_flags);
void bch2_btree_node_rewrite_async(struct bch_fs *, struct btree *);
diff --git a/libbcachefs/data_update.c b/libbcachefs/data_update.c
index e848e210..3968f3be 100644
--- a/libbcachefs/data_update.c
+++ b/libbcachefs/data_update.c
@@ -783,6 +783,9 @@ static int can_write_extent(struct bch_fs *c, struct data_update *m)
darray_for_each(m->op.devs_have, i)
__clear_bit(*i, devs.d);
+ CLASS(printbuf, buf)();
+ buf.atomic++;
+
guard(rcu)();
unsigned nr_replicas = 0, i;
@@ -794,7 +797,11 @@ static int can_write_extent(struct bch_fs *c, struct data_update *m)
struct bch_dev_usage usage;
bch2_dev_usage_read_fast(ca, &usage);
- if (!dev_buckets_free(ca, usage, m->op.watermark))
+ u64 nr_free = dev_buckets_free(ca, usage, m->op.watermark);
+
+ prt_printf(&buf, "%s=%llu ", ca->name, nr_free);
+
+ if (!nr_free)
continue;
nr_replicas += ca->mi.durability;
@@ -802,8 +809,10 @@ static int can_write_extent(struct bch_fs *c, struct data_update *m)
break;
}
- if (!nr_replicas)
+ if (!nr_replicas) {
+ trace_data_update_done_no_rw_devs(c, buf.buf);
return bch_err_throw(c, data_update_done_no_rw_devs);
+ }
if (nr_replicas < m->op.nr_replicas)
return bch_err_throw(c, insufficient_devices);
return 0;
diff --git a/libbcachefs/extents.c b/libbcachefs/extents.c
index 83cbd77d..ec0951fb 100644
--- a/libbcachefs/extents.c
+++ b/libbcachefs/extents.c
@@ -1023,6 +1023,18 @@ bool bch2_bkey_has_target(struct bch_fs *c, struct bkey_s_c k, unsigned target)
return false;
}
+bool bch2_bkey_in_target(struct bch_fs *c, struct bkey_s_c k, unsigned target)
+{
+ struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
+
+ guard(rcu)();
+ bkey_for_each_ptr(ptrs, ptr)
+ if (!bch2_dev_in_target(c, ptr->dev, target))
+ return false;
+
+ return true;
+}
+
bool bch2_bkey_matches_ptr(struct bch_fs *c, struct bkey_s_c k,
struct bch_extent_ptr m, u64 offset)
{
diff --git a/libbcachefs/extents.h b/libbcachefs/extents.h
index b8590e51..f212f91c 100644
--- a/libbcachefs/extents.h
+++ b/libbcachefs/extents.h
@@ -615,6 +615,7 @@ static inline struct bch_extent_ptr *bch2_bkey_has_device(struct bkey_s k, unsig
}
bool bch2_bkey_has_target(struct bch_fs *, struct bkey_s_c, unsigned);
+bool bch2_bkey_in_target(struct bch_fs *, struct bkey_s_c, unsigned);
void bch2_bkey_extent_entry_drop(struct bkey_i *, union bch_extent_entry *);
diff --git a/libbcachefs/io_read.c b/libbcachefs/io_read.c
index 210b6adc..fa56ff67 100644
--- a/libbcachefs/io_read.c
+++ b/libbcachefs/io_read.c
@@ -343,7 +343,16 @@ static struct bch_read_bio *promote_alloc(struct btree_trans *trans,
return promote;
nopromote:
- trace_io_read_nopromote(c, ret);
+ if (trace_io_read_nopromote_enabled()) {
+ CLASS(printbuf, buf)();
+ printbuf_indent_add_nextline(&buf, 2);
+ prt_printf(&buf, "%s\n", bch2_err_str(ret));
+ bch2_bkey_val_to_text(&buf, c, k);
+
+ trace_io_read_nopromote(c, buf.buf);
+ }
+ count_event(c, io_read_nopromote);
+
return NULL;
}
diff --git a/libbcachefs/journal.c b/libbcachefs/journal.c
index f22b05e0..93794d27 100644
--- a/libbcachefs/journal.c
+++ b/libbcachefs/journal.c
@@ -1589,7 +1589,7 @@ void bch2_dev_journal_exit(struct bch_dev *ca)
struct journal_device *ja = &ca->journal;
for (unsigned i = 0; i < ARRAY_SIZE(ja->bio); i++) {
- kfree(ja->bio[i]);
+ kvfree(ja->bio[i]);
ja->bio[i] = NULL;
}
@@ -1626,7 +1626,16 @@ int bch2_dev_journal_init(struct bch_dev *ca, struct bch_sb *sb)
unsigned nr_bvecs = DIV_ROUND_UP(JOURNAL_ENTRY_SIZE_MAX, PAGE_SIZE);
for (unsigned i = 0; i < ARRAY_SIZE(ja->bio); i++) {
- ja->bio[i] = kzalloc(struct_size(ja->bio[i], bio.bi_inline_vecs,
+ /*
+ * kvzalloc() is not what we want to be using here:
+ * JOURNAL_ENTRY_SIZE_MAX is probably quite a bit bigger than it
+ * needs to be.
+ *
+ * But changing that will require performance testing -
+ * performance can be sensitive to anything that affects journal
+ * pipelining.
+ */
+ ja->bio[i] = kvzalloc(struct_size(ja->bio[i], bio.bi_inline_vecs,
nr_bvecs), GFP_KERNEL);
if (!ja->bio[i])
return bch_err_throw(c, ENOMEM_dev_journal_init);
diff --git a/libbcachefs/journal_reclaim.c b/libbcachefs/journal_reclaim.c
index cd620174..0042d43b 100644
--- a/libbcachefs/journal_reclaim.c
+++ b/libbcachefs/journal_reclaim.c
@@ -170,6 +170,12 @@ static struct journal_space __journal_space_available(struct journal *j, unsigne
return (struct journal_space) { 0, 0 };
/*
+ * It's possible for bucket size to be misaligned w.r.t. the filesystem
+ * block size:
+ */
+ min_bucket_size = round_down(min_bucket_size, block_sectors(c));
+
+ /*
* We sorted largest to smallest, and we want the smallest out of the
* @nr_devs_want largest devices:
*/
diff --git a/libbcachefs/recovery_passes.c b/libbcachefs/recovery_passes.c
index c09ed2dd..6a039e01 100644
--- a/libbcachefs/recovery_passes.c
+++ b/libbcachefs/recovery_passes.c
@@ -360,7 +360,7 @@ int __bch2_run_explicit_recovery_pass(struct bch_fs *c,
!(r->passes_complete & BIT_ULL(pass));
bool ratelimit = flags & RUN_RECOVERY_PASS_ratelimit;
- if (!(in_recovery && (flags & RUN_RECOVERY_PASS_nopersistent))) {
+ if (!(flags & RUN_RECOVERY_PASS_nopersistent)) {
struct bch_sb_field_ext *ext = bch2_sb_field_get(c->disk_sb.sb, ext);
__set_bit_le64(bch2_recovery_pass_to_stable(pass), ext->recovery_passes_required);
}
diff --git a/libbcachefs/sb-counters_format.h b/libbcachefs/sb-counters_format.h
index b868702a..a59b2a10 100644
--- a/libbcachefs/sb-counters_format.h
+++ b/libbcachefs/sb-counters_format.h
@@ -12,6 +12,7 @@ enum counters_flags {
x(io_read_inline, 80, TYPE_SECTORS) \
x(io_read_hole, 81, TYPE_SECTORS) \
x(io_read_promote, 30, TYPE_COUNTER) \
+ x(io_read_nopromote, 85, TYPE_COUNTER) \
x(io_read_bounce, 31, TYPE_COUNTER) \
x(io_read_split, 33, TYPE_COUNTER) \
x(io_read_reuse_race, 34, TYPE_COUNTER) \
diff --git a/libbcachefs/trace.h b/libbcachefs/trace.h
index b5dae114..3776a140 100644
--- a/libbcachefs/trace.h
+++ b/libbcachefs/trace.h
@@ -292,23 +292,9 @@ DEFINE_EVENT(bio, io_read_promote,
TP_ARGS(bio)
);
-TRACE_EVENT(io_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(fs_str, io_read_nopromote,
+ TP_PROTO(struct bch_fs *c, const char *str),
+ TP_ARGS(c, str)
);
DEFINE_EVENT(bio, io_read_bounce,
@@ -1330,6 +1316,11 @@ DEFINE_EVENT(fs_str, data_update,
TP_ARGS(c, str)
);
+DEFINE_EVENT(fs_str, data_update_done_no_rw_devs,
+ TP_PROTO(struct bch_fs *c, const char *str),
+ TP_ARGS(c, str)
+);
+
DEFINE_EVENT(fs_str, io_move_pred,
TP_PROTO(struct bch_fs *c, const char *str),
TP_ARGS(c, str)