Skip to content

Commit 2bfcee5

Browse files
committed
Merge tag 'bcachefs-2025-05-01' of git://evilpiepirate.org/bcachefs
Pull bcachefs fixes from Kent Overstreet: "Lots of assorted small fixes... - Some repair path fixes, a fix for -ENOMEM when reconstructing lots of alloc info on large filesystems, upgrade for ancient 0.14 filesystems, etc. - Various assert tweaks; assert -> ERO, ERO -> log the error in the superblock and continue - casefolding now uses d_ops like on other casefolding filesystems - fix device label create on device add, fix bucket array resize on filesystem resize - fix xattrs with FORTIFY_SOURCE builds with gcc-15/clang" * tag 'bcachefs-2025-05-01' of git://evilpiepirate.org/bcachefs: (22 commits) bcachefs: Remove incorrect __counted_by annotation bcachefs: add missing sched_annotate_sleep() bcachefs: Fix __bch2_dev_group_set() bcachefs: Kill ERO for i_blocks check in truncate bcachefs: check for inode.bi_sectors underflow bcachefs: Kill ERO in __bch2_i_sectors_acct() bcachefs: readdir fixes bcachefs: improve missing journal write device error message bcachefs: Topology error after insert is now an ERO bcachefs: Use bch2_kvmalloc() for journal keys array bcachefs: More informative error message when shutting down due to error bcachefs: btree_root_unreadable_and_scan_found_nothing autofix for non data btrees bcachefs: btree_node_data_missing is now autofix bcachefs: Don't generate alloc updates to invalid buckets bcachefs: Improve bch2_dev_bucket_missing() bcachefs: fix bch2_dev_buckets_resize() bcachefs: Add upgrade table entry from 0.14 bcachefs: Run BCH_RECOVERY_PASS_reconstruct_snapshots on missing subvol -> snapshot bcachefs: Add missing utf8_unload() bcachefs: Emit unicode version message on startup ...
2 parents 85951e1 + 6846100 commit 2bfcee5

20 files changed

+219
-91
lines changed

fs/bcachefs/btree_gc.c

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,27 @@
4747
#define DROP_PREV_NODE 11
4848
#define DID_FILL_FROM_SCAN 12
4949

