Skip to content

Commit 4412b8b

Browse files
committed
Merge tag 'bcachefs-2025-07-11' of git://evilpiepirate.org/bcachefs
Pull bcachefs fixes from Kent Overstreet. * tag 'bcachefs-2025-07-11' of git://evilpiepirate.org/bcachefs: bcachefs: Don't set BCH_FS_error on transaction restart bcachefs: Fix additional misalignment in journal space calculations bcachefs: Don't schedule non persistent passes persistently bcachefs: Fix bch2_btree_transactions_read() synchronization bcachefs: btree read retry fixes bcachefs: btree node scan no longer uses btree cache bcachefs: Tweak btree cache helpers for use by btree node scan bcachefs: Fix btree for nonexistent tree depth bcachefs: Fix bch2_io_failures_to_text() bcachefs: bch2_fpunch_snapshot()
2 parents 2632d81 + fec5e6f commit 4412b8b

File tree

14 files changed

+138
-108
lines changed

14 files changed

+138
-108
lines changed

fs/bcachefs/btree_cache.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ void bch2_btree_node_to_freelist(struct bch_fs *c, struct btree *b)
8585
six_unlock_intent(&b->c.lock);
8686
}
8787

88-
static void __btree_node_data_free(struct btree_cache *bc, struct btree *b)
88+
void __btree_node_data_free(struct btree *b)
8989
{
9090
BUG_ON(!list_empty(&b->list));
9191
BUG_ON(btree_node_hashed(b));
@@ -112,16 +112,17 @@ static void __btree_node_data_free(struct btree_cache *bc, struct btree *b)
112112
munmap(b->aux_data, btree_aux_data_bytes(b));
113113
#endif
114114
b->aux_data = NULL;
115-
116-
btree_node_to_freedlist(bc, b);
117115
}
118116

119117
static void btree_node_data_free(struct btree_cache *bc, struct btree *b)
120118
{
121119
BUG_ON(list_empty(&b->list));
122120
list_del_init(&b->list);
121+
122+
__btree_node_data_free(b);
123+
123124
--bc->nr_freeable;
124-
__btree_node_data_free(bc, b);
125+
btree_node_to_freedlist(bc, b);
125126
}
126127

127128
static int bch2_btree_cache_cmp_fn(struct rhashtable_compare_arg *arg,
@@ -185,10 +186,7 @@ static struct btree *__btree_node_mem_alloc(struct bch_fs *c, gfp_t gfp)
185186

186187
struct btree *__bch2_btree_node_mem_alloc(struct bch_fs *c)
187188
{
188-
struct btree_cache *bc = &c->btree_cache;
189-
struct btree *b;
190-
191-
b = __btree_node_mem_alloc(c, GFP_KERNEL);
189+
struct btree *b = __btree_node_mem_alloc(c, GFP_KERNEL);
192190
if (!b)
193191
return NULL;
194192

@@ -198,8 +196,6 @@ struct btree *__bch2_btree_node_mem_alloc(struct bch_fs *c)
198196
}
199197

200198
bch2_btree_lock_init(&b->c, 0, GFP_KERNEL);
201-
202-
__bch2_btree_node_to_freelist(bc, b);
203199
return b;
204200
}
205201

