With the possibility of partially encrypted directories, lookup needs to try both the unencrypted and encrypted names. Signed-off-by: Sweet Tea Dorminy <sweettea-kernel@xxxxxxxxxx> --- fs/btrfs/dir-item.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/fs/btrfs/dir-item.c b/fs/btrfs/dir-item.c index d49bc19b91da..dc95ac987006 100644 --- a/fs/btrfs/dir-item.c +++ b/fs/btrfs/dir-item.c @@ -469,21 +469,40 @@ struct btrfs_dir_item *btrfs_match_dir_item_fname(struct btrfs_fs_info *fs_info, u32 cur = 0; u32 this_len; struct extent_buffer *leaf; + bool encrypted = (name->crypto_buf.name != NULL); + struct fscrypt_name unencrypted_name; + + if (encrypted) { + unencrypted_name = (struct fscrypt_name){ + .usr_fname = name->usr_fname, + .disk_name = { + .name = (unsigned char *)name->usr_fname->name, + .len = name->usr_fname->len, + }, + }; + } leaf = path->nodes[0]; dir_item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_dir_item); total_len = btrfs_item_size(leaf, path->slots[0]); while (cur < total_len) { - this_len = sizeof(*dir_item) + - btrfs_dir_name_len(leaf, dir_item) + + u64 dir_name_len = btrfs_dir_name_len(leaf, dir_item); + + this_len = sizeof(*dir_item) + dir_name_len + btrfs_dir_data_len(leaf, dir_item); name_ptr = (unsigned long)(dir_item + 1); if (btrfs_fscrypt_match_name(name, leaf, name_ptr, - btrfs_dir_name_len(leaf, dir_item))) + dir_name_len)) return dir_item; + if (encrypted && + btrfs_fscrypt_match_name(&unencrypted_name, leaf, + name_ptr, dir_name_len)) { + return dir_item; + } + cur += this_len; dir_item = (struct btrfs_dir_item *)((char *)dir_item + this_len); -- 2.35.1