50+
/*
51+
* Returns true if it's a btree we can easily reconstruct, or otherwise won't
52+
* cause data loss if it's missing:
53+
*/
54+
static bool btree_id_important(enum btree_id btree)
55+
{
56+
if (btree_id_is_alloc(btree))
57+
return false;
58+
59+
switch (btree) {
60+
case BTREE_ID_quotas:
61+
case BTREE_ID_snapshot_trees:
62+
case BTREE_ID_logged_ops:
63+
case BTREE_ID_rebalance_work:
64+
case BTREE_ID_subvolume_children:
65+
return false;
66+
default:
67+
return true;
68+
}
69+
}
70+
5071
static const char * const bch2_gc_phase_strs[] = {
5172
#define x(n) #n,
5273
GC_PHASES()
@@ -534,8 +555,10 @@ int bch2_check_topology(struct bch_fs *c)
534555
r->error = 0;
535556

536557
if (!bch2_btree_has_scanned_nodes(c, i)) {
537-
mustfix_fsck_err(trans, btree_root_unreadable_and_scan_found_nothing,
538-
"no nodes found for btree %s, continue?", buf.buf);
558+
__fsck_err(trans,
559+
FSCK_CAN_FIX|(!btree_id_important(i) ? FSCK_AUTOFIX : 0),
560+
btree_root_unreadable_and_scan_found_nothing,
561+
"no nodes found for btree %s, continue?", buf.buf);
539562
bch2_btree_root_alloc_fake_trans(trans, i, 0);
540563
} else {
541564
bch2_btree_root_alloc_fake_trans(trans, i, 1);

fs/bcachefs/btree_journal_iter.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ int bch2_journal_key_insert_take(struct bch_fs *c, enum btree_id id,
288288
.size = max_t(size_t, keys->size, 8) * 2,
289289
};
290290

291-
new_keys.data = kvmalloc_array(new_keys.size, sizeof(new_keys.data[0]), GFP_KERNEL);
291+
new_keys.data = bch2_kvmalloc(new_keys.size * sizeof(new_keys.data[0]), GFP_KERNEL);
292292
if (!new_keys.data) {
293293
bch_err(c, "%s: error allocating new key array (size %zu)",
294294
__func__, new_keys.size);

fs/bcachefs/btree_update_interior.c

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1389,7 +1389,7 @@ static void bch2_insert_fixup_btree_ptr(struct btree_update *as,
13891389
printbuf_exit(&buf);
13901390
}
13911391

1392-
static void
1392+
static int
13931393
bch2_btree_insert_keys_interior(struct btree_update *as,
13941394
struct btree_trans *trans,
13951395
struct btree_path *path,
@@ -1411,7 +1411,8 @@ bch2_btree_insert_keys_interior(struct btree_update *as,
14111411
insert = bkey_next(insert))
14121412
bch2_insert_fixup_btree_ptr(as, trans, path, b, &node_iter, insert);
14131413

1414-
if (bch2_btree_node_check_topology(trans, b)) {
1414+
int ret = bch2_btree_node_check_topology(trans, b);
1415+
if (ret) {
14151416
struct printbuf buf = PRINTBUF;
14161417

14171418
for (struct bkey_i *k = keys->keys;
@@ -1421,11 +1422,15 @@ bch2_btree_insert_keys_interior(struct btree_update *as,
14211422
prt_newline(&buf);
14221423
}
14231424

1424-
panic("%s(): check_topology error: inserted keys\n%s", __func__, buf.buf);
1425+
bch2_fs_fatal_error(as->c, "%ps -> %s(): check_topology error %s: inserted keys\n%s",
1426+
(void *) _RET_IP_, __func__, bch2_err_str(ret), buf.buf);
1427+
dump_stack();
1428+
return ret;
14251429
}
14261430

14271431
memmove_u64s_down(keys->keys, insert, keys->top_p - insert->_data);
14281432
keys->top_p -= insert->_data - keys->keys_p;
1433+
return 0;
14291434
}
14301435

14311436
static bool key_deleted_in_insert(struct keylist *insert_keys, struct bpos pos)
@@ -1559,11 +1564,11 @@ static void __btree_split_node(struct btree_update *as,
15591564
* nodes that were coalesced, and thus in the middle of a child node post
15601565
* coalescing:
15611566
*/
1562-
static void btree_split_insert_keys(struct btree_update *as,
1563-
struct btree_trans *trans,
1564-
btree_path_idx_t path_idx,
1565-
struct btree *b,
1566-
struct keylist *keys)
1567+
static int btree_split_insert_keys(struct btree_update *as,
1568+
struct btree_trans *trans,
1569+
btree_path_idx_t path_idx,
1570+
struct btree *b,
1571+
struct keylist *keys)
15671572
{
15681573
struct btree_path *path = trans->paths + path_idx;
15691574

@@ -1573,8 +1578,12 @@ static void btree_split_insert_keys(struct btree_update *as,
15731578

15741579
bch2_btree_node_iter_init(&node_iter, b, &bch2_keylist_front(keys)->k.p);
15751580

1576-
bch2_btree_insert_keys_interior(as, trans, path, b, node_iter, keys);
1581+
int ret = bch2_btree_insert_keys_interior(as, trans, path, b, node_iter, keys);
1582+
if (ret)
1583+
return ret;
15771584
}
1585+
1586+
return 0;
15781587
}
15791588

15801589
static int btree_split(struct btree_update *as, struct btree_trans *trans,
@@ -1607,8 +1616,10 @@ static int btree_split(struct btree_update *as, struct btree_trans *trans,
16071616
__btree_split_node(as, trans, b, n, keys);
16081617

16091618
if (keys) {
1610-
btree_split_insert_keys(as, trans, path, n1, keys);
1611-
btree_split_insert_keys(as, trans, path, n2, keys);
1619+
ret = btree_split_insert_keys(as, trans, path, n1, keys) ?:
1620+
btree_split_insert_keys(as, trans, path, n2, keys);
1621+
if (ret)
1622+
goto err;
16121623
BUG_ON(!bch2_keylist_empty(keys));
16131624
}
16141625

@@ -1654,15 +1665,19 @@ static int btree_split(struct btree_update *as, struct btree_trans *trans,
16541665
n3->sib_u64s[0] = U16_MAX;
16551666
n3->sib_u64s[1] = U16_MAX;
16561667

1657-
btree_split_insert_keys(as, trans, path, n3, &as->parent_keys);
1668+
ret = btree_split_insert_keys(as, trans, path, n3, &as->parent_keys);
1669+
if (ret)
1670+
goto err;
16581671
}
16591672
} else {
16601673
trace_and_count(c, btree_node_compact, trans, b);
16611674

16621675
n1 = bch2_btree_node_alloc_replacement(as, trans, b);
16631676

16641677
if (keys) {
1665-
btree_split_insert_keys(as, trans, path, n1, keys);
1678+
ret = btree_split_insert_keys(as, trans, path, n1, keys);
1679+
if (ret)
1680+
goto err;
16661681
BUG_ON(!bch2_keylist_empty(keys));
16671682
}
16681683

@@ -1809,15 +1824,15 @@ static int bch2_btree_insert_node(struct btree_update *as, struct btree_trans *t
18091824
goto split;
18101825
}
18111826

1812-
ret = bch2_btree_node_check_topology(trans, b);
1827+
1828+
ret = bch2_btree_node_check_topology(trans, b) ?:
1829+
bch2_btree_insert_keys_interior(as, trans, path, b,
1830+
path->l[b->c.level].iter, keys);
18131831
if (ret) {
18141832
bch2_btree_node_unlock_write(trans, path, b);
18151833
return ret;
18161834
}
18171835

1818-
bch2_btree_insert_keys_interior(as, trans, path, b,
1819-
path->l[b->c.level].iter, keys);
1820-
18211836
trans_for_each_path_with_node(trans, b, linked, i)
18221837
bch2_btree_node_iter_peek(&linked->l[b->c.level].iter, b);
18231838

fs/bcachefs/buckets.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,13 @@ static int bch2_trigger_pointer(struct btree_trans *trans,
604604
}
605605

606606
struct bpos bucket = PTR_BUCKET_POS(ca, &p.ptr);
607+
if (!bucket_valid(ca, bucket.offset)) {
608+
if (insert) {
609+
bch2_dev_bucket_missing(ca, bucket.offset);
610+
ret = -BCH_ERR_trigger_pointer;
611+
}
612+
goto err;
613+
}
607614

608615
if (flags & BTREE_TRIGGER_transactional) {
609616
struct bkey_i_alloc_v4 *a = bch2_trans_start_alloc_update(trans, bucket, 0);
@@ -1307,13 +1314,11 @@ int bch2_dev_buckets_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets)
13071314
old_bucket_gens = rcu_dereference_protected(ca->bucket_gens, 1);
13081315

13091316
if (resize) {
1310-
bucket_gens->nbuckets = min(bucket_gens->nbuckets,
1311-
old_bucket_gens->nbuckets);
1312-
bucket_gens->nbuckets_minus_first =
1313-
bucket_gens->nbuckets - bucket_gens->first_bucket;
1317+
u64 copy = min(bucket_gens->nbuckets,
1318+
old_bucket_gens->nbuckets);
13141319
memcpy(bucket_gens->b,
13151320
old_bucket_gens->b,
1316-
bucket_gens->nbuckets);
1321+
sizeof(bucket_gens->b[0]) * copy);
13171322
}
13181323

13191324
rcu_assign_pointer(ca->bucket_gens, bucket_gens);

fs/bcachefs/dirent.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,7 @@ static int bch2_dir_emit(struct dir_context *ctx, struct bkey_s_c_dirent d, subv
685685
vfs_d_type(d.v->d_type));
686686
if (ret)
687687
ctx->pos = d.k->p.offset + 1;
688-
return ret;
688+
return !ret;
689689
}
690690

691691
int bch2_readdir(struct bch_fs *c, subvol_inum inum, struct dir_context *ctx)
@@ -710,7 +710,7 @@ int bch2_readdir(struct bch_fs *c, subvol_inum inum, struct dir_context *ctx)
710710
if (ret2 > 0)
711711
continue;
712712

713-
ret2 ?: drop_locks_do(trans, bch2_dir_emit(ctx, dirent, target));
713+
ret2 ?: (bch2_trans_unlock(trans), bch2_dir_emit(ctx, dirent, target));
714714
})));
715715

716716
bch2_bkey_buf_exit(&sk, c);

fs/bcachefs/disk_groups.c

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -470,23 +470,22 @@ void bch2_disk_path_to_text_sb(struct printbuf *out, struct bch_sb *sb, unsigned
470470

471471
int __bch2_dev_group_set(struct bch_fs *c, struct bch_dev *ca, const char *name)
472472
{
473-
struct bch_member *mi;
474-
int ret, v = -1;
473+
lockdep_assert_held(&c->sb_lock);
475474

476-
if (!strlen(name) || !strcmp(name, "none"))
477-
return 0;
478475

479-
v = bch2_disk_path_find_or_create(&c->disk_sb, name);
480-
if (v < 0)
481-
return v;
476+
if (!strlen(name) || !strcmp(name, "none")) {
477+
struct bch_member *mi = bch2_members_v2_get_mut(c->disk_sb.sb, ca->dev_idx);
478+
SET_BCH_MEMBER_GROUP(mi, 0);
479+
} else {
480+
int v = bch2_disk_path_find_or_create(&c->disk_sb, name);
481+
if (v < 0)
482+
return v;
482483

483-
ret = bch2_sb_disk_groups_to_cpu(c);
484-
if (ret)
485-
return ret;
484+
struct bch_member *mi = bch2_members_v2_get_mut(c->disk_sb.sb, ca->dev_idx);
485+
SET_BCH_MEMBER_GROUP(mi, v + 1);
486+
}
486487

487-
mi = bch2_members_v2_get_mut(c->disk_sb.sb, ca->dev_idx);
488-
SET_BCH_MEMBER_GROUP(mi, v + 1);
489-
return 0;
488+
return bch2_sb_disk_groups_to_cpu(c);
490489
}
491490

492491
int bch2_dev_group_set(struct bch_fs *c, struct bch_dev *ca, const char *name)

fs/bcachefs/ec.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2204,10 +2204,10 @@ void bch2_fs_ec_stop(struct bch_fs *c)
22042204

22052205
static bool bch2_fs_ec_flush_done(struct bch_fs *c)
22062206
{
2207-
bool ret;
2207+
sched_annotate_sleep();
22082208

22092209
mutex_lock(&c->ec_stripe_new_lock);
2210-
ret = list_empty(&c->ec_stripe_new_list);
2210+
bool ret = list_empty(&c->ec_stripe_new_list);
22112211
mutex_unlock(&c->ec_stripe_new_lock);
22122212

22132213
return ret;

fs/bcachefs/error.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,9 @@ int __bch2_fsck_err(struct bch_fs *c,
478478
} else if (!test_bit(BCH_FS_fsck_running, &c->flags)) {
479479
if (c->opts.errors != BCH_ON_ERROR_continue ||
480480
!(flags & (FSCK_CAN_FIX|FSCK_CAN_IGNORE))) {
481-
prt_str(out, ", shutting down");
481+
prt_str_indented(out, ", shutting down\n"
482+
"error not marked as autofix and not in fsck\n"
483+
"run fsck, and forward to devs so error can be marked for self-healing");
482484
inconsistent = true;
483485
print = true;
484486
ret = -BCH_ERR_fsck_errors_not_fixed;

fs/bcachefs/fs-io.c

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -144,10 +144,25 @@ int __must_check bch2_write_inode_size(struct bch_fs *c,
144144
void __bch2_i_sectors_acct(struct bch_fs *c, struct bch_inode_info *inode,
145145
struct quota_res *quota_res, s64 sectors)
146146
{
147-
bch2_fs_inconsistent_on((s64) inode->v.i_blocks + sectors < 0, c,
148-
"inode %lu i_blocks underflow: %llu + %lli < 0 (ondisk %lli)",
149-
inode->v.i_ino, (u64) inode->v.i_blocks, sectors,
150-
inode->ei_inode.bi_sectors);
147+
if (unlikely((s64) inode->v.i_blocks + sectors < 0)) {
148+
struct printbuf buf = PRINTBUF;
149+
bch2_log_msg_start(c, &buf);
150+
prt_printf(&buf, "inode %lu i_blocks underflow: %llu + %lli < 0 (ondisk %lli)",
151+
inode->v.i_ino, (u64) inode->v.i_blocks, sectors,
152+
inode->ei_inode.bi_sectors);
153+
154+
bool repeat = false, print = false, suppress = false;
155+
bch2_count_fsck_err(c, vfs_inode_i_blocks_underflow, buf.buf, &repeat, &print, &suppress);
156+
if (print)
157+
bch2_print_str(c, buf.buf);
158+
printbuf_exit(&buf);
159+
160+
if (sectors < 0)
161+
sectors = -inode->v.i_blocks;
162+
else
163+
sectors = 0;
164+
}
165+
151166
inode->v.i_blocks += sectors;
152167

153168
#ifdef CONFIG_BCACHEFS_QUOTA
@@ -502,11 +517,22 @@ int bchfs_truncate(struct mnt_idmap *idmap,
502517
goto err;
503518
}
504519

505-
bch2_fs_inconsistent_on(!inode->v.i_size && inode->v.i_blocks &&
506-
!bch2_journal_error(&c->journal), c,
507-
"inode %lu truncated to 0 but i_blocks %llu (ondisk %lli)",
508-
inode->v.i_ino, (u64) inode->v.i_blocks,
509-
inode->ei_inode.bi_sectors);
520+
if (unlikely(!inode->v.i_size && inode->v.i_blocks &&
521+
!bch2_journal_error(&c->journal))) {
522+
struct printbuf buf = PRINTBUF;
523+
bch2_log_msg_start(c, &buf);
524+
prt_printf(&buf,
525+
"inode %lu truncated to 0 but i_blocks %llu (ondisk %lli)",
526+
inode->v.i_ino, (u64) inode->v.i_blocks,
527+
inode->ei_inode.bi_sectors);
528+
529+
bool repeat = false, print = false, suppress = false;
530+
bch2_count_fsck_err(c, vfs_inode_i_blocks_not_zero_at_truncate, buf.buf,
531+
&repeat, &print, &suppress);
532+
if (print)
533+
bch2_print_str(c, buf.buf);
534+
printbuf_exit(&buf);
535+
}
510536

511537
ret = bch2_setattr_nonsize(idmap, inode, iattr);
512538
err:

fs/bcachefs/fs.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ static inline void bch2_inode_flags_to_vfs(struct bch_fs *c, struct bch_inode_in
6666

6767
if (bch2_inode_casefold(c, &inode->ei_inode))
6868
inode->v.i_flags |= S_CASEFOLD;
69+
else
70+
inode->v.i_flags &= ~S_CASEFOLD;
6971
}
7072

7173
void bch2_inode_update_after_write(struct btree_trans *trans,
@@ -848,10 +850,8 @@ int __bch2_unlink(struct inode *vdir, struct dentry *dentry,
848850
set_nlink(&inode->v, 0);
849851
}
850852

851-
if (IS_CASEFOLDED(vdir)) {
853+
if (IS_CASEFOLDED(vdir))
852854
d_invalidate(dentry);
853-
d_prune_aliases(&inode->v);
854-
}
855855
err:
856856
bch2_trans_put(trans);
857857
bch2_unlock_inodes(INODE_UPDATE_LOCK, dir, inode);
@@ -1464,8 +1464,8 @@ static int bch2_next_fiemap_extent(struct btree_trans *trans,
14641464
unsigned sectors = cur->kbuf.k->k.size;
14651465
s64 offset_into_extent = 0;
14661466
enum btree_id data_btree = BTREE_ID_extents;
1467-
int ret = bch2_read_indirect_extent(trans, &data_btree, &offset_into_extent,
1468-
&cur->kbuf);
1467+
ret = bch2_read_indirect_extent(trans, &data_btree, &offset_into_extent,
1468+
&cur->kbuf);
14691469
if (ret)
14701470
goto err;
14711471

@@ -2571,6 +2571,11 @@ static int bch2_fs_get_tree(struct fs_context *fc)
25712571
if (ret)
25722572
goto err_put_super;
25732573

2574+
#ifdef CONFIG_UNICODE
2575+
sb->s_encoding = c->cf_encoding;
2576+
#endif
2577+
generic_set_sb_d_ops(sb);
2578+
25742579
vinode = bch2_vfs_inode_get(c, BCACHEFS_ROOT_SUBVOL_INUM);
25752580
ret = PTR_ERR_OR_ZERO(vinode);
25762581
bch_err_msg(c, ret, "mounting: error getting root inode");

0 commit comments

Comments
 (0)