@@ -524,7 +520,8 @@ static unsigned long bch2_btree_cache_scan(struct shrinker *shrink,
524520
--touched;;
525521
} else if (!btree_node_reclaim(c, b)) {
526522
__bch2_btree_node_hash_remove(bc, b);
527-
__btree_node_data_free(bc, b);
523+
__btree_node_data_free(b);
524+
btree_node_to_freedlist(bc, b);
528525

529526
freed++;
530527
bc->nr_freed++;
@@ -652,9 +649,12 @@ int bch2_fs_btree_cache_init(struct bch_fs *c)
652649

653650
bch2_recalc_btree_reserve(c);
654651

655-
for (i = 0; i < bc->nr_reserve; i++)
656-
if (!__bch2_btree_node_mem_alloc(c))
652+
for (i = 0; i < bc->nr_reserve; i++) {
653+
struct btree *b = __bch2_btree_node_mem_alloc(c);
654+
if (!b)
657655
goto err;
656+
__bch2_btree_node_to_freelist(bc, b);
657+
}
658658

659659
list_splice_init(&bc->live[0].list, &bc->freeable);
660660

fs/bcachefs/btree_cache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ void bch2_btree_node_update_key_early(struct btree_trans *, enum btree_id, unsig
3030
void bch2_btree_cache_cannibalize_unlock(struct btree_trans *);
3131
int bch2_btree_cache_cannibalize_lock(struct btree_trans *, struct closure *);
3232

33+
void __btree_node_data_free(struct btree *);
3334
struct btree *__bch2_btree_node_mem_alloc(struct bch_fs *);
3435
struct btree *bch2_btree_node_mem_alloc(struct btree_trans *, bool);
3536

fs/bcachefs/btree_io.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -568,9 +568,9 @@ static int __btree_err(int ret,
568568
bch2_mark_btree_validate_failure(failed, ca->dev_idx);
569569

570570
struct extent_ptr_decoded pick;
571-
have_retry = !bch2_bkey_pick_read_device(c,
571+
have_retry = bch2_bkey_pick_read_device(c,
572572
bkey_i_to_s_c(&b->key),
573-
failed, &pick, -1);
573+
failed, &pick, -1) == 1;
574574
}
575575

576576
if (!have_retry && ret == -BCH_ERR_btree_node_read_err_want_retry)
@@ -615,7 +615,6 @@ static int __btree_err(int ret,
615615
goto out;
616616
case -BCH_ERR_btree_node_read_err_bad_node:
617617
prt_str(&out, ", ");
618-
ret = __bch2_topology_error(c, &out);
619618
break;
620619
}
621620

@@ -644,7 +643,6 @@ static int __btree_err(int ret,
644643
goto out;
645644
case -BCH_ERR_btree_node_read_err_bad_node:
646645
prt_str(&out, ", ");
647-
ret = __bch2_topology_error(c, &out);
648646
break;
649647
}
650648
print:
@@ -1408,7 +1406,7 @@ static void btree_node_read_work(struct work_struct *work)
14081406
ret = bch2_bkey_pick_read_device(c,
14091407
bkey_i_to_s_c(&b->key),
14101408
&failed, &rb->pick, -1);
1411-
if (ret) {
1409+
if (ret <= 0) {
14121410
set_btree_node_read_error(b);
14131411
break;
14141412
}

fs/bcachefs/btree_node_scan.c

Lines changed: 41 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -75,39 +75,6 @@ static inline u64 bkey_journal_seq(struct bkey_s_c k)
7575
}
7676
}
7777

78-
static bool found_btree_node_is_readable(struct btree_trans *trans,
79-
struct found_btree_node *f)
80-
{
81-
struct { __BKEY_PADDED(k, BKEY_BTREE_PTR_VAL_U64s_MAX); } tmp;
82-
83-
found_btree_node_to_key(&tmp.k, f);
84-
85-
struct btree *b = bch2_btree_node_get_noiter(trans, &tmp.k, f->btree_id, f->level, false);
86-
bool ret = !IS_ERR_OR_NULL(b);
87-
if (!ret)
88-
return ret;
89-
90-
f->sectors_written = b->written;
91-
f->journal_seq = le64_to_cpu(b->data->keys.journal_seq);
92-
93-
struct bkey_s_c k;
94-
struct bkey unpacked;
95-
struct btree_node_iter iter;
96-
for_each_btree_node_key_unpack(b, k, &iter, &unpacked)
97-
f->journal_seq = max(f->journal_seq, bkey_journal_seq(k));
98-
99-
six_unlock_read(&b->c.lock);
100-
101-
/*
102-
* We might update this node's range; if that happens, we need the node
103-
* to be re-read so the read path can trim keys that are no longer in
104-
* this node
105-
*/
106-
if (b != btree_node_root(trans->c, b))
107-
bch2_btree_node_evict(trans, &tmp.k);
108-
return ret;
109-
}
110-
11178
static int found_btree_node_cmp_cookie(const void *_l, const void *_r)
11279
{
11380
const struct found_btree_node *l = _l;
@@ -159,17 +126,17 @@ static const struct min_heap_callbacks found_btree_node_heap_cbs = {
159126
};
160127

161128
static void try_read_btree_node(struct find_btree_nodes *f, struct bch_dev *ca,
162-
struct bio *bio, struct btree_node *bn, u64 offset)
129+
struct btree *b, struct bio *bio, u64 offset)
163130
{
164131
struct bch_fs *c = container_of(f, struct bch_fs, found_btree_nodes);
132+
struct btree_node *bn = b->data;
165133

166134
bio_reset(bio, ca->disk_sb.bdev, REQ_OP_READ);
167135
bio->bi_iter.bi_sector = offset;
168-
bch2_bio_map(bio, bn, PAGE_SIZE);
136+
bch2_bio_map(bio, b->data, c->opts.block_size);
169137

170138
u64 submit_time = local_clock();
171139
submit_bio_wait(bio);
172-
173140
bch2_account_io_completion(ca, BCH_MEMBER_ERROR_read, submit_time, !bio->bi_status);
174141

175142
if (bio->bi_status) {
@@ -201,6 +168,14 @@ static void try_read_btree_node(struct find_btree_nodes *f, struct bch_dev *ca,
201168
if (BTREE_NODE_ID(bn) >= BTREE_ID_NR_MAX)
202169
return;
203170

171+
bio_reset(bio, ca->disk_sb.bdev, REQ_OP_READ);
172+
bio->bi_iter.bi_sector = offset;
173+
bch2_bio_map(bio, b->data, c->opts.btree_node_size);
174+
175+
submit_time = local_clock();
176+
submit_bio_wait(bio);
177+
bch2_account_io_completion(ca, BCH_MEMBER_ERROR_read, submit_time, !bio->bi_status);
178+
204179
rcu_read_lock();
205180
struct found_btree_node n = {
206181
.btree_id = BTREE_NODE_ID(bn),
@@ -217,7 +192,20 @@ static void try_read_btree_node(struct find_btree_nodes *f, struct bch_dev *ca,
217192
};
218193
rcu_read_unlock();
219194

220-
if (bch2_trans_run(c, found_btree_node_is_readable(trans, &n))) {
195+
found_btree_node_to_key(&b->key, &n);
196+
197+
CLASS(printbuf, buf)();
198+
if (!bch2_btree_node_read_done(c, ca, b, NULL, &buf)) {
199+
/* read_done will swap out b->data for another buffer */
200+
bn = b->data;
201+
/*
202+
* Grab journal_seq here because we want the max journal_seq of
203+
* any bset; read_done sorts down to a single set and picks the
204+
* max journal_seq
205+
*/
206+
n.journal_seq = le64_to_cpu(bn->keys.journal_seq),
207+
n.sectors_written = b->written;
208+
221209
mutex_lock(&f->lock);
222210
if (BSET_BIG_ENDIAN(&bn->keys) != CPU_BIG_ENDIAN) {
223211
bch_err(c, "try_read_btree_node() can't handle endian conversion");
@@ -237,12 +225,20 @@ static int read_btree_nodes_worker(void *p)
237225
struct find_btree_nodes_worker *w = p;
238226
struct bch_fs *c = container_of(w->f, struct bch_fs, found_btree_nodes);
239227
struct bch_dev *ca = w->ca;
240-
void *buf = (void *) __get_free_page(GFP_KERNEL);
241-
struct bio *bio = bio_alloc(NULL, 1, 0, GFP_KERNEL);
242228
unsigned long last_print = jiffies;
229+
struct btree *b = NULL;
230+
struct bio *bio = NULL;
231+
232+
b = __bch2_btree_node_mem_alloc(c);
233+
if (!b) {
234+
bch_err(c, "read_btree_nodes_worker: error allocating buf");
235+
w->f->ret = -ENOMEM;
236+
goto err;
237+
}
243238

244-
if (!buf || !bio) {
245-
bch_err(c, "read_btree_nodes_worker: error allocating bio/buf");
239+
bio = bio_alloc(NULL, buf_pages(b->data, c->opts.btree_node_size), 0, GFP_KERNEL);
240+
if (!bio) {
241+
bch_err(c, "read_btree_nodes_worker: error allocating bio");
246242
w->f->ret = -ENOMEM;
247243
goto err;
248244
}
@@ -266,11 +262,13 @@ static int read_btree_nodes_worker(void *p)
266262
!bch2_dev_btree_bitmap_marked_sectors(ca, sector, btree_sectors(c)))
267263
continue;
268264

269-
try_read_btree_node(w->f, ca, bio, buf, sector);
265+
try_read_btree_node(w->f, ca, b, bio, sector);
270266
}
271267
err:
268+
if (b)
269+
__btree_node_data_free(b);
270+
kfree(b);
272271
bio_put(bio);
273-
free_page((unsigned long) buf);
274272
enumerated_ref_put(&ca->io_ref[READ], BCH_DEV_READ_REF_btree_node_scan);
275273
closure_put(w->cl);
276274
kfree(w);

fs/bcachefs/debug.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,6 @@ void __bch2_btree_verify(struct bch_fs *c, struct btree *b)
153153
c->verify_data = __bch2_btree_node_mem_alloc(c);
154154
if (!c->verify_data)
155155
goto out;
156-
157-
list_del_init(&c->verify_data->list);
158156
}
159157

160158
BUG_ON(b->nsets != 1);
@@ -586,6 +584,8 @@ static ssize_t bch2_btree_transactions_read(struct file *file, char __user *buf,
586584
i->ubuf = buf;
587585
i->size = size;
588586
i->ret = 0;
587+
588+
int srcu_idx = srcu_read_lock(&c->btree_trans_barrier);
589589
restart:
590590
seqmutex_lock(&c->btree_trans_lock);
591591
list_sort(&c->btree_trans_list, list_ptr_order_cmp);
@@ -599,6 +599,11 @@ static ssize_t bch2_btree_transactions_read(struct file *file, char __user *buf,
599599
if (!closure_get_not_zero(&trans->ref))
600600
continue;
601601

602+
if (!trans->srcu_held) {
603+
closure_put(&trans->ref);
604+
continue;
605+
}
606+
602607
u32 seq = seqmutex_unlock(&c->btree_trans_lock);
603608

604609
bch2_btree_trans_to_text(&i->buf, trans);
@@ -620,6 +625,8 @@ static ssize_t bch2_btree_transactions_read(struct file *file, char __user *buf,
620625
}
621626
seqmutex_unlock(&c->btree_trans_lock);
622627
unlocked:
628+
srcu_read_unlock(&c->btree_trans_barrier, srcu_idx);
629+
623630
if (i->buf.allocation_failure)
624631
ret = -ENOMEM;
625632

fs/bcachefs/errcode.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,6 @@
282282
x(EIO, sb_not_downgraded) \
283283
x(EIO, btree_node_write_all_failed) \
284284
x(EIO, btree_node_read_error) \
285-
x(EIO, btree_node_read_validate_error) \
286285
x(EIO, btree_need_topology_repair) \
287286
x(EIO, bucket_ref_update) \
288287
x(EIO, trigger_alloc) \

fs/bcachefs/error.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ int __bch2_topology_error(struct bch_fs *c, struct printbuf *out)
103103
return bch_err_throw(c, btree_need_topology_repair);
104104
} else {
105105
return bch2_run_explicit_recovery_pass(c, out, BCH_RECOVERY_PASS_check_topology, 0) ?:
106-
bch_err_throw(c, btree_node_read_validate_error);
106+
bch_err_throw(c, btree_need_topology_repair);
107107
}
108108
}
109109

@@ -633,7 +633,9 @@ int __bch2_fsck_err(struct bch_fs *c,
633633
* log_fsck_err()s: that would require us to track for every error type
634634
* which recovery pass corrects it, to get the fsck exit status correct:
635635
*/
636-
if (bch2_err_matches(ret, BCH_ERR_fsck_fix)) {
636+
if (bch2_err_matches(ret, BCH_ERR_transaction_restart)) {
637+
/* nothing */
638+
} else if (bch2_err_matches(ret, BCH_ERR_fsck_fix)) {
637639
set_bit(BCH_FS_errors_fixed, &c->flags);
638640
} else {
639641
set_bit(BCH_FS_errors_not_fixed, &c->flags);

fs/bcachefs/extents.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,19 +50,17 @@ void bch2_io_failures_to_text(struct printbuf *out,
5050
struct bch_io_failures *failed)
5151
{
5252
static const char * const error_types[] = {
53-
"io", "checksum", "ec reconstruct", NULL
53+
"btree validate", "io", "checksum", "ec reconstruct", NULL
5454
};
5555

5656
for (struct bch_dev_io_failures *f = failed->devs;
5757
f < failed->devs + failed->nr;
5858
f++) {
5959
unsigned errflags =
60-
((!!f->failed_io) << 0) |
61-
((!!f->failed_csum_nr) << 1) |
62-
((!!f->failed_ec) << 2);
63-
64-
if (!errflags)
65-
continue;
60+
((!!f->failed_btree_validate) << 0) |
61+
((!!f->failed_io) << 1) |
62+
((!!f->failed_csum_nr) << 2) |
63+
((!!f->failed_ec) << 3);
6664

6765
bch2_printbuf_make_room(out, 1024);
6866
out->atomic++;
@@ -77,7 +75,9 @@ void bch2_io_failures_to_text(struct printbuf *out,
7775

7876
prt_char(out, ' ');
7977

80-
if (is_power_of_2(errflags)) {
78+
if (!errflags) {
79+
prt_str(out, "no error - confused");
80+
} else if (is_power_of_2(errflags)) {
8181
prt_bitflags(out, error_types, errflags);
8282
prt_str(out, " error");
8383
} else {

0 commit comments

Comments
 (0)