mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-02-16 21:15:10 -05:00
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:
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user