From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.9 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AB5C5C432C0 for ; Tue, 3 Dec 2019 05:39:53 +0000 (UTC) Received: from lists.sourceforge.net (lists.sourceforge.net [216.105.38.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 76535206DF for ; Tue, 3 Dec 2019 05:39:53 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=lists.sourceforge.net header.i=@lists.sourceforge.net header.b="Zh6/N0mH"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=sourceforge.net header.i=@sourceforge.net header.b="eO628/63"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=sf.net header.i=@sf.net header.b="VF53+g8p"; dkim=neutral (0-bit key) header.d=google.com header.i=@google.com header.b="mdyqPGow" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 76535206DF Authentication-Results: mail.kernel.org; dmarc=pass (p=none dis=none) header.from=lists.sourceforge.net Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=linux-f2fs-devel-bounces@lists.sourceforge.net DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.sourceforge.net; s=beta; h=Content-Transfer-Encoding:Content-Type:Cc: Reply-To:From:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:Subject:To:References:Mime-Version:Message-Id: In-Reply-To:Date:Sender:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=Rkm17YHytabjFI3+dv5w9pjKTu0vCpRoU7QXYc6toOk=; b=Zh6/N0mHbN0wt9o0bMzhYRAwW ztry3a+UDjWTaL2CwD9g7ewo8Jvz+yfe4iFDJyWik3ITIdbDl/p7gg7NYYlJpRdD0QfnjHQzaknYT e6HrgmGhlivsypgSvb9ma3xAWdgkSftMjgvvte/UgOEmVFXyx2lcmhiV3IGSZYiG4q5yU=; Received: from [127.0.0.1] (helo=sfs-ml-4.v29.lw.sourceforge.com) by sfs-ml-4.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1ic0uf-0001kW-5T; Tue, 03 Dec 2019 05:39:53 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-4.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from <3gO7lXQYKAOkOcZdPYRZZRWP.NZX@flex--drosen.bounces.google.com>) id 1ic0ud-0001kO-VX for linux-f2fs-devel@lists.sourceforge.net; Tue, 03 Dec 2019 05:39:52 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Type:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Sender:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=s9Z9LjD9ymkQQUZ+VH0GlQne8IEw1wiPyT49On1Az6o=; b=eO628/63kwwUZBqugbGLSJjFn TTo603wbBR32sJlyo8lQchzkQhnTt6bgUGNjIQKt5jtYYnCv4rkGRaeQYKOBwjH4kiRvOEnoJGq+7 i53oGAWkXha/zAFWDXzo2OUNcpK16aJnroUQIv0TqSh6UFd0njhnALGvtpdNZC7weetwE=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Type:Cc:To:From:Subject:References:Mime-Version:Message-Id: In-Reply-To:Date:Sender:Reply-To:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=s9Z9LjD9ymkQQUZ+VH0GlQne8IEw1wiPyT49On1Az6o=; b=VF53+g8pmWeWjgc4XvrG6b49Pr oMLO7Ivc3GesZIhMDvD/XiwfpTu2bewqyT0bMyxwqWPrXxZgJIje6ohfJ7migLdztJLlscM03wudI oxuhH3zSpAk9IGitkijIFTncaknrNAvV+6auPMBoIIeLsASh8aSaSExHNGnRBgBcb66o=; Received: from mail-qt1-f201.google.com ([209.85.160.201]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.92.2) id 1ic0uc-001gZL-8g for linux-f2fs-devel@lists.sourceforge.net; Tue, 03 Dec 2019 05:39:51 +0000 Received: by mail-qt1-f201.google.com with SMTP id m8so1632014qta.20 for ; Mon, 02 Dec 2019 21:39:50 -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=s9Z9LjD9ymkQQUZ+VH0GlQne8IEw1wiPyT49On1Az6o=; b=mdyqPGowQAy57ke3pYs7WyHpLTx6DoPtf9TfYQjz/Wk+gjXPr/XwnFzpjLq1XJAKqG 8m7yKkkZyQCRvikIWLKWiJWZZ8l+6pxhzmbcNvJpzaMlCXhj3rSFjcbTILSy6YQY+/KO RS8sSTcxK2ZxwMHN0CzjpfBjQ3UxxQ+dIN9EdvRVCjVvok8k3J1TtYBTNAcQEx7hKcjs bSiyKlUYClbhnsNkTXpmB2dvoNA+CnskMavt1ePN4tih7Hv4me1ERZ9j2B4TbRAC5M42 2rSl/cLdZzgns+5G12aLkOv8bx67rCXuk95KPGZvnZR6e55nK4gM1UhZ1PK78G9DV48O g1Lw== 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=s9Z9LjD9ymkQQUZ+VH0GlQne8IEw1wiPyT49On1Az6o=; b=rSqwBK0cUolT+xCNNms7YomOj6K2afxbhwi3V8NTLlNm2+UzcgggEdteRIR8J6F5Eq M719a0YaIMPIIh1dJaUI/N+7d1jSJy/OFLQXpwsjPdjN4d8QxWiDN/rt7WZy1+VG9Th6 FWxmGFt8wBjBWFYye44KyVhxQNCEVLLOUQpDJ7pd7HmqeavFKLbXmFBoKUv4SZHhz8Eo CiDy1gVMswOIEXkFzrfMyo/SqY1DUiSBhElT1l2BE62LtKanGWHsQxhfx72EwoSlVk+s 5vnOjJd+p109Xka5PZzmsdSf6j1VX80BmDiyn6csigMxgho7pQnwDzkmsZP88X/TdNe2 DZMQ== X-Gm-Message-State: APjAAAURDJi1qP1AE+N6CjvSZ/3L4bSaUPwMRodR96Gt38WVFBrTP6XY L/fmr/eXAx7hGuYKek1U09pP0jDUFe8= X-Google-Smtp-Source: APXvYqwC9P8HaWM223eOEegLFhN5JV0hs/CGnhSkDLW2WnMpfDSnC18x/rIf914nZTxS1PdDesEi4SVAvns= X-Received: by 2002:a63:480f:: with SMTP id v15mr3361962pga.201.1575349888187; Mon, 02 Dec 2019 21:11:28 -0800 (PST) Date: Mon, 2 Dec 2019 21:10:45 -0800 In-Reply-To: <20191203051049.44573-1-drosen@google.com> Message-Id: <20191203051049.44573-5-drosen@google.com> Mime-Version: 1.0 References: <20191203051049.44573-1-drosen@google.com> X-Mailer: git-send-email 2.24.0.393.g34dc348eaf-goog 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 X-Headers-End: 1ic0uc-001gZL-8g Subject: [f2fs-dev] [PATCH 4/8] vfs: Fold casefolding into vfs X-BeenThere: linux-f2fs-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Daniel Rosenberg via Linux-f2fs-devel Reply-To: Daniel Rosenberg Cc: Daniel Rosenberg , linux-doc@vger.kernel.org, kernel-team@android.com, Jonathan Corbet , linux-kernel@vger.kernel.org, Andreas Dilger , linux-fsdevel@vger.kernel.org, Gabriel Krisman Bertazi Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: linux-f2fs-devel-bounces@lists.sourceforge.net Ext4 and F2fs are both using casefolding, and they, along with any other filesystem that adds the feature, will be using identical dentry_ops. Additionally, those dentry ops interfere with the dentry_ops required for fscrypt once we add support for casefolding and encryption. Moving this into the vfs removes code duplication as well as the complication with encryption. Currently this is pretty close to just moving the existing f2fs/ext4 code up a level into the vfs, although there is a lot of room for improvement now. Signed-off-by: Daniel Rosenberg --- fs/dcache.c | 35 +++++++++++++++++++++++++++++++++++ fs/namei.c | 43 ++++++++++++++++++++++++++++++++++++++++--- include/linux/fs.h | 12 ++++++++++++ 3 files changed, 87 insertions(+), 3 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index f7931b682a0d..575f3c2c3f77 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "internal.h" #include "mount.h" @@ -228,6 +229,13 @@ static inline int dentry_string_cmp(const unsigned char *cs, const unsigned char #endif +bool needs_casefold(const struct inode *dir) +{ + return IS_CASEFOLDED(dir) && + (!IS_ENCRYPTED(dir) || fscrypt_has_encryption_key(dir)); +} +EXPORT_SYMBOL(needs_casefold); + static inline int dentry_cmp(const struct dentry *dentry, const unsigned char *ct, unsigned tcount) { /* @@ -247,7 +255,19 @@ static inline int dentry_cmp(const struct dentry *dentry, const unsigned char *c * be no NUL in the ct/tcount data) */ const unsigned char *cs = READ_ONCE(dentry->d_name.name); +#ifdef CONFIG_UNICODE + struct inode *parent = dentry->d_parent->d_inode; + if (unlikely(needs_casefold(parent))) { + const struct qstr n1 = QSTR_INIT(cs, tcount); + const struct qstr n2 = QSTR_INIT(ct, tcount); + int result = utf8_strncasecmp(dentry->d_sb->s_encoding, + &n1, &n2); + + if (result >= 0 || sb_has_enc_strict_mode(dentry->d_sb)) + return result; + } +#endif return dentry_string_cmp(cs, ct, tcount); } @@ -2404,7 +2424,22 @@ struct dentry *d_hash_and_lookup(struct dentry *dir, struct qstr *name) * calculate the standard hash first, as the d_op->d_hash() * routine may choose to leave the hash value unchanged. */ +#ifdef CONFIG_UNICODE + unsigned char *hname = NULL; + int hlen = name->len; + + if (IS_CASEFOLDED(dir->d_inode)) { + hname = kmalloc(PATH_MAX, GFP_ATOMIC); + if (!hname) + return ERR_PTR(-ENOMEM); + hlen = utf8_casefold(dir->d_sb->s_encoding, + name, hname, PATH_MAX); + } + name->hash = full_name_hash(dir, hname ?: name->name, hlen); + kfree(hname); +#else name->hash = full_name_hash(dir, name->name, name->len); +#endif if (dir->d_flags & DCACHE_OP_HASH) { int err = dir->d_op->d_hash(dir, name); if (unlikely(err < 0)) diff --git a/fs/namei.c b/fs/namei.c index 2dda552bcf7a..b8d5cb0994ec 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -39,6 +39,7 @@ #include #include #include +#include #include "internal.h" #include "mount.h" @@ -2062,6 +2063,10 @@ static inline u64 hash_name(const void *salt, const char *name) static int link_path_walk(const char *name, struct nameidata *nd) { int err; +#ifdef CONFIG_UNICODE + char *hname = NULL; + int hlen = 0; +#endif if (IS_ERR(name)) return PTR_ERR(name); @@ -2078,9 +2083,21 @@ static int link_path_walk(const char *name, struct nameidata *nd) err = may_lookup(nd); if (err) return err; - +#ifdef CONFIG_UNICODE + if (needs_casefold(nd->path.dentry->d_inode)) { + struct qstr str = QSTR_INIT(name, PATH_MAX); + + hname = kmalloc(PATH_MAX, GFP_ATOMIC); + if (!hname) + return -ENOMEM; + hlen = utf8_casefold(nd->path.dentry->d_sb->s_encoding, + &str, hname, PATH_MAX); + } + hash_len = hash_name(nd->path.dentry, hname ?: name); + kfree(hname); +#else hash_len = hash_name(nd->path.dentry, name); - +#endif type = LAST_NORM; if (name[0] == '.') switch (hashlen_len(hash_len)) { case 2: @@ -2452,9 +2469,29 @@ EXPORT_SYMBOL(vfs_path_lookup); static int lookup_one_len_common(const char *name, struct dentry *base, int len, struct qstr *this) { +#ifdef CONFIG_UNICODE + char *hname = NULL; + int hlen = len; + + if (needs_casefold(base->d_inode)) { + struct qstr str = QSTR_INIT(name, len); + + hname = kmalloc(PATH_MAX, GFP_ATOMIC); + if (!hname) + return -ENOMEM; + hlen = utf8_casefold(base->d_sb->s_encoding, + &str, hname, PATH_MAX); + } + this->hash = full_name_hash(base, hname ?: name, hlen); + kvfree(hname); +#else + this->hash = full_name_hash(base, name, len); +#endif this->name = name; this->len = len; - this->hash = full_name_hash(base, name, len); +#ifdef CONFIG_UNICODE + kfree(hname); +#endif if (!len) return -EACCES; diff --git a/include/linux/fs.h b/include/linux/fs.h index c159a8bdee8b..38d1c20f3e6f 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1382,6 +1382,12 @@ extern int send_sigurg(struct fown_struct *fown); #define SB_ACTIVE (1<<30) #define SB_NOUSER (1<<31) +/* These flags relate to encoding and casefolding */ +#define SB_ENC_STRICT_MODE_FL (1 << 0) + +#define sb_has_enc_strict_mode(sb) \ + (sb->s_encoding_flags & SB_ENC_STRICT_MODE_FL) + /* * Umount options */ @@ -1449,6 +1455,10 @@ struct super_block { #endif #ifdef CONFIG_FS_VERITY const struct fsverity_operations *s_vop; +#endif +#ifdef CONFIG_UNICODE + struct unicode_map *s_encoding; + __u16 s_encoding_flags; #endif struct hlist_bl_head s_roots; /* alternate root dentries for NFS */ struct list_head s_mounts; /* list of mounts; _not_ for fs use */ @@ -2044,6 +2054,8 @@ static inline bool sb_rdonly(const struct super_block *sb) { return sb->s_flags #define IS_WHITEOUT(inode) (S_ISCHR(inode->i_mode) && \ (inode)->i_rdev == WHITEOUT_DEV) +extern bool needs_casefold(const struct inode *dir); + static inline bool HAS_UNMAPPED_ID(struct inode *inode) { return !uid_valid(inode->i_uid) || !gid_valid(inode->i_gid); -- 2.24.0.393.g34dc348eaf-goog _______________________________________________ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel