LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
From: Daniel Rosenberg <drosen@google.com>
To: "Theodore Ts'o" <tytso@mit.edu>,
linux-ext4@vger.kernel.org, Jaegeuk Kim <jaegeuk@kernel.org>,
Chao Yu <chao@kernel.org>,
linux-f2fs-devel@lists.sourceforge.net,
Eric Biggers <ebiggers@kernel.org>,
linux-fscrypt@vger.kernel.org,
Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Andreas Dilger <adilger.kernel@dilger.ca>,
Jonathan Corbet <corbet@lwn.net>,
linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-fsdevel@vger.kernel.org,
Gabriel Krisman Bertazi <krisman@collabora.com>,
kernel-team@android.com, Daniel Rosenberg <drosen@google.com>
Subject: [PATCH v2 6/6] ext4: Optimize match for casefolded encrypted dirs
Date: Mon, 6 Jan 2020 21:16:38 -0800 [thread overview]
Message-ID: <20200107051638.40893-7-drosen@google.com> (raw)
In-Reply-To: <20200107051638.40893-1-drosen@google.com>
Matching names with casefolded encrypting directories requires
decrypting entries to confirm case since we are case preserving. We can
avoid needing to decrypt if our hash values don't match.
Signed-off-by: Daniel Rosenberg <drosen@google.com>
---
fs/ext4/ext4.h | 17 ++++++++-------
fs/ext4/namei.c | 55 ++++++++++++++++++++++++++-----------------------
2 files changed, 38 insertions(+), 34 deletions(-)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index f06bab489d372..f104c46a68950 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -2393,9 +2393,9 @@ extern unsigned ext4_free_clusters_after_init(struct super_block *sb,
ext4_fsblk_t ext4_inode_to_goal_block(struct inode *);
#ifdef CONFIG_UNICODE
-extern void ext4_fname_setup_ci_filename(struct inode *dir,
+extern int ext4_fname_setup_ci_filename(struct inode *dir,
const struct qstr *iname,
- struct fscrypt_str *fname);
+ struct ext4_filename *fname);
#endif
#ifdef CONFIG_FS_ENCRYPTION
@@ -2426,9 +2426,9 @@ static inline int ext4_fname_setup_filename(struct inode *dir,
ext4_fname_from_fscrypt_name(fname, &name);
#ifdef CONFIG_UNICODE
- ext4_fname_setup_ci_filename(dir, iname, &fname->cf_name);
+ err = ext4_fname_setup_ci_filename(dir, iname, fname);
#endif
- return 0;
+ return err;
}
static inline int ext4_fname_prepare_lookup(struct inode *dir,
@@ -2445,9 +2445,9 @@ static inline int ext4_fname_prepare_lookup(struct inode *dir,
ext4_fname_from_fscrypt_name(fname, &name);
#ifdef CONFIG_UNICODE
- ext4_fname_setup_ci_filename(dir, &dentry->d_name, &fname->cf_name);
+ err = ext4_fname_setup_ci_filename(dir, &dentry->d_name, fname);
#endif
- return 0;
+ return err;
}
static inline void ext4_fname_free_filename(struct ext4_filename *fname)
@@ -2472,15 +2472,16 @@ static inline int ext4_fname_setup_filename(struct inode *dir,
int lookup,
struct ext4_filename *fname)
{
+ int err = 0;
fname->usr_fname = iname;
fname->disk_name.name = (unsigned char *) iname->name;
fname->disk_name.len = iname->len;
#ifdef CONFIG_UNICODE
- ext4_fname_setup_ci_filename(dir, iname, &fname->cf_name);
+ err = ext4_fname_setup_ci_filename(dir, iname, fname);
#endif
- return 0;
+ return err;
}
static inline int ext4_fname_prepare_lookup(struct inode *dir,
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 42ed2e9d3a1f4..1357d82d27395 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -784,7 +784,9 @@ dx_probe(struct ext4_filename *fname, struct inode *dir,
if (hinfo->hash_version <= DX_HASH_TEA)
hinfo->hash_version += EXT4_SB(dir->i_sb)->s_hash_unsigned;
hinfo->seed = EXT4_SB(dir->i_sb)->s_hash_seed;
- if (fname && fname_name(fname))
+ /* hash is already computed for encrypted casefolded directory */
+ if (fname && fname_name(fname) &&
+ !(IS_ENCRYPTED(dir) && IS_CASEFOLDED(dir)))
ext4fs_dirhash(dir, fname_name(fname), fname_len(fname), hinfo);
hash = hinfo->hash;
@@ -1352,19 +1354,21 @@ int ext4_ci_compare(struct inode *parent, const struct qstr *name,
return ret;
}
-void ext4_fname_setup_ci_filename(struct inode *dir, const struct qstr *iname,
- struct fscrypt_str *cf_name)
+int ext4_fname_setup_ci_filename(struct inode *dir, const struct qstr *iname,
+ struct ext4_filename *name)
{
+ struct fscrypt_str *cf_name = &name->cf_name;
+ struct dx_hash_info *hinfo = &name->hinfo;
int len;
if (!needs_casefold(dir)) {
cf_name->name = NULL;
- return;
+ return 0;
}
cf_name->name = kmalloc(EXT4_NAME_LEN, GFP_NOFS);
if (!cf_name->name)
- return;
+ return -ENOMEM;
len = utf8_casefold(dir->i_sb->s_encoding,
iname, cf_name->name,
@@ -1372,10 +1376,18 @@ void ext4_fname_setup_ci_filename(struct inode *dir, const struct qstr *iname,
if (len <= 0) {
kfree(cf_name->name);
cf_name->name = NULL;
- return;
}
cf_name->len = (unsigned) len;
+ if (!IS_ENCRYPTED(dir))
+ return 0;
+ hinfo->hash_version = DX_HASH_SIPHASH;
+ hinfo->seed = NULL;
+ if (cf_name->name)
+ ext4fs_dirhash(dir, cf_name->name, cf_name->len, hinfo);
+ else
+ ext4fs_dirhash(dir, iname->name, iname->len, hinfo);
+ return 0;
}
#endif
@@ -1405,16 +1417,12 @@ static bool ext4_match(struct inode *parent,
struct qstr cf = {.name = fname->cf_name.name,
.len = fname->cf_name.len};
if (IS_ENCRYPTED(parent)) {
- struct dx_hash_info hinfo;
-
- hinfo.hash_version = DX_HASH_SIPHASH;
- hinfo.seed = NULL;
- ext4fs_dirhash(parent, fname->cf_name.name,
- fname_len(fname), &hinfo);
- if (hinfo.hash != EXT4_DIRENT_HASH(de) ||
- hinfo.minor_hash !=
- EXT4_DIRENT_MINOR_HASH(de))
+ if (fname->hinfo.hash != EXT4_DIRENT_HASH(de) ||
+ fname->hinfo.minor_hash !=
+ EXT4_DIRENT_MINOR_HASH(de)) {
+
return 0;
+ }
}
return !ext4_ci_compare(parent, &cf, de->name,
de->name_len, true);
@@ -2036,15 +2044,11 @@ void ext4_insert_dentry(struct inode *dir,
de->name_len = fname_len(fname);
memcpy(de->name, fname_name(fname), fname_len(fname));
if (ext4_hash_in_dirent(dir)) {
- struct dx_hash_info hinfo;
+ struct dx_hash_info *hinfo = &fname->hinfo;
- hinfo.hash_version = DX_HASH_SIPHASH;
- hinfo.seed = NULL;
- ext4fs_dirhash(dir, fname_usr_name(fname),
- fname_len(fname), &hinfo);
- EXT4_EXTENDED_DIRENT(de)->hash = cpu_to_le32(hinfo.hash);
+ EXT4_EXTENDED_DIRENT(de)->hash = cpu_to_le32(hinfo->hash);
EXT4_EXTENDED_DIRENT(de)->minor_hash =
- cpu_to_le32(hinfo.minor_hash);
+ cpu_to_le32(hinfo->minor_hash);
}
}
@@ -2195,10 +2199,9 @@ static int make_indexed_dir(handle_t *handle, struct ext4_filename *fname,
if (fname->hinfo.hash_version <= DX_HASH_TEA)
fname->hinfo.hash_version += EXT4_SB(dir->i_sb)->s_hash_unsigned;
fname->hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed;
- if (ext4_hash_in_dirent(dir))
- ext4fs_dirhash(dir, fname_usr_name(fname),
- fname_len(fname), &fname->hinfo);
- else
+
+ /* casefolded encrypted hashes are computed on fname setup */
+ if (!ext4_hash_in_dirent(dir))
ext4fs_dirhash(dir, fname_name(fname),
fname_len(fname), &fname->hinfo);
--
2.24.1.735.g03f4e72817-goog
next prev parent reply other threads:[~2020-01-07 5:17 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-01-07 5:16 [PATCH v2 0/6] Support for Casefolding and Encryption Daniel Rosenberg
2020-01-07 5:16 ` [PATCH v2 1/6] TMP: fscrypt: Add support for casefolding with encryption Daniel Rosenberg
2020-01-07 5:16 ` [PATCH v2 2/6] vfs: Fold casefolding into vfs Daniel Rosenberg
2020-01-07 5:16 ` [PATCH v2 3/6] f2fs: Handle casefolding with Encryption Daniel Rosenberg
2020-01-07 5:16 ` [PATCH v2 4/6] ext4: Use struct super_blocks' casefold data Daniel Rosenberg
2020-01-07 5:16 ` [PATCH v2 5/6] ext4: Hande casefolding with encryption Daniel Rosenberg
2020-01-07 5:16 ` Daniel Rosenberg [this message]
2020-01-08 18:50 ` [PATCH v2 0/6] Support for Casefolding and Encryption Theodore Y. Ts'o
2020-01-08 21:24 ` Daniel Rosenberg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200107051638.40893-7-drosen@google.com \
--to=drosen@google.com \
--cc=adilger.kernel@dilger.ca \
--cc=chao@kernel.org \
--cc=corbet@lwn.net \
--cc=ebiggers@kernel.org \
--cc=jaegeuk@kernel.org \
--cc=kernel-team@android.com \
--cc=krisman@collabora.com \
--cc=linux-doc@vger.kernel.org \
--cc=linux-ext4@vger.kernel.org \
--cc=linux-f2fs-devel@lists.sourceforge.net \
--cc=linux-fscrypt@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=tytso@mit.edu \
--cc=viro@zeniv.linux.org.uk \
--subject='Re: [PATCH v2 6/6] ext4: Optimize match for casefolded encrypted dirs' \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).