Skip to content

Commit d39881d

Browse files
author
Kent Overstreet
committed
bcachefs: add check for missing fragmentation in check_alloc_to_lru_ref()
We need to make sure we're not missing any fragmenation entries in the LRU BTREE after repairing ALLOC BTREE Also, use the new bch2_btree_write_buffer_maybe_flush() helper; this was only working without it before since bucket invalidation (usually) wasn't happening while fsck was running. Co-developed-by: Daniel Hill <[email protected]> Signed-off-by: Kent Overstreet <[email protected]>
1 parent 92e1c29 commit d39881d

File tree

3 files changed

+65
-25
lines changed

3 files changed

+65
-25
lines changed

fs/bcachefs/alloc_background.c

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "alloc_background.h"
44
#include "alloc_foreground.h"
55
#include "backpointers.h"
6+
#include "bkey_buf.h"
67
#include "btree_cache.h"
78
#include "btree_io.h"
89
#include "btree_key_cache.h"
@@ -1553,13 +1554,13 @@ int bch2_check_alloc_info(struct bch_fs *c)
15531554
}
15541555

15551556
static int bch2_check_alloc_to_lru_ref(struct btree_trans *trans,
1556-
struct btree_iter *alloc_iter)
1557+
struct btree_iter *alloc_iter,
1558+
struct bkey_buf *last_flushed)
15571559
{
15581560
struct bch_fs *c = trans->c;
1559-
struct btree_iter lru_iter;
15601561
struct bch_alloc_v4 a_convert;
15611562
const struct bch_alloc_v4 *a;
1562-
struct bkey_s_c alloc_k, lru_k;
1563+
struct bkey_s_c alloc_k;
15631564
struct printbuf buf = PRINTBUF;
15641565
int ret;
15651566

@@ -1573,6 +1574,14 @@ static int bch2_check_alloc_to_lru_ref(struct btree_trans *trans,
15731574

15741575
a = bch2_alloc_to_v4(alloc_k, &a_convert);
15751576

1577+
if (a->fragmentation_lru) {
1578+
ret = bch2_lru_check_set(trans, BCH_LRU_FRAGMENTATION_START,
1579+
a->fragmentation_lru,
1580+
alloc_k, last_flushed);
1581+
if (ret)
1582+
return ret;
1583+
}
1584+
15761585
if (a->data_type != BCH_DATA_cached)
15771586
return 0;
15781587

@@ -1597,41 +1606,30 @@ static int bch2_check_alloc_to_lru_ref(struct btree_trans *trans,
15971606
a = &a_mut->v;
15981607
}
15991608

1600-
lru_k = bch2_bkey_get_iter(trans, &lru_iter, BTREE_ID_lru,
1601-
lru_pos(alloc_k.k->p.inode,
1602-
bucket_to_u64(alloc_k.k->p),
1603-
a->io_time[READ]), 0);
1604-
ret = bkey_err(lru_k);
1609+
ret = bch2_lru_check_set(trans, alloc_k.k->p.inode, a->io_time[READ],
1610+
alloc_k, last_flushed);
16051611
if (ret)
1606-
return ret;
1607-
1608-
if (fsck_err_on(lru_k.k->type != KEY_TYPE_set, c,
1609-
alloc_key_to_missing_lru_entry,
1610-
"missing lru entry\n"
1611-
" %s",
1612-
(printbuf_reset(&buf),
1613-
bch2_bkey_val_to_text(&buf, c, alloc_k), buf.buf))) {
1614-
ret = bch2_lru_set(trans,
1615-
alloc_k.k->p.inode,
1616-
bucket_to_u64(alloc_k.k->p),
1617-
a->io_time[READ]);
1618-
if (ret)
1619-
goto err;
1620-
}
1612+
goto err;
16211613
err:
16221614
fsck_err:
1623-
bch2_trans_iter_exit(trans, &lru_iter);
16241615
printbuf_exit(&buf);
16251616
return ret;
16261617
}
16271618

16281619
int bch2_check_alloc_to_lru_refs(struct bch_fs *c)
16291620
{
1621+
struct bkey_buf last_flushed;
1622+
1623+
bch2_bkey_buf_init(&last_flushed);
1624+
bkey_init(&last_flushed.k->k);
1625+
16301626
int ret = bch2_trans_run(c,
16311627
for_each_btree_key_commit(trans, iter, BTREE_ID_alloc,
16321628
POS_MIN, BTREE_ITER_prefetch, k,
16331629
NULL, NULL, BCH_TRANS_COMMIT_no_enospc,
1634-
bch2_check_alloc_to_lru_ref(trans, &iter)));
1630+
bch2_check_alloc_to_lru_ref(trans, &iter, &last_flushed)));
1631+
1632+
bch2_bkey_buf_exit(&last_flushed, c);
16351633
bch_err_fn(c, ret);
16361634
return ret;
16371635
}

fs/bcachefs/lru.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,45 @@ static const char * const bch2_lru_types[] = {
7777
NULL
7878
};
7979

80+
int bch2_lru_check_set(struct btree_trans *trans,
81+
u16 lru_id, u64 time,
82+
struct bkey_s_c referring_k,
83+
struct bkey_buf *last_flushed)
84+
{
85+
struct bch_fs *c = trans->c;
86+
struct printbuf buf = PRINTBUF;
87+
struct btree_iter lru_iter;
88+
struct bkey_s_c lru_k =
89+
bch2_bkey_get_iter(trans, &lru_iter, BTREE_ID_lru,
90+
lru_pos(lru_id,
91+
bucket_to_u64(referring_k.k->p),
92+
time), 0);
93+
int ret = bkey_err(lru_k);
94+
if (ret)
95+
return ret;
96+
97+
if (lru_k.k->type != KEY_TYPE_set) {
98+
ret = bch2_btree_write_buffer_maybe_flush(trans, referring_k, last_flushed);
99+
if (ret)
100+
goto err;
101+
102+
if (fsck_err(c, alloc_key_to_missing_lru_entry,
103+
"missing %s lru entry\n"
104+
" %s",
105+
bch2_lru_types[lru_type(lru_k)],
106+
(bch2_bkey_val_to_text(&buf, c, referring_k), buf.buf))) {
107+
ret = bch2_lru_set(trans, lru_id, bucket_to_u64(referring_k.k->p), time);
108+
if (ret)
109+
goto err;
110+
}
111+
}
112+
err:
113+
fsck_err:
114+
bch2_trans_iter_exit(trans, &lru_iter);
115+
printbuf_exit(&buf);
116+
return ret;
117+
}
118+
80119
static int bch2_check_lru_key(struct btree_trans *trans,
81120
struct btree_iter *lru_iter,
82121
struct bkey_s_c lru_k,

fs/bcachefs/lru.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ int bch2_lru_del(struct btree_trans *, u16, u64, u64);
6161
int bch2_lru_set(struct btree_trans *, u16, u64, u64);
6262
int bch2_lru_change(struct btree_trans *, u16, u64, u64, u64);
6363

64+
struct bkey_buf;
65+
int bch2_lru_check_set(struct btree_trans *, u16, u64, struct bkey_s_c, struct bkey_buf *);
66+
6467
int bch2_check_lrus(struct bch_fs *);
6568

6669
#endif /* _BCACHEFS_LRU_H */

0 commit comments

Comments
 (0)