Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp9528515ybl; Fri, 17 Jan 2020 13:43:44 -0800 (PST) X-Google-Smtp-Source: APXvYqw7KzQ38fo8o+eM7MgCjPDgJ6oN0tiuxnsTTCp6zIQTGXS94ADvHYRdwV/TxLannv0q9FfI X-Received: by 2002:aca:c5ca:: with SMTP id v193mr5133778oif.77.1579297424081; Fri, 17 Jan 2020 13:43:44 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1579297424; cv=none; d=google.com; s=arc-20160816; b=BCdZ1TiklQD3d8n9+dj6zHAbWyYuZXf3wuiqmVas87WHmUt/ouVNfEK9BL80FjXP7K gklUYAi9Ka++vsIFBoCEvbs3Mhs9ZRUfJTd9El4CwBj4BSe+rK7FFS7AFGdUmgSymXPc sTfrpcDWil6xVvJ319lCmajGN8ovELBgzmD/F5/JgMjpRPgY1AH/8D/m8ZKuNqpzUu/7 JzxRSe7wU6A9KxJALdiXNDMUvjLva4q2hOq5BxYp+rDwCrMNmw4y1ZYZqDlHWcOl1j5h sZ/asyfPr6hLkqkzGqYzVexYv4OaqvA8qAcy6FbSMUZhcHynRn4Kd2a9Rx/UCcU2QoR+ 725Q== 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=WxgwVjypClb4wXBEnsFhPs7Md2cufBpre+u9WsKYw7I=; b=c3e3pqxhXczW+Y+n40vyhTjCR+tNDSxl1WE9GnzBXyA2ViFutQAevPDZRIhH0/ubTe KANAzmbkNwrlUnuXUCXE0eo6e0riTgpZQezwBI7dgi3G0E2BdyCiSjPSy0QEmLbvAp6J +1dODURb9eeDyeE6+cR8iJeHuYuUJm+AOqRcW9dJlSehGrjaoUY4XZepeFW3x6PmFLlN OBPzfpp2TTMjm6YNGvD5GLACM9WIKGCJ2aj9PJpIIRYybPBGZrBmcriYCgZRLCxxEgzr ZFW1gPl31BZb5dnZJWdS6pSOy73mfhozKtD/usNrxdMEnOuLqKS2Pm3Lwwg2bwXe9Csv h3Xg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=CXn4pZxO; 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 e6si15552038otq.217.2020.01.17.13.43.33; Fri, 17 Jan 2020 13:43:44 -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=CXn4pZxO; 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 S1729934AbgAQVnT (ORCPT + 99 others); Fri, 17 Jan 2020 16:43:19 -0500 Received: from mail-pj1-f74.google.com ([209.85.216.74]:58231 "EHLO mail-pj1-f74.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729967AbgAQVnS (ORCPT ); Fri, 17 Jan 2020 16:43:18 -0500 Received: by mail-pj1-f74.google.com with SMTP id x16so4799900pjq.7 for ; Fri, 17 Jan 2020 13:43:18 -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=WxgwVjypClb4wXBEnsFhPs7Md2cufBpre+u9WsKYw7I=; b=CXn4pZxOLuGC69Nz6+VELpBugZtMeU/+bpuehqeDRIvTgJ1+DTEzF6kAnUKvl/kdpv tH1ORxCZV8mfoQdBRjVVDCjzQGKEUzKuC9Fn0wiJOEdN1iK7doyl6jr02pV4L4pRtHY3 JAvZmdteNZl+3GhUhhKfY5puOczHxeAX/ZDHqtyZWovpSgo0ipRlpN3i6DMOWNQEmCxm RgOncLDTBFjfO93fHu0zE2K8yUE6NfrYSwL4N103piqajX4AE55PaR42jGXLnspE1BgQ LLQoLJYHoy/0AY/2poOlEsLlDTYraotXfoLEu85+AhDihvkjSNloELKjuZ0DaF84EHHV PCpw== 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=WxgwVjypClb4wXBEnsFhPs7Md2cufBpre+u9WsKYw7I=; b=X2Du+vcevvAJoRZrxQyKGHitL/q5lT55dFegruNXlXn9SNN3Q7lxqUkw8Gap64vrAg xk3Vmmg+WRjzKKECKoGIF9uE7jGOi7hBxsTBkgqAj8uhzZU919X7FRar7Z88GaaWENF6 /3+sw1wa3jkLCQIhJQhS4XfIVNDsGOnATRbcSsxgBt5IhR/KRwkzaBnLYUGbMNC9z9Fj uGPjq29h4p+x0N75FJFZvVusZkAltWr6rKMtKptrcSMN02fPeloH7Rjiakw25lSOxo4h DBIU8A8eepsBPtJQnhvha02+ggnzvr2ULg6xqjup9PEkC+j7oql3pbugVFLqZP04ocL5 LOsQ== X-Gm-Message-State: APjAAAXu6jKz4s0zi6OAIHh3RheL9GQwQQxQt7VIr4Reitjddu4dsic8 YNAjsmiFM5AlzOTDCyOdK9MNHnrnZE0= X-Received: by 2002:a63:770c:: with SMTP id s12mr49288598pgc.25.1579297398140; Fri, 17 Jan 2020 13:43:18 -0800 (PST) Date: Fri, 17 Jan 2020 13:42:46 -0800 In-Reply-To: <20200117214246.235591-1-drosen@google.com> Message-Id: <20200117214246.235591-10-drosen@google.com> Mime-Version: 1.0 References: <20200117214246.235591-1-drosen@google.com> X-Mailer: git-send-email 2.25.0.341.g760bfbb309-goog Subject: [PATCH v3 9/9] 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 Cc: 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 a70b4db05b745..6755eb30a89b7 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 a5ee76a14e3b7..6b63271978a0b 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); @@ -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.25.0.341.g760bfbb309-goog