From: Gabriel Krisman Bertazi <krisman@suse.de>
To: Eugen Hristev <eugen.hristev@collabora.com>
Cc: linux-ext4@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-f2fs-devel@lists.sourceforge.net,
linux-fsdevel@vger.kernel.org, jaegeuk@kernel.org,
adilger.kernel@dilger.ca, tytso@mit.edu, chao@kernel.org,
viro@zeniv.linux.org.uk, brauner@kernel.org, jack@suse.cz,
ebiggers@google.com, kernel@collabora.com,
Gabriel Krisman Bertazi <krisman@collabora.com>
Subject: Re: [PATCH v17 4/7] ext4: Reuse generic_ci_match for ci comparisons
Date: Tue, 04 Jun 2024 15:17:41 -0400 [thread overview]
Message-ID: <87cyowldpm.fsf@mailhost.krisman.be> (raw)
In-Reply-To: <20240529082634.141286-5-eugen.hristev@collabora.com> (Eugen Hristev's message of "Wed, 29 May 2024 11:26:31 +0300")
Eugen Hristev <eugen.hristev@collabora.com> writes:
> From: Gabriel Krisman Bertazi <krisman@collabora.com>
>
> Instead of reimplementing ext4_match_ci, use the new libfs helper.
>
> It also adds a comment explaining why fname->cf_name.name must be
> checked prior to the encryption hash optimization, because that tripped
> me before.
>
> Signed-off-by: Gabriel Krisman Bertazi <krisman@collabora.com>
> Signed-off-by: Eugen Hristev <eugen.hristev@collabora.com>
> Reviewed-by: Eric Biggers <ebiggers@google.com>
> ---
> fs/ext4/namei.c | 91 +++++++++++++++----------------------------------
> 1 file changed, 27 insertions(+), 64 deletions(-)
>
> diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
> index ec4c9bfc1057..20668741a23c 100644
> --- a/fs/ext4/namei.c
> +++ b/fs/ext4/namei.c
> @@ -1390,58 +1390,6 @@ static void dx_insert_block(struct dx_frame *frame, u32 hash, ext4_lblk_t block)
> }
>
> #if IS_ENABLED(CONFIG_UNICODE)
> -/*
> - * Test whether a case-insensitive directory entry matches the filename
> - * being searched for. If quick is set, assume the name being looked up
> - * is already in the casefolded form.
> - *
> - * Returns: 0 if the directory entry matches, more than 0 if it
> - * doesn't match or less than zero on error.
> - */
> -static int ext4_ci_compare(const struct inode *parent, const struct qstr *name,
> - u8 *de_name, size_t de_name_len, bool quick)
> -{
> - const struct super_block *sb = parent->i_sb;
> - const struct unicode_map *um = sb->s_encoding;
> - struct fscrypt_str decrypted_name = FSTR_INIT(NULL, de_name_len);
> - struct qstr entry = QSTR_INIT(de_name, de_name_len);
> - int ret;
> -
> - if (IS_ENCRYPTED(parent)) {
> - const struct fscrypt_str encrypted_name =
> - FSTR_INIT(de_name, de_name_len);
> -
> - decrypted_name.name = kmalloc(de_name_len, GFP_KERNEL);
> - if (!decrypted_name.name)
> - return -ENOMEM;
> - ret = fscrypt_fname_disk_to_usr(parent, 0, 0, &encrypted_name,
> - &decrypted_name);
> - if (ret < 0)
> - goto out;
> - entry.name = decrypted_name.name;
> - entry.len = decrypted_name.len;
> - }
> -
> - if (quick)
> - ret = utf8_strncasecmp_folded(um, name, &entry);
> - else
> - ret = utf8_strncasecmp(um, name, &entry);
> - if (ret < 0) {
> - /* Handle invalid character sequence as either an error
> - * or as an opaque byte sequence.
> - */
> - if (sb_has_strict_encoding(sb))
> - ret = -EINVAL;
> - else if (name->len != entry.len)
> - ret = 1;
> - else
> - ret = !!memcmp(name->name, entry.name, entry.len);
> - }
> -out:
> - kfree(decrypted_name.name);
> - return ret;
> -}
> -
> int ext4_fname_setup_ci_filename(struct inode *dir, const struct qstr *iname,
> struct ext4_filename *name)
> {
> @@ -1503,20 +1451,35 @@ static bool ext4_match(struct inode *parent,
> #if IS_ENABLED(CONFIG_UNICODE)
> if (IS_CASEFOLDED(parent) &&
> (!IS_ENCRYPTED(parent) || fscrypt_has_encryption_key(parent))) {
> - if (fname->cf_name.name) {
> - if (IS_ENCRYPTED(parent)) {
> - if (fname->hinfo.hash != EXT4_DIRENT_HASH(de) ||
> - fname->hinfo.minor_hash !=
> - EXT4_DIRENT_MINOR_HASH(de)) {
> + int ret;
>
> - return false;
> - }
> - }
> - return !ext4_ci_compare(parent, &fname->cf_name,
> - de->name, de->name_len, true);
> + /*
> + * Just checking IS_ENCRYPTED(parent) below is not
> + * sufficient to decide whether one can use the hash for
> + * skipping the string comparison, because the key might
> + * have been added right after
> + * ext4_fname_setup_ci_filename(). In this case, a hash
> + * mismatch will be a false negative. Therefore, make
> + * sure cf_name was properly initialized before
> + * considering the calculated hash.
> + */
> + if (IS_ENCRYPTED(parent) && fname->cf_name.name &&
> + (fname->hinfo.hash != EXT4_DIRENT_HASH(de) ||
> + fname->hinfo.minor_hash != EXT4_DIRENT_MINOR_HASH(de)))
> + return false;
> +
> + ret = generic_ci_match(parent, fname->usr_fname,
> + &fname->cf_name, de->name,
> + de->name_len);
> + if (ret < 0) {
> + /*
> + * Treat comparison errors as not a match. The
> + * only case where it happens is on a disk
> + * corruption or ENOMEM.
> + */
> + return false;
> }
> - return !ext4_ci_compare(parent, fname->usr_fname, de->name,
> - de->name_len, false);
With the changes to patch 3 in this iteration, This could become:
/*
* Treat comparison errors as not a match. The
* only case where it happens is disk corruption
* or ENOMEM.
*/
return ext4_ci_compare(parent, fname->usr_fname, de->name,
de->name_len, false) > 0;
--
Gabriel Krisman Bertazi
WARNING: multiple messages have this Message-ID (diff)
From: Gabriel Krisman Bertazi <krisman@suse.de>
To: Eugen Hristev <eugen.hristev@collabora.com>
Cc: brauner@kernel.org, kernel@collabora.com, tytso@mit.edu,
ebiggers@google.com, jack@suse.cz, linux-kernel@vger.kernel.org,
linux-f2fs-devel@lists.sourceforge.net, adilger.kernel@dilger.ca,
viro@zeniv.linux.org.uk, linux-fsdevel@vger.kernel.org,
jaegeuk@kernel.org, linux-ext4@vger.kernel.org,
Gabriel Krisman Bertazi <krisman@collabora.com>
Subject: Re: [f2fs-dev] [PATCH v17 4/7] ext4: Reuse generic_ci_match for ci comparisons
Date: Tue, 04 Jun 2024 15:17:41 -0400 [thread overview]
Message-ID: <87cyowldpm.fsf@mailhost.krisman.be> (raw)
In-Reply-To: <20240529082634.141286-5-eugen.hristev@collabora.com> (Eugen Hristev's message of "Wed, 29 May 2024 11:26:31 +0300")
Eugen Hristev <eugen.hristev@collabora.com> writes:
> From: Gabriel Krisman Bertazi <krisman@collabora.com>
>
> Instead of reimplementing ext4_match_ci, use the new libfs helper.
>
> It also adds a comment explaining why fname->cf_name.name must be
> checked prior to the encryption hash optimization, because that tripped
> me before.
>
> Signed-off-by: Gabriel Krisman Bertazi <krisman@collabora.com>
> Signed-off-by: Eugen Hristev <eugen.hristev@collabora.com>
> Reviewed-by: Eric Biggers <ebiggers@google.com>
> ---
> fs/ext4/namei.c | 91 +++++++++++++++----------------------------------
> 1 file changed, 27 insertions(+), 64 deletions(-)
>
> diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
> index ec4c9bfc1057..20668741a23c 100644
> --- a/fs/ext4/namei.c
> +++ b/fs/ext4/namei.c
> @@ -1390,58 +1390,6 @@ static void dx_insert_block(struct dx_frame *frame, u32 hash, ext4_lblk_t block)
> }
>
> #if IS_ENABLED(CONFIG_UNICODE)
> -/*
> - * Test whether a case-insensitive directory entry matches the filename
> - * being searched for. If quick is set, assume the name being looked up
> - * is already in the casefolded form.
> - *
> - * Returns: 0 if the directory entry matches, more than 0 if it
> - * doesn't match or less than zero on error.
> - */
> -static int ext4_ci_compare(const struct inode *parent, const struct qstr *name,
> - u8 *de_name, size_t de_name_len, bool quick)
> -{
> - const struct super_block *sb = parent->i_sb;
> - const struct unicode_map *um = sb->s_encoding;
> - struct fscrypt_str decrypted_name = FSTR_INIT(NULL, de_name_len);
> - struct qstr entry = QSTR_INIT(de_name, de_name_len);
> - int ret;
> -
> - if (IS_ENCRYPTED(parent)) {
> - const struct fscrypt_str encrypted_name =
> - FSTR_INIT(de_name, de_name_len);
> -
> - decrypted_name.name = kmalloc(de_name_len, GFP_KERNEL);
> - if (!decrypted_name.name)
> - return -ENOMEM;
> - ret = fscrypt_fname_disk_to_usr(parent, 0, 0, &encrypted_name,
> - &decrypted_name);
> - if (ret < 0)
> - goto out;
> - entry.name = decrypted_name.name;
> - entry.len = decrypted_name.len;
> - }
> -
> - if (quick)
> - ret = utf8_strncasecmp_folded(um, name, &entry);
> - else
> - ret = utf8_strncasecmp(um, name, &entry);
> - if (ret < 0) {
> - /* Handle invalid character sequence as either an error
> - * or as an opaque byte sequence.
> - */
> - if (sb_has_strict_encoding(sb))
> - ret = -EINVAL;
> - else if (name->len != entry.len)
> - ret = 1;
> - else
> - ret = !!memcmp(name->name, entry.name, entry.len);
> - }
> -out:
> - kfree(decrypted_name.name);
> - return ret;
> -}
> -
> int ext4_fname_setup_ci_filename(struct inode *dir, const struct qstr *iname,
> struct ext4_filename *name)
> {
> @@ -1503,20 +1451,35 @@ static bool ext4_match(struct inode *parent,
> #if IS_ENABLED(CONFIG_UNICODE)
> if (IS_CASEFOLDED(parent) &&
> (!IS_ENCRYPTED(parent) || fscrypt_has_encryption_key(parent))) {
> - if (fname->cf_name.name) {
> - if (IS_ENCRYPTED(parent)) {
> - if (fname->hinfo.hash != EXT4_DIRENT_HASH(de) ||
> - fname->hinfo.minor_hash !=
> - EXT4_DIRENT_MINOR_HASH(de)) {
> + int ret;
>
> - return false;
> - }
> - }
> - return !ext4_ci_compare(parent, &fname->cf_name,
> - de->name, de->name_len, true);
> + /*
> + * Just checking IS_ENCRYPTED(parent) below is not
> + * sufficient to decide whether one can use the hash for
> + * skipping the string comparison, because the key might
> + * have been added right after
> + * ext4_fname_setup_ci_filename(). In this case, a hash
> + * mismatch will be a false negative. Therefore, make
> + * sure cf_name was properly initialized before
> + * considering the calculated hash.
> + */
> + if (IS_ENCRYPTED(parent) && fname->cf_name.name &&
> + (fname->hinfo.hash != EXT4_DIRENT_HASH(de) ||
> + fname->hinfo.minor_hash != EXT4_DIRENT_MINOR_HASH(de)))
> + return false;
> +
> + ret = generic_ci_match(parent, fname->usr_fname,
> + &fname->cf_name, de->name,
> + de->name_len);
> + if (ret < 0) {
> + /*
> + * Treat comparison errors as not a match. The
> + * only case where it happens is on a disk
> + * corruption or ENOMEM.
> + */
> + return false;
> }
> - return !ext4_ci_compare(parent, fname->usr_fname, de->name,
> - de->name_len, false);
With the changes to patch 3 in this iteration, This could become:
/*
* Treat comparison errors as not a match. The
* only case where it happens is disk corruption
* or ENOMEM.
*/
return ext4_ci_compare(parent, fname->usr_fname, de->name,
de->name_len, false) > 0;
--
Gabriel Krisman Bertazi
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
next prev parent reply other threads:[~2024-06-04 19:17 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-05-29 8:26 [PATCH v17 0/7] Case insensitive cleanup for ext4/f2fs Eugen Hristev
2024-05-29 8:26 ` [f2fs-dev] " Eugen Hristev via Linux-f2fs-devel
2024-05-29 8:26 ` [PATCH v17 1/7] ext4: Simplify the handling of cached casefolded names Eugen Hristev
2024-05-29 8:26 ` [f2fs-dev] " Eugen Hristev via Linux-f2fs-devel
2024-05-29 8:26 ` [PATCH v17 2/7] f2fs: " Eugen Hristev
2024-05-29 8:26 ` [f2fs-dev] " Eugen Hristev via Linux-f2fs-devel
2024-05-29 8:26 ` [PATCH v17 3/7] libfs: Introduce case-insensitive string comparison helper Eugen Hristev
2024-05-29 8:26 ` [f2fs-dev] " Eugen Hristev via Linux-f2fs-devel
2024-05-31 4:48 ` Eric Biggers
2024-05-31 4:48 ` [f2fs-dev] " Eric Biggers
2024-05-31 10:12 ` Eugen Hristev
2024-05-31 10:12 ` [f2fs-dev] " Eugen Hristev via Linux-f2fs-devel
2024-06-04 19:18 ` Gabriel Krisman Bertazi
2024-06-04 19:18 ` [f2fs-dev] " Gabriel Krisman Bertazi
2024-05-29 8:26 ` [PATCH v17 4/7] ext4: Reuse generic_ci_match for ci comparisons Eugen Hristev
2024-05-29 8:26 ` [f2fs-dev] " Eugen Hristev via Linux-f2fs-devel
2024-06-04 19:17 ` Gabriel Krisman Bertazi [this message]
2024-06-04 19:17 ` Gabriel Krisman Bertazi
2024-06-05 10:48 ` Eugen Hristev
2024-06-05 10:48 ` [f2fs-dev] " Eugen Hristev via Linux-f2fs-devel
2024-05-29 8:26 ` [PATCH v17 5/7] f2fs: " Eugen Hristev
2024-05-29 8:26 ` [f2fs-dev] " Eugen Hristev via Linux-f2fs-devel
2024-05-29 8:26 ` [PATCH v17 6/7] ext4: Move CONFIG_UNICODE defguards into the code flow Eugen Hristev
2024-05-29 8:26 ` [f2fs-dev] " Eugen Hristev via Linux-f2fs-devel
2024-05-29 8:26 ` [PATCH v17 7/7] f2fs: " Eugen Hristev
2024-05-29 8:26 ` [f2fs-dev] " Eugen Hristev via Linux-f2fs-devel
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=87cyowldpm.fsf@mailhost.krisman.be \
--to=krisman@suse.de \
--cc=adilger.kernel@dilger.ca \
--cc=brauner@kernel.org \
--cc=chao@kernel.org \
--cc=ebiggers@google.com \
--cc=eugen.hristev@collabora.com \
--cc=jack@suse.cz \
--cc=jaegeuk@kernel.org \
--cc=kernel@collabora.com \
--cc=krisman@collabora.com \
--cc=linux-ext4@vger.kernel.org \
--cc=linux-f2fs-devel@lists.sourceforge.net \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=tytso@mit.edu \
--cc=viro@zeniv.linux.org.uk \
/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
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.