84 lines
2.9 KiB
Diff
84 lines
2.9 KiB
Diff
From 1a8f5adc2028bd7a11a96f85abae6a0e051c7ba4 Mon Sep 17 00:00:00 2001
|
|
From: Kent Overstreet <kent.overstreet@linux.dev>
|
|
Date: Sun, 17 Nov 2024 14:39:46 -0500
|
|
Subject: [PATCH 099/213] bcachefs: btree_and_journal_iter: don't iterate over
|
|
too many whiteouts when prefetching
|
|
Content-Type: text/plain; charset="utf-8"
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
To help ameloriate issues with peek operations having to skip over
|
|
deletions in the journal - just bail out if all we're doing is
|
|
prefetching btree nodes.
|
|
|
|
Since btree node prefetching runs every time we iterate to a new node,
|
|
and has to sequentially scan ahead, this avoids another O(n^2).
|
|
|
|
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
|
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
|
---
|
|
fs/bcachefs/btree_iter.c | 2 ++
|
|
fs/bcachefs/btree_journal_iter.c | 7 +++++++
|
|
fs/bcachefs/btree_journal_iter.h | 1 +
|
|
3 files changed, 10 insertions(+)
|
|
|
|
diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c
|
|
index ed74f0655d98..89f9665ce70d 100644
|
|
--- a/fs/bcachefs/btree_iter.c
|
|
+++ b/fs/bcachefs/btree_iter.c
|
|
@@ -825,6 +825,8 @@ static int btree_path_prefetch_j(struct btree_trans *trans, struct btree_path *p
|
|
|
|
bch2_bkey_buf_init(&tmp);
|
|
|
|
+ jiter->fail_if_too_many_whiteouts = true;
|
|
+
|
|
while (nr-- && !ret) {
|
|
if (!bch2_btree_node_relock(trans, path, path->level))
|
|
break;
|
|
diff --git a/fs/bcachefs/btree_journal_iter.c b/fs/bcachefs/btree_journal_iter.c
|
|
index dbc9bc233cca..cc7f5fad90c6 100644
|
|
--- a/fs/bcachefs/btree_journal_iter.c
|
|
+++ b/fs/bcachefs/btree_journal_iter.c
|
|
@@ -426,6 +426,7 @@ static void btree_and_journal_iter_prefetch(struct btree_and_journal_iter *_iter
|
|
: (level > 1 ? 1 : 16);
|
|
|
|
iter.prefetch = false;
|
|
+ iter.fail_if_too_many_whiteouts = true;
|
|
bch2_bkey_buf_init(&tmp);
|
|
|
|
while (nr--) {
|
|
@@ -444,6 +445,7 @@ static void btree_and_journal_iter_prefetch(struct btree_and_journal_iter *_iter
|
|
struct bkey_s_c bch2_btree_and_journal_iter_peek(struct btree_and_journal_iter *iter)
|
|
{
|
|
struct bkey_s_c btree_k, journal_k = bkey_s_c_null, ret;
|
|
+ size_t iters = 0;
|
|
|
|
if (iter->prefetch && iter->journal.level)
|
|
btree_and_journal_iter_prefetch(iter);
|
|
@@ -451,6 +453,11 @@ struct bkey_s_c bch2_btree_and_journal_iter_peek(struct btree_and_journal_iter *
|
|
if (iter->at_end)
|
|
return bkey_s_c_null;
|
|
|
|
+ iters++;
|
|
+
|
|
+ if (iters > 20 && iter->fail_if_too_many_whiteouts)
|
|
+ return bkey_s_c_null;
|
|
+
|
|
while ((btree_k = bch2_journal_iter_peek_btree(iter)).k &&
|
|
bpos_lt(btree_k.k->p, iter->pos))
|
|
bch2_journal_iter_advance_btree(iter);
|
|
diff --git a/fs/bcachefs/btree_journal_iter.h b/fs/bcachefs/btree_journal_iter.h
|
|
index 118ada4cdd1b..9e8f8ab1c6ff 100644
|
|
--- a/fs/bcachefs/btree_journal_iter.h
|
|
+++ b/fs/bcachefs/btree_journal_iter.h
|
|
@@ -26,6 +26,7 @@ struct btree_and_journal_iter {
|
|
struct bpos pos;
|
|
bool at_end;
|
|
bool prefetch;
|
|
+ bool fail_if_too_many_whiteouts;
|
|
};
|
|
|
|
static inline int __journal_key_btree_cmp(enum btree_id l_btree_id,
|
|
--
|
|
2.45.2
|
|
|