Received: by 2002:a05:6a10:8c0a:0:0:0:0 with SMTP id go10csp128845pxb; Wed, 3 Feb 2021 01:14:02 -0800 (PST) X-Google-Smtp-Source: ABdhPJz4ug9KQ++ckz1dxtLIgIM78fSqsIFsRyo5c7KrH/66ivym/DtSrydMZxJKgA9S+KntDX6v X-Received: by 2002:a17:907:aa9:: with SMTP id bz9mr2175150ejc.528.1612343642360; Wed, 03 Feb 2021 01:14:02 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1612343642; cv=none; d=google.com; s=arc-20160816; b=XWpvuTPCrWzL5YKhP0IlpPTFW+49iuc0Hl4XKl7b0BUNdSQpaq0t/7dqcn7jxN1IZh c4Gzutt5FcqUj4XdSZXxbLUxy7y57O0S6YxzrQSqaNq06G54vXYsZAfyP3gKMW2xtYU5 5P4dTz9xGCiDbtC8D/t5cNKLGIpHCbMp3g+WPgMCPRdEXO/VS2jGaD3by/vfUcSvgi2b 9zDVze5e/QfdsxFxZfOB17QQPjqpNZvaPJ1uPehs6BDoYXTAW/v4NZ832E8w3QNUhkAO dTX3vuc3/UL/Jij0gi0qLagKKDFx+l5oZ0TYcMKjtHVyRJRZ9sO00p4CaOmdtZzrfGK2 FjCg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:references:mime-version :message-id:in-reply-to:date:sender:dkim-signature; bh=aacYYvBrsO89246VG7kwqo+UEXeIJ89FcRhL6OJu++c=; b=Gdr1V8CartDDTefVmzk5a1CBaxsJGiL1KCLQQ5guuPlc+Hk2JV2YH4fyFFSwF5xyBX jwyQMx/ljFIIkwPRfBX8gqxoQkVGi98I4RwVlawMVVJENDbgLB9na6OHxuE64yuc8YaN 7kgSPtiz0gL8gohF0sUQzMzVOWDqeSYSHpl/hzFwtbRkzf/63cLr6bw61dINlRRnUB+o /WO9uOtTKs9nkt0Sv4fmRQh47pAECcNzpo68J9IXJBw/js8tCFTaeHuNdLKvzbPgZOzU 1wM1dMgvx34pYUpv9Kte1Pz4lOdWJx3H24x4LrSgqqe/PxlBc/yydrQto/TNyjitqOVK iZQg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b="pN/zjW9W"; spf=pass (google.com: domain of linux-ext4-owner@vger.kernel.org designates 23.128.96.18 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. [23.128.96.18]) by mx.google.com with ESMTP id q21si927647ejz.227.2021.02.03.01.13.36; Wed, 03 Feb 2021 01:14:02 -0800 (PST) Received-SPF: pass (google.com: domain of linux-ext4-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b="pN/zjW9W"; spf=pass (google.com: domain of linux-ext4-owner@vger.kernel.org designates 23.128.96.18 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 S229815AbhBCJKf (ORCPT + 99 others); Wed, 3 Feb 2021 04:10:35 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42412 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233263AbhBCJJH (ORCPT ); Wed, 3 Feb 2021 04:09:07 -0500 Received: from mail-pf1-x449.google.com (mail-pf1-x449.google.com [IPv6:2607:f8b0:4864:20::449]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A69B3C06178C for ; Wed, 3 Feb 2021 01:07:53 -0800 (PST) Received: by mail-pf1-x449.google.com with SMTP id x206so15696398pfc.16 for ; Wed, 03 Feb 2021 01:07:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=aacYYvBrsO89246VG7kwqo+UEXeIJ89FcRhL6OJu++c=; b=pN/zjW9WW+TyD9lbKiOtFxDGJFcLXOUEk8mf4j4LL2nKVCYXWHgvcFMAIDORtfvxjR ab3D51qsSlSJFu8gkhH1ug3grudzV/43vairsH8wHF9Ox8zgf/d4SiVVCBN+3PrNqV0R YB2rujh4TnKXkkIiaDcAWTKoE4FtaH3x9IUUceBso37WVLyA+Rm4352hhfTAcvmLwxil xxmxtYhk/nI96yrAAvcZKKm5Kw7YJWrKOe7oYYPugQEROAh512qFLoJIWgW24rtDPOvL hdiNl7bLuddHHdxG+IQfcVfFT3bO2DKY2gKKdC6Rmc4zWzecF2ZeCFuHP9yYkjLckSk5 CFQA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=aacYYvBrsO89246VG7kwqo+UEXeIJ89FcRhL6OJu++c=; b=a4qIl+eNPe71DQkN/8TukjW0PXampT5ASYzTd05hkchjPfduSlvSe51jl9g6azJoKH 5x0JdJVLX67gE5mswaH9aDXbKuluH5EkUSB4WTTMXn+Rtp3D0PcPywiEU9dKHkkKunap KlJ4c6xo8gnOUk+K/bg0pJR8G1pEn2mDiA+yk/L3skCz+iAQdILAao889myLlOCg59uR j8jq5WamP2mcOg4uzGozBDZLpP7ny4oxQjGNs2vfaOmRBPYH/XrZrFuue5sTe8TuFPL9 6oVrxH+/SCx1yPUjex707OFvQnRoY7c2fadPhot8NtQUoXKqMWPVCerHfe5MIOCiUD1d +upA== X-Gm-Message-State: AOAM531T5JNA2HQQ+L0KssBJ2V0VCbS8M1eKELIcxUk93frv7yI96bF4 4bCrxsOL3yCCiPXLG2rS8snwRmpfqfE= Sender: "drosen via sendgmr" X-Received: from drosen.c.googlers.com ([fda3:e722:ac3:10:24:72f4:c0a8:4e6f]) (user=drosen job=sendgmr) by 2002:a17:90a:3b44:: with SMTP id t4mr87542pjf.1.1612343272973; Wed, 03 Feb 2021 01:07:52 -0800 (PST) Date: Wed, 3 Feb 2021 09:07:45 +0000 In-Reply-To: <20210203090745.4103054-1-drosen@google.com> Message-Id: <20210203090745.4103054-3-drosen@google.com> Mime-Version: 1.0 References: <20210203090745.4103054-1-drosen@google.com> X-Mailer: git-send-email 2.30.0.365.g02bc693789-goog Subject: [PATCH 2/2] ext4: Optimize match for casefolded encrypted dirs From: Daniel Rosenberg To: "Theodore Y . Ts'o" , Eric Biggers , Andreas Dilger , linux-ext4@vger.kernel.org Cc: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, Gabriel Krisman Bertazi , kernel-team@android.com, Daniel Rosenberg , Paul Lawrence Content-Type: text/plain; charset="UTF-8" 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 Signed-off-by: Paul Lawrence --- 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 90a2c182e4d7..997f80cfe5df 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -2637,9 +2637,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 @@ -2670,9 +2670,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, @@ -2689,9 +2689,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) @@ -2716,15 +2716,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 00b0b0cb4600..ff024bb613c0 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -799,7 +799,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; @@ -1364,19 +1366,21 @@ static 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 (!IS_CASEFOLDED(dir) || !dir->i_sb->s_encoding) { 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, @@ -1384,10 +1388,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 @@ -1417,16 +1429,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); @@ -2061,15 +2069,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_DIRENT_HASHES(de)->hash = cpu_to_le32(hinfo.hash); + EXT4_DIRENT_HASHES(de)->hash = cpu_to_le32(hinfo->hash); EXT4_DIRENT_HASHES(de)->minor_hash = - cpu_to_le32(hinfo.minor_hash); + cpu_to_le32(hinfo->minor_hash); } } @@ -2220,10 +2224,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.30.0.365.g02bc693789-goog