mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-03-04 09:58:26 -05:00
bcachefs: Fix bch2_dirent_create_snapshot() for casefolding
bch2_dirent_create_snapshot(), used in fsck, neglected to create a casefolded dirent. Just move this into dirent_create_key(). Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
@@ -288,6 +288,7 @@ static void dirent_init_casefolded_name(struct bkey_i_dirent *dirent,
|
||||
}
|
||||
|
||||
static struct bkey_i_dirent *dirent_create_key(struct btree_trans *trans,
|
||||
const struct bch_hash_info *hash_info,
|
||||
subvol_inum dir,
|
||||
u8 type,
|
||||
const struct qstr *name,
|
||||
@@ -295,10 +296,19 @@ static struct bkey_i_dirent *dirent_create_key(struct btree_trans *trans,
|
||||
u64 dst)
|
||||
{
|
||||
struct bkey_i_dirent *dirent;
|
||||
struct qstr _cf_name;
|
||||
|
||||
if (name->len > BCH_NAME_MAX)
|
||||
return ERR_PTR(-ENAMETOOLONG);
|
||||
|
||||
if (hash_info->cf_encoding && !cf_name) {
|
||||
int ret = bch2_casefold(trans, hash_info, name, &_cf_name);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
cf_name = &_cf_name;
|
||||
}
|
||||
|
||||
dirent = dirent_alloc_key(trans, dir, type, name->len, cf_name ? cf_name->len : 0, dst);
|
||||
if (IS_ERR(dirent))
|
||||
return dirent;
|
||||
@@ -324,7 +334,7 @@ int bch2_dirent_create_snapshot(struct btree_trans *trans,
|
||||
struct bkey_i_dirent *dirent;
|
||||
int ret;
|
||||
|
||||
dirent = dirent_create_key(trans, dir_inum, type, name, NULL, dst_inum);
|
||||
dirent = dirent_create_key(trans, hash_info, dir_inum, type, name, NULL, dst_inum);
|
||||
ret = PTR_ERR_OR_ZERO(dirent);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -333,8 +343,7 @@ int bch2_dirent_create_snapshot(struct btree_trans *trans,
|
||||
dirent->k.p.snapshot = snapshot;
|
||||
|
||||
ret = bch2_hash_set_in_snapshot(trans, bch2_dirent_hash_desc, hash_info,
|
||||
dir_inum, snapshot, &dirent->k_i,
|
||||
flags|BTREE_UPDATE_internal_snapshot_node);
|
||||
dir_inum, snapshot, &dirent->k_i, flags);
|
||||
*dir_offset = dirent->k.p.offset;
|
||||
|
||||
return ret;
|
||||
@@ -344,28 +353,16 @@ int bch2_dirent_create(struct btree_trans *trans, subvol_inum dir,
|
||||
const struct bch_hash_info *hash_info,
|
||||
u8 type, const struct qstr *name, u64 dst_inum,
|
||||
u64 *dir_offset,
|
||||
u64 *i_size,
|
||||
enum btree_iter_update_trigger_flags flags)
|
||||
{
|
||||
struct bkey_i_dirent *dirent;
|
||||
int ret;
|
||||
|
||||
if (hash_info->cf_encoding) {
|
||||
struct qstr cf_name;
|
||||
ret = bch2_casefold(trans, hash_info, name, &cf_name);
|
||||
if (ret)
|
||||
return ret;
|
||||
dirent = dirent_create_key(trans, dir, type, name, &cf_name, dst_inum);
|
||||
} else {
|
||||
dirent = dirent_create_key(trans, dir, type, name, NULL, dst_inum);
|
||||
}
|
||||
|
||||
dirent = dirent_create_key(trans, hash_info, dir, type, name, NULL, dst_inum);
|
||||
ret = PTR_ERR_OR_ZERO(dirent);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
*i_size += bkey_bytes(&dirent->k);
|
||||
|
||||
ret = bch2_hash_set(trans, bch2_dirent_hash_desc, hash_info,
|
||||
dir, &dirent->k_i, flags);
|
||||
*dir_offset = dirent->k.p.offset;
|
||||
@@ -466,7 +463,7 @@ int bch2_dirent_rename(struct btree_trans *trans,
|
||||
*src_offset = dst_iter.pos.offset;
|
||||
|
||||
/* Create new dst key: */
|
||||
new_dst = dirent_create_key(trans, dst_dir, 0, dst_name,
|
||||
new_dst = dirent_create_key(trans, dst_hash, dst_dir, 0, dst_name,
|
||||
dst_hash->cf_encoding ? &dst_name_lookup : NULL, 0);
|
||||
ret = PTR_ERR_OR_ZERO(new_dst);
|
||||
if (ret)
|
||||
@@ -477,7 +474,7 @@ int bch2_dirent_rename(struct btree_trans *trans,
|
||||
|
||||
/* Create new src key: */
|
||||
if (mode == BCH_RENAME_EXCHANGE) {
|
||||
new_src = dirent_create_key(trans, src_dir, 0, src_name,
|
||||
new_src = dirent_create_key(trans, src_hash, src_dir, 0, src_name,
|
||||
src_hash->cf_encoding ? &src_name_lookup : NULL, 0);
|
||||
ret = PTR_ERR_OR_ZERO(new_src);
|
||||
if (ret)
|
||||
|
||||
@@ -65,7 +65,7 @@ int bch2_dirent_create_snapshot(struct btree_trans *, u32, u64, u32,
|
||||
enum btree_iter_update_trigger_flags);
|
||||
int bch2_dirent_create(struct btree_trans *, subvol_inum,
|
||||
const struct bch_hash_info *, u8,
|
||||
const struct qstr *, u64, u64 *, u64 *,
|
||||
const struct qstr *, u64, u64 *,
|
||||
enum btree_iter_update_trigger_flags);
|
||||
|
||||
static inline unsigned vfs_d_type(unsigned type)
|
||||
|
||||
@@ -306,6 +306,7 @@ static int lookup_lostfound(struct btree_trans *trans, u32 snapshot,
|
||||
&lostfound_str,
|
||||
lostfound->bi_inum,
|
||||
&lostfound->bi_dir_offset,
|
||||
BTREE_UPDATE_internal_snapshot_node|
|
||||
STR_HASH_must_create) ?:
|
||||
bch2_inode_write_flags(trans, &lostfound_iter, lostfound,
|
||||
BTREE_UPDATE_internal_snapshot_node);
|
||||
@@ -431,6 +432,7 @@ static int reattach_inode(struct btree_trans *trans, struct bch_inode_unpacked *
|
||||
&name,
|
||||
inode->bi_subvol ?: inode->bi_inum,
|
||||
&inode->bi_dir_offset,
|
||||
BTREE_UPDATE_internal_snapshot_node|
|
||||
STR_HASH_must_create);
|
||||
if (ret) {
|
||||
bch_err_msg(c, ret, "error creating dirent");
|
||||
|
||||
@@ -158,7 +158,6 @@ int bch2_create_trans(struct btree_trans *trans,
|
||||
name,
|
||||
dir_target,
|
||||
&dir_offset,
|
||||
&dir_u->bi_size,
|
||||
STR_HASH_must_create|BTREE_ITER_with_updates) ?:
|
||||
bch2_inode_write(trans, &dir_iter, dir_u);
|
||||
if (ret)
|
||||
@@ -225,7 +224,6 @@ int bch2_link_trans(struct btree_trans *trans,
|
||||
mode_to_type(inode_u->bi_mode),
|
||||
name, inum.inum,
|
||||
&dir_offset,
|
||||
&dir_u->bi_size,
|
||||
STR_HASH_must_create);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
Reference in New Issue
Block a user