Skip to content

Commit 2e9940d

Browse files
author
Kent Overstreet
committed
bcachefs: Handle cached data LRU wraparound
We only have 48 bits for the LRU time field, which is insufficient to prevent wraparound. Signed-off-by: Kent Overstreet <[email protected]>
1 parent cff07e2 commit 2e9940d

File tree

1 file changed

+41
-5
lines changed

1 file changed

+41
-5
lines changed

fs/bcachefs/alloc_background.c

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2019,6 +2019,21 @@ static int invalidate_one_bucket(struct btree_trans *trans,
20192019
goto out;
20202020
}
20212021

2022+
static struct bkey_s_c next_lru_key(struct btree_trans *trans, struct btree_iter *iter,
2023+
struct bch_dev *ca, bool *wrapped)
2024+
{
2025+
struct bkey_s_c k;
2026+
again:
2027+
k = bch2_btree_iter_peek_upto(iter, lru_pos(ca->dev_idx, U64_MAX, LRU_TIME_MAX));
2028+
if (!k.k && !*wrapped) {
2029+
bch2_btree_iter_set_pos(iter, lru_pos(ca->dev_idx, 0, 0));
2030+
*wrapped = true;
2031+
goto again;
2032+
}
2033+
2034+
return k;
2035+
}
2036+
20222037
static void bch2_do_invalidates_work(struct work_struct *work)
20232038
{
20242039
struct bch_fs *c = container_of(work, struct bch_fs, invalidate_work);
@@ -2032,12 +2047,33 @@ static void bch2_do_invalidates_work(struct work_struct *work)
20322047
for_each_member_device(c, ca) {
20332048
s64 nr_to_invalidate =
20342049
should_invalidate_buckets(ca, bch2_dev_usage_read(ca));
2050+
struct btree_iter iter;
2051+
bool wrapped = false;
2052+
2053+
bch2_trans_iter_init(trans, &iter, BTREE_ID_lru,
2054+
lru_pos(ca->dev_idx, 0,
2055+
((bch2_current_io_time(c, READ) + U32_MAX) &
2056+
LRU_TIME_MAX)), 0);
20352057

2036-
ret = for_each_btree_key_upto(trans, iter, BTREE_ID_lru,
2037-
lru_pos(ca->dev_idx, 0, 0),
2038-
lru_pos(ca->dev_idx, U64_MAX, LRU_TIME_MAX),
2039-
BTREE_ITER_intent, k,
2040-
invalidate_one_bucket(trans, &iter, k, &nr_to_invalidate));
2058+
while (true) {
2059+
bch2_trans_begin(trans);
2060+
2061+
struct bkey_s_c k = next_lru_key(trans, &iter, ca, &wrapped);
2062+
ret = bkey_err(k);
2063+
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
2064+
continue;
2065+
if (ret)
2066+
break;
2067+
if (!k.k)
2068+
break;
2069+
2070+
ret = invalidate_one_bucket(trans, &iter, k, &nr_to_invalidate);
2071+
if (ret)
2072+
break;
2073+
2074+
bch2_btree_iter_advance(&iter);
2075+
}
2076+
bch2_trans_iter_exit(trans, &iter);
20412077

20422078
if (ret < 0) {
20432079
bch2_dev_put(ca);

0 commit comments

Comments
 (0)