Skip to content

Commit 482deed

Browse files
committed
Merge tag 'bcachefs-2025-07-03' of git://evilpiepirate.org/bcachefs
Pull bcachefs fixes from Kent Overstreet: "The 'opts.casefold_disabled' patch is non critical, but would be a 6.15 backport; it's to address the casefolding + overlayfs incompatibility that was discovvered late. It's late because I was hoping that this would be addressed on the overlayfs side (and will be in 6.17), but user reports keep coming in on this one (lots of people are using docker these days)" * tag 'bcachefs-2025-07-03' of git://evilpiepirate.org/bcachefs: bcachefs: opts.casefold_disabled bcachefs: Work around deadlock to btree node rewrites in journal replay bcachefs: Fix incorrect transaction restart handling bcachefs: fix btree_trans_peek_prev_journal() bcachefs: mark invalid_btree_id autofix
2 parents 2eb7f03 + 94426e4 commit 482deed

File tree

13 files changed

+93
-54
lines changed

13 files changed

+93
-54
lines changed

fs/bcachefs/bcachefs.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -863,9 +863,7 @@ struct bch_fs {
863863
DARRAY(enum bcachefs_metadata_version)
864864
incompat_versions_requested;
865865

866-
#ifdef CONFIG_UNICODE
867866
struct unicode_map *cf_encoding;
868-
#endif
869867

870868
struct bch_sb_handle disk_sb;
871869

@@ -1285,4 +1283,13 @@ static inline bool bch2_discard_opt_enabled(struct bch_fs *c, struct bch_dev *ca
12851283
: ca->mi.discard;
12861284
}
12871285

1286+
static inline bool bch2_fs_casefold_enabled(struct bch_fs *c)
1287+
{
1288+
#ifdef CONFIG_UNICODE
1289+
return !c->opts.casefold_disabled;
1290+
#else
1291+
return false;
1292+
#endif
1293+
}
1294+
12881295
#endif /* _BCACHEFS_H */

fs/bcachefs/btree_io.c

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1337,15 +1337,42 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct bch_dev *ca,
13371337

13381338
btree_node_reset_sib_u64s(b);
13391339

1340-
scoped_guard(rcu)
1341-
bkey_for_each_ptr(bch2_bkey_ptrs(bkey_i_to_s(&b->key)), ptr) {
1342-
struct bch_dev *ca2 = bch2_dev_rcu(c, ptr->dev);
1343-
1344-
if (!ca2 || ca2->mi.state != BCH_MEMBER_STATE_rw) {
1345-
set_btree_node_need_rewrite(b);
1346-
set_btree_node_need_rewrite_degraded(b);
1340+
/*
1341+
* XXX:
1342+
*
1343+
* We deadlock if too many btree updates require node rewrites while
1344+
* we're still in journal replay.
1345+
*
1346+
* This is because btree node rewrites generate more updates for the
1347+
* interior updates (alloc, backpointers), and if those updates touch
1348+
* new nodes and generate more rewrites - well, you see the problem.
1349+
*
1350+
* The biggest cause is that we don't use the btree write buffer (for
1351+
* the backpointer updates - this needs some real thought on locking in
1352+
* order to fix.
1353+
*
1354+
* The problem with this workaround (not doing the rewrite for degraded
1355+
* nodes in journal replay) is that those degraded nodes persist, and we
1356+
* don't want that (this is a real bug when a btree node write completes
1357+
* with fewer replicas than we wanted and leaves a degraded node due to
1358+
* device _removal_, i.e. the device went away mid write).
1359+
*
1360+
* It's less of a bug here, but still a problem because we don't yet
1361+
* have a way of tracking degraded data - we another index (all
1362+
* extents/btree nodes, by replicas entry) in order to fix properly
1363+
* (re-replicate degraded data at the earliest possible time).
1364+
*/
1365+
if (c->recovery.passes_complete & BIT_ULL(BCH_RECOVERY_PASS_journal_replay)) {
1366+
scoped_guard(rcu)
1367+
bkey_for_each_ptr(bch2_bkey_ptrs(bkey_i_to_s(&b->key)), ptr) {
1368+
struct bch_dev *ca2 = bch2_dev_rcu(c, ptr->dev);
1369+
1370+
if (!ca2 || ca2->mi.state != BCH_MEMBER_STATE_rw) {
1371+
set_btree_node_need_rewrite(b);
1372+
set_btree_node_need_rewrite_degraded(b);
1373+
}
13471374
}
1348-
}
1375+
}
13491376

13501377
if (!ptr_written) {
13511378
set_btree_node_need_rewrite(b);

fs/bcachefs/btree_iter.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2189,7 +2189,7 @@ void btree_trans_peek_prev_journal(struct btree_trans *trans,
21892189
struct btree_path *path = btree_iter_path(trans, iter);
21902190
struct bkey_i *next_journal =
21912191
bch2_btree_journal_peek_prev(trans, iter, search_key,
2192-
k->k ? k->k->p : path_l(path)->b->key.k.p);
2192+
k->k ? k->k->p : path_l(path)->b->data->min_key);
21932193

21942194
if (next_journal) {
21952195
iter->k = next_journal->k;

fs/bcachefs/dirent.c

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ int bch2_casefold(struct btree_trans *trans, const struct bch_hash_info *info,
1818
{
1919
*out_cf = (struct qstr) QSTR_INIT(NULL, 0);
2020

21-
#ifdef CONFIG_UNICODE
21+
if (!bch2_fs_casefold_enabled(trans->c))
22+
return -EOPNOTSUPP;
23+
2224
unsigned char *buf = bch2_trans_kmalloc(trans, BCH_NAME_MAX + 1);
2325
int ret = PTR_ERR_OR_ZERO(buf);
2426
if (ret)
@@ -30,9 +32,6 @@ int bch2_casefold(struct btree_trans *trans, const struct bch_hash_info *info,
3032

3133
*out_cf = (struct qstr) QSTR_INIT(buf, ret);
3234
return 0;
33-
#else
34-
return -EOPNOTSUPP;
35-
#endif
3635
}
3736

3837
static unsigned bch2_dirent_name_bytes(struct bkey_s_c_dirent d)
@@ -231,7 +230,8 @@ void bch2_dirent_to_text(struct printbuf *out, struct bch_fs *c, struct bkey_s_c
231230
prt_printf(out, " type %s", bch2_d_type_str(d.v->d_type));
232231
}
233232

234-
int bch2_dirent_init_name(struct bkey_i_dirent *dirent,
233+
int bch2_dirent_init_name(struct bch_fs *c,
234+
struct bkey_i_dirent *dirent,
235235
const struct bch_hash_info *hash_info,
236236
const struct qstr *name,
237237
const struct qstr *cf_name)
@@ -251,7 +251,9 @@ int bch2_dirent_init_name(struct bkey_i_dirent *dirent,
251251
offsetof(struct bch_dirent, d_name) -
252252
name->len);
253253
} else {
254-
#ifdef CONFIG_UNICODE
254+
if (!bch2_fs_casefold_enabled(c))
255+
return -EOPNOTSUPP;
256+
255257
memcpy(&dirent->v.d_cf_name_block.d_names[0], name->name, name->len);
256258

257259
char *cf_out = &dirent->v.d_cf_name_block.d_names[name->len];
@@ -277,9 +279,6 @@ int bch2_dirent_init_name(struct bkey_i_dirent *dirent,
277279
dirent->v.d_cf_name_block.d_cf_name_len = cpu_to_le16(cf_len);
278280

279281
EBUG_ON(bch2_dirent_get_casefold_name(dirent_i_to_s_c(dirent)).len != cf_len);
280-
#else
281-
return -EOPNOTSUPP;
282-
#endif
283282
}
284283

285284
unsigned u64s = dirent_val_u64s(name->len, cf_len);
@@ -313,7 +312,7 @@ struct bkey_i_dirent *bch2_dirent_create_key(struct btree_trans *trans,
313312
dirent->v.d_type = type;
314313
dirent->v.d_unused = 0;
315314

316-
int ret = bch2_dirent_init_name(dirent, hash_info, name, cf_name);
315+
int ret = bch2_dirent_init_name(trans->c, dirent, hash_info, name, cf_name);
317316
if (ret)
318317
return ERR_PTR(ret);
319318

fs/bcachefs/dirent.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ static inline void dirent_copy_target(struct bkey_i_dirent *dst,
5959
dst->v.d_type = src.v->d_type;
6060
}
6161

62-
int bch2_dirent_init_name(struct bkey_i_dirent *,
62+
int bch2_dirent_init_name(struct bch_fs *,
63+
struct bkey_i_dirent *,
6364
const struct bch_hash_info *,
6465
const struct qstr *,
6566
const struct qstr *);

fs/bcachefs/fs.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -722,7 +722,6 @@ static struct dentry *bch2_lookup(struct inode *vdir, struct dentry *dentry,
722722
if (IS_ERR(inode))
723723
inode = NULL;
724724

725-
#ifdef CONFIG_UNICODE
726725
if (!inode && IS_CASEFOLDED(vdir)) {
727726
/*
728727
* Do not cache a negative dentry in casefolded directories
@@ -737,7 +736,6 @@ static struct dentry *bch2_lookup(struct inode *vdir, struct dentry *dentry,
737736
*/
738737
return NULL;
739738
}
740-
#endif
741739

742740
return d_splice_alias(&inode->v, dentry);
743741
}
@@ -2566,9 +2564,10 @@ static int bch2_fs_get_tree(struct fs_context *fc)
25662564
sb->s_shrink->seeks = 0;
25672565

25682566
#ifdef CONFIG_UNICODE
2569-
sb->s_encoding = c->cf_encoding;
2570-
#endif
2567+
if (bch2_fs_casefold_enabled(c))
2568+
sb->s_encoding = c->cf_encoding;
25712569
generic_set_sb_d_ops(sb);
2570+
#endif
25722571

25732572
vinode = bch2_vfs_inode_get(c, BCACHEFS_ROOT_SUBVOL_INUM);
25742573
ret = PTR_ERR_OR_ZERO(vinode);

fs/bcachefs/fsck.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2302,9 +2302,7 @@ static int check_dirent(struct btree_trans *trans, struct btree_iter *iter,
23022302
*hash_info = bch2_hash_info_init(c, &i->inode);
23032303
dir->first_this_inode = false;
23042304

2305-
#ifdef CONFIG_UNICODE
23062305
hash_info->cf_encoding = bch2_inode_casefold(c, &i->inode) ? c->cf_encoding : NULL;
2307-
#endif
23082306

23092307
ret = bch2_str_hash_check_key(trans, s, &bch2_dirent_hash_desc, hash_info,
23102308
iter, k, need_second_pass);
@@ -2819,7 +2817,7 @@ static int check_path_loop(struct btree_trans *trans, struct bkey_s_c inode_k)
28192817
ret = remove_backpointer(trans, &inode);
28202818
bch_err_msg(c, ret, "removing dirent");
28212819
if (ret)
2822-
break;
2820+
goto out;
28232821

28242822
ret = reattach_inode(trans, &inode);
28252823
bch_err_msg(c, ret, "reattaching inode %llu", inode.bi_inum);

fs/bcachefs/inode.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1265,7 +1265,14 @@ int bch2_inode_set_casefold(struct btree_trans *trans, subvol_inum inum,
12651265
{
12661266
struct bch_fs *c = trans->c;
12671267

1268-
#ifdef CONFIG_UNICODE
1268+
#ifndef CONFIG_UNICODE
1269+
bch_err(c, "Cannot use casefolding on a kernel without CONFIG_UNICODE");
1270+
return -EOPNOTSUPP;
1271+
#endif
1272+
1273+
if (c->opts.casefold_disabled)
1274+
return -EOPNOTSUPP;
1275+
12691276
int ret = 0;
12701277
/* Not supported on individual files. */
12711278
if (!S_ISDIR(bi->bi_mode))
@@ -1289,10 +1296,6 @@ int bch2_inode_set_casefold(struct btree_trans *trans, subvol_inum inum,
12891296
bi->bi_fields_set |= BIT(Inode_opt_casefold);
12901297

12911298
return bch2_maybe_propagate_has_case_insensitive(trans, inum, bi);
1292-
#else
1293-
bch_err(c, "Cannot use casefolding on a kernel without CONFIG_UNICODE");
1294-
return -EOPNOTSUPP;
1295-
#endif
12961299
}
12971300

12981301
static noinline int __bch2_inode_rm_snapshot(struct btree_trans *trans, u64 inum, u32 snapshot)

fs/bcachefs/opts.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,11 @@ enum fsck_err_opts {
234234
OPT_BOOL(), \
235235
BCH_SB_CASEFOLD, false, \
236236
NULL, "Dirent lookups are casefolded") \
237+
x(casefold_disabled, u8, \
238+
OPT_FS|OPT_MOUNT, \
239+
OPT_BOOL(), \
240+
BCH2_NO_SB_OPT, false, \
241+
NULL, "Disable casefolding filesystem wide") \
237242
x(inodes_32bit, u8, \
238243
OPT_FS|OPT_INODE|OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME, \
239244
OPT_BOOL(), \

fs/bcachefs/sb-errors_format.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ enum bch_fsck_flags {
314314
x(accounting_mismatch, 272, FSCK_AUTOFIX) \
315315
x(accounting_replicas_not_marked, 273, 0) \
316316
x(accounting_to_invalid_device, 289, 0) \
317-
x(invalid_btree_id, 274, 0) \
317+
x(invalid_btree_id, 274, FSCK_AUTOFIX) \
318318
x(alloc_key_io_time_bad, 275, 0) \
319319
x(alloc_key_fragmentation_lru_wrong, 276, FSCK_AUTOFIX) \
320320
x(accounting_key_junk_at_end, 277, FSCK_AUTOFIX) \

0 commit comments

Comments
 (0)