bcachefs: Fix bch2_fsck_rename_dirent() for casefold

bch2_fsck_renamed_dirent was creating bch_dirent keys open-coded - but
we need to use the appropriate helper, if the directory is casefolded.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
Kent Overstreet
2025-05-31 17:00:00 -04:00
parent 35c1f131bc
commit b938d3c970
3 changed files with 25 additions and 13 deletions

View File

@@ -2184,6 +2184,10 @@ static int check_dirent(struct btree_trans *trans, struct btree_iter *iter,
*hash_info = bch2_hash_info_init(c, &i->inode);
dir->first_this_inode = false;
#ifdef CONFIG_UNICODE
hash_info->cf_encoding = bch2_inode_casefold(c, &i->inode) ? c->cf_encoding : NULL;
#endif
ret = bch2_str_hash_check_key(trans, s, &bch2_dirent_hash_desc, hash_info,
iter, k, need_second_pass);
if (ret < 0)

View File

@@ -39,7 +39,7 @@ static noinline int fsck_rename_dirent(struct btree_trans *trans,
bool *updated_before_k_pos)
{
struct qstr old_name = bch2_dirent_get_name(old);
struct bkey_i_dirent *new = bch2_trans_kmalloc(trans, bkey_bytes(old.k) + 32);
struct bkey_i_dirent *new = bch2_trans_kmalloc(trans, BKEY_U64s_MAX * sizeof(u64));
int ret = PTR_ERR_OR_ZERO(new);
if (ret)
return ret;
@@ -48,20 +48,27 @@ static noinline int fsck_rename_dirent(struct btree_trans *trans,
dirent_copy_target(new, old);
new->k.p = old.k->p;
char *renamed_buf = bch2_trans_kmalloc(trans, old_name.len + 20);
ret = PTR_ERR_OR_ZERO(renamed_buf);
if (ret)
return ret;
for (unsigned i = 0; i < 1000; i++) {
unsigned len = sprintf(new->v.d_name, "%.*s.fsck_renamed-%u",
old_name.len, old_name.name, i);
unsigned u64s = BKEY_U64s + dirent_val_u64s(len, 0);
new->k.u64s = BKEY_U64s_MAX;
if (u64s > U8_MAX)
return -EINVAL;
struct qstr renamed_name = (struct qstr) QSTR_INIT(renamed_buf,
sprintf(renamed_buf, "%.*s.fsck_renamed-%u",
old_name.len, old_name.name, i));
new->k.u64s = u64s;
ret = bch2_dirent_init_name(new, hash_info, &renamed_name, NULL);
if (ret)
return ret;
ret = bch2_hash_set_in_snapshot(trans, bch2_dirent_hash_desc, hash_info,
(subvol_inum) { 0, old.k->p.inode },
old.k->p.snapshot, &new->k_i,
BTREE_UPDATE_internal_snapshot_node);
BTREE_UPDATE_internal_snapshot_node|
STR_HASH_must_create);
if (ret && !bch2_err_matches(ret, EEXIST))
break;
if (!ret) {

View File

@@ -1148,11 +1148,12 @@ int bch2_fs_start(struct bch_fs *c)
print_mount_opts(c);
if (IS_ENABLED(CONFIG_UNICODE))
bch_info(c, "Using encoding defined by superblock: utf8-%u.%u.%u",
unicode_major(BCH_FS_DEFAULT_UTF8_ENCODING),
unicode_minor(BCH_FS_DEFAULT_UTF8_ENCODING),
unicode_rev(BCH_FS_DEFAULT_UTF8_ENCODING));
#ifdef CONFIG_UNICODE
bch_info(c, "Using encoding defined by superblock: utf8-%u.%u.%u",
unicode_major(BCH_FS_DEFAULT_UTF8_ENCODING),
unicode_minor(BCH_FS_DEFAULT_UTF8_ENCODING),
unicode_rev(BCH_FS_DEFAULT_UTF8_ENCODING));
#endif
if (!bch2_fs_may_start(c))
return bch_err_throw(c, insufficient_devices_to_start);