Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp927700ybl; Tue, 28 Jan 2020 15:05:18 -0800 (PST) X-Google-Smtp-Source: APXvYqwAPcT6pBReqBMgl1Zs9EFTQwif98KzodAzu6NzXQE34oE1LEplpny8nnvFRQt5qfmmTpgN X-Received: by 2002:a05:6830:1d6e:: with SMTP id l14mr17938553oti.32.1580252718537; Tue, 28 Jan 2020 15:05:18 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1580252718; cv=none; d=google.com; s=arc-20160816; b=hGUm27Ms4eWqlESF8NTwTNC9tIzQRIPSdaQ/V6YWE1qAmvsjUMNzLYzdOgXK3L5OAU MZ+efypM2N+HtnICKoZ1q8Avh+O44m1g0zAmr9mFS3j3MtdcXE5HnNnbz745k5mgwfwO cgw7Ntd6K2ij00Hw2Canx4B5iA/0akZTjFXR/v6RerTdLpdFVjnS7+4bISp2e5itob07 sIDATHirE0M0uMV/b3VQ1BqqTKsArQFcagB+IxU+aechUc/hcu/EJnaewRHO08cTVCEs jEND0sq9+f8CVossmXRwAiSv6MkQwreRMm6F2oaWnbCybY4GZkXbGTvTfa72c394Ap0G ifSg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:from:subject:references :mime-version:message-id:in-reply-to:date:dkim-signature; bh=lKtpwaZKWL1neBB1NRO1dY7byN6w+Jp1l7lnT/R4Qwg=; b=jIRlIRXWqCGptKSk3W+m6dzOmxBykwBKarQ5BBwyWYftCuXAsH/6thpNtKNJWGv+fz FeMZGhedN0O8s2AjtyhWs5ROjgS6K8GlD0lBLgpHgqmZffW0Xu86LcYkwcaZ9shNUR4E YUiiTt1qEyokZFCkvT8xMZbO4OTtyTQoN/6SC6Hk9aPOdHzuxGEBe5C0nwVDasWUqmU9 42rELua06drt6V4qigPpt4ocldlg19UeEc5ye4dAD4nswrB0dbQ+xzPtRDnvbdWp3kli pvr6K8yuJuNeIhe81BD2DzEVTiL3dxniKWMYM7fM7ZumqGiXg8OG0CzRqRRzby8MOkpA 8jvw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=p3xievYC; spf=pass (google.com: best guess record for domain of linux-ext4-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-ext4-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f23si81151oto.205.2020.01.28.15.05.02; Tue, 28 Jan 2020 15:05:18 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-ext4-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=p3xievYC; spf=pass (google.com: best guess record for domain of linux-ext4-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-ext4-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726411AbgA1XEl (ORCPT + 99 others); Tue, 28 Jan 2020 18:04:41 -0500 Received: from mail-pg1-f202.google.com ([209.85.215.202]:54561 "EHLO mail-pg1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726670AbgA1XEf (ORCPT ); Tue, 28 Jan 2020 18:04:35 -0500 Received: by mail-pg1-f202.google.com with SMTP id i21so9555183pgm.21 for ; Tue, 28 Jan 2020 15:04:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=lKtpwaZKWL1neBB1NRO1dY7byN6w+Jp1l7lnT/R4Qwg=; b=p3xievYCqztxTXmXD7nJZEAigVvj3Lda/BhlRwqAqO3SHUrWy2KYwJJwqzA8kdttn8 3TIN0DSCPxI/tQj9BFFSLm5x3SCKosBBV/eNJr/2VeRvzqmfRGnotjqSAyndL+8WFt45 FkX3jQVFdZ8y4oYU8mXKWI2R4ERFZgPxktIQWSRfSxxvZ3bo7U6lWkYUiJ4lmO3/H7Rb 0STyMPQ6ZvSaQPRdK8Ao/z1soK7+JoyEfVcC7MSfrhsdalSrG0/9OK1giramiXMhLRQd Cu8SkgQXkfjMz2vFSlGeWDNfUmjVaXeoWo8gBcYGVT7wMS7I8+XCGB2JR4jiyvoKg9ZM o26g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=lKtpwaZKWL1neBB1NRO1dY7byN6w+Jp1l7lnT/R4Qwg=; b=t9fgqEzEphy3Bs0vIkqm5WpGFIMWG7ALLGzPCuqfkNKzILB36yuTWnZgAa0Xr8+gUR qmvpzIhbUSc1ZkHkEcVl8FA0H1QcUKTe1Hdw2GZ2C4SmgLpyYSaVFFQfql3Tg5FwBYuq 8dsRCoP6GOCunExWcTXGK0DW2D5WA4Cn4jr7zcScXvfU24yzWR00uuFf5OFr62zFT84c ZVZ29L+kxSJBwIuyGCQEdT2T+1tnPDXyLSldfWBE0aUMvNWaI1Bfg/IGn6Bh5TmfHt78 SggDeJWH4U+HtneeZwSww/mIL8ki61CuHVjuoD0vocyyHvBXwuNZ1U6DFMUOzsc5Vdn2 JGDA== X-Gm-Message-State: APjAAAWjoA25GVaKFqNSF3nqGFX99w4Ob6e4ODfC8SyNIlYggFvVQp22 zdNggAevznCWmgGbgv5mB0/ex47fkhc= X-Received: by 2002:a63:5b0e:: with SMTP id p14mr28473962pgb.315.1580252674948; Tue, 28 Jan 2020 15:04:34 -0800 (PST) Date: Tue, 28 Jan 2020 15:03:28 -0800 In-Reply-To: <20200128230328.183524-1-drosen@google.com> Message-Id: <20200128230328.183524-6-drosen@google.com> Mime-Version: 1.0 References: <20200128230328.183524-1-drosen@google.com> X-Mailer: git-send-email 2.25.0.341.g760bfbb309-goog Subject: [PATCH v6 5/5] ext4: Optimize match for casefolded encrypted dirs From: Daniel Rosenberg To: "Theodore Ts'o" , linux-ext4@vger.kernel.org, Jaegeuk Kim , Chao Yu , linux-f2fs-devel@lists.sourceforge.net, Eric Biggers , linux-fscrypt@vger.kernel.org, Alexander Viro , Richard Weinberger Cc: linux-mtd@lists.infradead.org, Andreas Dilger , Jonathan Corbet , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, Gabriel Krisman Bertazi , kernel-team@android.com, Daniel Rosenberg Content-Type: text/plain; charset="UTF-8" Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org 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 --- 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 64c7375bc3f65..c69b2bd66b201 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 4fc543f459aed..25541d08f648b 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(const 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); @@ -2037,15 +2045,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); } } @@ -2196,10 +2200,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.25.0.341.g760bfbb309-goog