Skip to content

Commit 94426e4

Browse files
author
Kent Overstreet
committed
bcachefs: opts.casefold_disabled
Add an option for completely disabling casefolding on a filesystem, as a workaround for overlayfs. This should only be needed as a temporary workaround, until the overlayfs fix arrives. Signed-off-by: Kent Overstreet <[email protected]>
1 parent c6e8d51 commit 94426e4

File tree

10 files changed

+55
-43
lines changed

10 files changed

+55
-43
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/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: 0 additions & 2 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);

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/str_hash.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ static int bch2_fsck_rename_dirent(struct btree_trans *trans,
3838
struct bkey_s_c_dirent old,
3939
bool *updated_before_k_pos)
4040
{
41+
struct bch_fs *c = trans->c;
4142
struct qstr old_name = bch2_dirent_get_name(old);
4243
struct bkey_i_dirent *new = bch2_trans_kmalloc(trans, BKEY_U64s_MAX * sizeof(u64));
4344
int ret = PTR_ERR_OR_ZERO(new);
@@ -60,7 +61,7 @@ static int bch2_fsck_rename_dirent(struct btree_trans *trans,
6061
sprintf(renamed_buf, "%.*s.fsck_renamed-%u",
6162
old_name.len, old_name.name, i));
6263

63-
ret = bch2_dirent_init_name(new, hash_info, &renamed_name, NULL);
64+
ret = bch2_dirent_init_name(c, new, hash_info, &renamed_name, NULL);
6465
if (ret)
6566
return ret;
6667

@@ -79,7 +80,7 @@ static int bch2_fsck_rename_dirent(struct btree_trans *trans,
7980
}
8081

8182
ret = ret ?: bch2_fsck_update_backpointers(trans, s, desc, hash_info, &new->k_i);
82-
bch_err_fn(trans->c, ret);
83+
bch_err_fn(c, ret);
8384
return ret;
8485
}
8586

fs/bcachefs/str_hash.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,7 @@ bch2_hash_info_init(struct bch_fs *c, const struct bch_inode_unpacked *bi)
4848
struct bch_hash_info info = {
4949
.inum_snapshot = bi->bi_snapshot,
5050
.type = INODE_STR_HASH(bi),
51-
#ifdef CONFIG_UNICODE
5251
.cf_encoding = bch2_inode_casefold(c, bi) ? c->cf_encoding : NULL,
53-
#endif
5452
.siphash_key = { .k0 = bi->bi_hash_seed }
5553
};
5654

fs/bcachefs/super.c

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,15 +1025,17 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts *opts,
10251025
}
10261026

10271027
#ifdef CONFIG_UNICODE
1028-
/* Default encoding until we can potentially have more as an option. */
1029-
c->cf_encoding = utf8_load(BCH_FS_DEFAULT_UTF8_ENCODING);
1030-
if (IS_ERR(c->cf_encoding)) {
1031-
printk(KERN_ERR "Cannot load UTF-8 encoding for filesystem. Version: %u.%u.%u",
1032-
unicode_major(BCH_FS_DEFAULT_UTF8_ENCODING),
1033-
unicode_minor(BCH_FS_DEFAULT_UTF8_ENCODING),
1034-
unicode_rev(BCH_FS_DEFAULT_UTF8_ENCODING));
1035-
ret = -EINVAL;
1036-
goto err;
1028+
if (bch2_fs_casefold_enabled(c)) {
1029+
/* Default encoding until we can potentially have more as an option. */
1030+
c->cf_encoding = utf8_load(BCH_FS_DEFAULT_UTF8_ENCODING);
1031+
if (IS_ERR(c->cf_encoding)) {
1032+
printk(KERN_ERR "Cannot load UTF-8 encoding for filesystem. Version: %u.%u.%u",
1033+
unicode_major(BCH_FS_DEFAULT_UTF8_ENCODING),
1034+
unicode_minor(BCH_FS_DEFAULT_UTF8_ENCODING),
1035+
unicode_rev(BCH_FS_DEFAULT_UTF8_ENCODING));
1036+
ret = -EINVAL;
1037+
goto err;
1038+
}
10371039
}
10381040
#else
10391041
if (c->sb.features & BIT_ULL(BCH_FEATURE_casefolding)) {
@@ -1160,12 +1162,11 @@ int bch2_fs_start(struct bch_fs *c)
11601162

11611163
print_mount_opts(c);
11621164

1163-
#ifdef CONFIG_UNICODE
1164-
bch_info(c, "Using encoding defined by superblock: utf8-%u.%u.%u",
1165-
unicode_major(BCH_FS_DEFAULT_UTF8_ENCODING),
1166-
unicode_minor(BCH_FS_DEFAULT_UTF8_ENCODING),
1167-
unicode_rev(BCH_FS_DEFAULT_UTF8_ENCODING));
1168-
#endif
1165+
if (c->cf_encoding)
1166+
bch_info(c, "Using encoding defined by superblock: utf8-%u.%u.%u",
1167+
unicode_major(BCH_FS_DEFAULT_UTF8_ENCODING),
1168+
unicode_minor(BCH_FS_DEFAULT_UTF8_ENCODING),
1169+
unicode_rev(BCH_FS_DEFAULT_UTF8_ENCODING));
11691170

11701171
if (!bch2_fs_may_start(c))
11711172
return bch_err_throw(c, insufficient_devices_to_start);

0 commit comments

Comments
 (0)