summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2024-01-04 17:21:06 -0500
committerKent Overstreet <kent.overstreet@linux.dev>2024-02-15 22:07:27 -0500
commit1274ddd2526ca2afc1c3d8d2b80c05872533c5e2 (patch)
treee7a9ed9d618de570e347f9ff879ad1120f80c8b2
parent9a555a741e807275c320807babd3f42efb8fee90 (diff)
bcachefs: better srcu warning
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r--fs/bcachefs/btree_iter.c29
-rw-r--r--fs/bcachefs/fs-io.c10
2 files changed, 36 insertions, 3 deletions
diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c
index 20b32c71b20a..9f9ebca6656b 100644
--- a/fs/bcachefs/btree_iter.c
+++ b/fs/bcachefs/btree_iter.c
@@ -2822,11 +2822,34 @@ void *__bch2_trans_kmalloc(struct btree_trans *trans, size_t size)
return p;
}
+#include "sb-members.h"
+
static inline void check_srcu_held_too_long(struct btree_trans *trans)
{
- WARN(trans->srcu_held && time_after(jiffies, trans->srcu_lock_time + HZ * 10),
- "btree trans held srcu lock (delaying memory reclaim) for %lu seconds",
- (jiffies - trans->srcu_lock_time) / HZ);
+ if (trans->srcu_held && time_after(jiffies, trans->srcu_lock_time + HZ * 10)) {
+ struct printbuf buf = PRINTBUF;
+
+ prt_str(&buf, "btree node read time:\n");
+ bch2_time_stats_to_text(&buf, &trans->c->times[BCH_TIME_btree_node_read]);
+
+ prt_str(&buf, "btree node read_done time:\n");
+ bch2_time_stats_to_text(&buf, &trans->c->times[BCH_TIME_btree_node_read_done]);
+
+ for_each_member_device(trans->c, ca) {
+ prt_printf(&buf, "device %u read time:\n", ca->dev_idx);
+ bch2_time_stats_to_text(&buf, &ca->io_latency[READ]);
+ }
+
+ struct btree_transaction_stats *s = btree_trans_stats(trans);
+ prt_str(&buf, "transaction duration:\n");
+ bch2_time_stats_to_text(&buf, &s->duration);
+
+ WARN(trans->srcu_held && time_after(jiffies, trans->srcu_lock_time + HZ * 10),
+ "btree trans held srcu lock (delaying memory reclaim) for %lu seconds",
+ (jiffies - trans->srcu_lock_time) / HZ);
+ bch2_print_string_as_lines(KERN_ERR, buf.buf);
+ printbuf_exit(&buf);
+ }
}
void bch2_trans_srcu_unlock(struct btree_trans *trans)
diff --git a/fs/bcachefs/fs-io.c b/fs/bcachefs/fs-io.c
index 8c70123b6a0c..9139caa0fc25 100644
--- a/fs/bcachefs/fs-io.c
+++ b/fs/bcachefs/fs-io.c
@@ -194,6 +194,16 @@ int bch2_fsync(struct file *file, loff_t start, loff_t end, int datasync)
struct bch_fs *c = inode->v.i_sb->s_fs_info;
int ret;
+ /*
+ * check if unlinked, disable/defer until relink
+ */
+
+ /*
+ * also: add a mode where a file is a tmpfile until fully,
+ * asynchronously written
+ */
+
+
ret = file_write_and_wait_range(file, start, end);
if (ret)
goto out;