From patchwork Sat Aug 12 00:41:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gabriel Krisman Bertazi X-Patchwork-Id: 13351600 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EB322C41513 for ; Sat, 12 Aug 2023 00:41:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229734AbjHLAl7 (ORCPT ); Fri, 11 Aug 2023 20:41:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52308 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237108AbjHLAl6 (ORCPT ); Fri, 11 Aug 2023 20:41:58 -0400 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4A8CC3581; Fri, 11 Aug 2023 17:41:57 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id EFB4D1F385; Sat, 12 Aug 2023 00:41:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1691800915; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=gc3ImIlvvNAlNv89w2x2DqtkUeFquTvzH0e1HxxlakQ=; b=WPNMe74pRP9y1F4AfbMzA7v1wLaAk+rqQH4j7Fc2IBMN/lncSw4YpqM716vOqVqmsL7zjC AELb8iIU2hVGEdbcS6eTnI4op/H7W2sNkgx3DZnAXSs3b+rQnvpI0LT10+cr/UoQdkIIUP 928H4kORANFovpX4ZSoZPfMpbAgCLKU= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1691800915; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=gc3ImIlvvNAlNv89w2x2DqtkUeFquTvzH0e1HxxlakQ=; b=7bO/NmKNxiJ/5BFD5zAPqsdas9fCtjTJzsBfJlhynDqUada/lYz9mNV5xKH3cMHPZTSPUK 9jxi+CQumQORzSDA== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id B712213592; Sat, 12 Aug 2023 00:41:55 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id TcJ7JlPV1mQLEAAAMHmgww (envelope-from ); Sat, 12 Aug 2023 00:41:55 +0000 From: Gabriel Krisman Bertazi To: viro@zeniv.linux.org.uk, brauner@kernel.org, tytso@mit.edu, ebiggers@kernel.org, jaegeuk@kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, Gabriel Krisman Bertazi Subject: [PATCH v5 01/10] fs: Expose helper to check if a directory needs casefolding Date: Fri, 11 Aug 2023 20:41:37 -0400 Message-ID: <20230812004146.30980-2-krisman@suse.de> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230812004146.30980-1-krisman@suse.de> References: <20230812004146.30980-1-krisman@suse.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org In preparation to use it in ecryptfs, move needs_casefolding into a public header and give it a namespaced name. Signed-off-by: Gabriel Krisman Bertazi --- fs/libfs.c | 14 ++------------ include/linux/fs.h | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/fs/libfs.c b/fs/libfs.c index 5b851315eeed..8d0b64cfd5da 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -1381,16 +1381,6 @@ bool is_empty_dir_inode(struct inode *inode) } #if IS_ENABLED(CONFIG_UNICODE) -/* - * Determine if the name of a dentry should be casefolded. - * - * Return: if names will need casefolding - */ -static bool needs_casefold(const struct inode *dir) -{ - return IS_CASEFOLDED(dir) && dir->i_sb->s_encoding; -} - /** * generic_ci_d_compare - generic d_compare implementation for casefolding filesystems * @dentry: dentry whose name we are checking against @@ -1411,7 +1401,7 @@ static int generic_ci_d_compare(const struct dentry *dentry, unsigned int len, char strbuf[DNAME_INLINE_LEN]; int ret; - if (!dir || !needs_casefold(dir)) + if (!dir || !dir_is_casefolded(dir)) goto fallback; /* * If the dentry name is stored in-line, then it may be concurrently @@ -1453,7 +1443,7 @@ static int generic_ci_d_hash(const struct dentry *dentry, struct qstr *str) const struct unicode_map *um = sb->s_encoding; int ret = 0; - if (!dir || !needs_casefold(dir)) + if (!dir || !dir_is_casefolded(dir)) return 0; ret = utf8_casefold_hash(um, dentry, str); diff --git a/include/linux/fs.h b/include/linux/fs.h index 6867512907d6..e3b631c6d24a 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -3213,6 +3213,27 @@ static inline bool dir_relax_shared(struct inode *inode) return !IS_DEADDIR(inode); } +/** + * dir_is_casefolded - Safely determine if filenames inside of a + * directory should be casefolded. + * @dir: The directory inode to be checked + * + * Filesystems should usually rely on this instead of checking the + * S_CASEFOLD flag directly when handling inodes, to avoid surprises + * with corrupted volumes. Checking i_sb->s_encoding ensures the + * filesystem knows how to deal with case-insensitiveness. + * + * Return: if names will need casefolding + */ +static inline bool dir_is_casefolded(const struct inode *dir) +{ +#if IS_ENABLED(CONFIG_UNICODE) + return IS_CASEFOLDED(dir) && dir->i_sb->s_encoding; +#else + return false; +#endif +} + extern bool path_noexec(const struct path *path); extern void inode_nohighmem(struct inode *inode); From patchwork Sat Aug 12 00:41:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gabriel Krisman Bertazi X-Patchwork-Id: 13351601 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3609DC04A6A for ; Sat, 12 Aug 2023 00:42:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237152AbjHLAmA (ORCPT ); Fri, 11 Aug 2023 20:42:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52312 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237149AbjHLAl6 (ORCPT ); Fri, 11 Aug 2023 20:41:58 -0400 Received: from smtp-out1.suse.de (smtp-out1.suse.de [IPv6:2001:67c:2178:6::1c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AFEA6A6; Fri, 11 Aug 2023 17:41:58 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 74A9321885; Sat, 12 Aug 2023 00:41:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1691800917; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=QeHgxjk4qHnUIIhBwhEx6gXjURKH4sMFZ4pmLOe7O5w=; b=M6lRGsatagECls+mo8KGm78FfdQNZ0/jdVBKAP2Rjx38U8NAhTPq35gZsf3OG0BXO5lhBe AZV09l4MIYo9KIIWjfZlETOF2FOth0F0Py0OnBenFTEap296C6KgSW2/n1z8YVPoUlqPnh FZ1V/i4WF3IiucfCmuz+3CXKxAVdeJk= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1691800917; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=QeHgxjk4qHnUIIhBwhEx6gXjURKH4sMFZ4pmLOe7O5w=; b=jdAiTm5V8dYFS+EC0KOhewhYD6Pnb2AOJIKuth5oWk5h01Az2PxQv7mF9t1gVmCY+vIo+i PNq6DtbNGaHLGQDA== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 4031313592; Sat, 12 Aug 2023 00:41:57 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id 95cQClXV1mQNEAAAMHmgww (envelope-from ); Sat, 12 Aug 2023 00:41:57 +0000 From: Gabriel Krisman Bertazi To: viro@zeniv.linux.org.uk, brauner@kernel.org, tytso@mit.edu, ebiggers@kernel.org, jaegeuk@kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, Gabriel Krisman Bertazi Subject: [PATCH v5 02/10] ecryptfs: Reject casefold directory inodes Date: Fri, 11 Aug 2023 20:41:38 -0400 Message-ID: <20230812004146.30980-3-krisman@suse.de> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230812004146.30980-1-krisman@suse.de> References: <20230812004146.30980-1-krisman@suse.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Even though it seems to be able to resolve some names of case-insensitive directories, the lack of d_hash and d_compare means we end up with a broken state in the d_cache. Considering it was never a goal to support these two together, and we are preparing to use d_revalidate in case-insensitive filesystems, which would make the combination even more broken, reject any attempt to get a casefolded inode from ecryptfs. Signed-off-by: Gabriel Krisman Bertazi --- fs/ecryptfs/inode.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 83274915ba6d..1305dc49df78 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -78,6 +78,14 @@ static struct inode *__ecryptfs_get_inode(struct inode *lower_inode, if (lower_inode->i_sb != ecryptfs_superblock_to_lower(sb)) return ERR_PTR(-EXDEV); + + /* Reject dealing with casefold directories. */ + if (S_ISDIR(lower_inode->i_mode) && dir_is_casefolded(lower_inode)) { + pr_err_ratelimited("%s: Can't handle casefolded directory.\n", + __func__); + return ERR_PTR(-EREMOTE); + } + if (!igrab(lower_inode)) return ERR_PTR(-ESTALE); inode = iget5_locked(sb, (unsigned long)lower_inode, From patchwork Sat Aug 12 00:41:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gabriel Krisman Bertazi X-Patchwork-Id: 13351603 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 28A75C04FE0 for ; Sat, 12 Aug 2023 00:42:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237183AbjHLAmC (ORCPT ); Fri, 11 Aug 2023 20:42:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58278 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237156AbjHLAmA (ORCPT ); Fri, 11 Aug 2023 20:42:00 -0400 Received: from smtp-out1.suse.de (smtp-out1.suse.de [IPv6:2001:67c:2178:6::1c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4D246A6; Fri, 11 Aug 2023 17:42:00 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id EEB07218E6; Sat, 12 Aug 2023 00:41:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1691800918; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ZLSJltA607r7xtpPPkkvUfJUZbMcdXItzz2TC+sxABk=; b=SQTOGHNV2KiavvzoucAG5T8Vw5AFv5EqUIT7kv7/ngcaAqlx47a8XJNITsEjC5YDJ/KbXw wenk5fzYjOmUCtWwimhSa3Zgkhx2H3QRzrEmmVANv2AGmz9VV+eBxyTDPMjATet6RyV6dq 9aRrHOSeHurjemQaGcy+dOVl5DFOeMk= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1691800918; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ZLSJltA607r7xtpPPkkvUfJUZbMcdXItzz2TC+sxABk=; b=t+aMxO4dfWreIRpbqekuGL5xR6qXonpBXp/46PoO9x4xKG7WBEvCyDBYbyG/pPKaw67Waj 7a6q0bcfAfohLZCA== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id BA1F713592; Sat, 12 Aug 2023 00:41:58 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id nwbYJ1bV1mQREAAAMHmgww (envelope-from ); Sat, 12 Aug 2023 00:41:58 +0000 From: Gabriel Krisman Bertazi To: viro@zeniv.linux.org.uk, brauner@kernel.org, tytso@mit.edu, ebiggers@kernel.org, jaegeuk@kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, Gabriel Krisman Bertazi Subject: [PATCH v5 03/10] 9p: Split ->weak_revalidate from ->revalidate Date: Fri, 11 Aug 2023 20:41:39 -0400 Message-ID: <20230812004146.30980-4-krisman@suse.de> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230812004146.30980-1-krisman@suse.de> References: <20230812004146.30980-1-krisman@suse.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org In preparation to change the signature of dentry_ops->revalidate, avoid reusing the handler directly for d_weak_revalidate in 9p. Signed-off-by: Gabriel Krisman Bertazi --- fs/9p/vfs_dentry.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c index f16f73581634..0c6fa1f53530 100644 --- a/fs/9p/vfs_dentry.c +++ b/fs/9p/vfs_dentry.c @@ -94,9 +94,15 @@ static int v9fs_lookup_revalidate(struct dentry *dentry, unsigned int flags) return 1; } +static int v9fs_lookup_weak_revalidate(struct dentry *dentry, + unsigned int flags) +{ + return v9fs_lookup_revalidate(dentry, flags); +} + const struct dentry_operations v9fs_cached_dentry_operations = { .d_revalidate = v9fs_lookup_revalidate, - .d_weak_revalidate = v9fs_lookup_revalidate, + .d_weak_revalidate = v9fs_lookup_weak_revalidate, .d_delete = v9fs_cached_dentry_delete, .d_release = v9fs_dentry_release, }; From patchwork Sat Aug 12 00:41:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gabriel Krisman Bertazi X-Patchwork-Id: 13351604 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AB8ADC41513 for ; Sat, 12 Aug 2023 00:42:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237210AbjHLAmE (ORCPT ); Fri, 11 Aug 2023 20:42:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58288 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237156AbjHLAmD (ORCPT ); Fri, 11 Aug 2023 20:42:03 -0400 Received: from smtp-out1.suse.de (smtp-out1.suse.de [IPv6:2001:67c:2178:6::1c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1F563A6; Fri, 11 Aug 2023 17:42:02 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id CA75F218ED; Sat, 12 Aug 2023 00:42:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1691800920; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=CmJfT1nmKi9TBJihLOUVJWtNn9PwJXKiJfPTJpvjICw=; b=TbWt1QoVCbqhLC1oqUn8dcFnmT/avQk/jNM+pLBhceF0W2enoNQHWV3P0g9YUrz50HGMyj Kt/FYahT7bxBVbVaDLwMcYYoCtk1MvNTroqMrid3o0TY7xrfKLcG63B7Fn9zFohdNY6oh6 XEhfaeJGi/LwzBxsqM5hEbICqAOTA0w= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1691800920; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=CmJfT1nmKi9TBJihLOUVJWtNn9PwJXKiJfPTJpvjICw=; b=KcDPHboekPO5hHU9Pf8PEunD2KIoLFC2Fe5YJYije4zkP9sCDw1m/dcea2ghZt8UuXXcKp +VK3WJRATfGFnuAA== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 7BA0313592; Sat, 12 Aug 2023 00:42:00 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id Vxm5GFjV1mQUEAAAMHmgww (envelope-from ); Sat, 12 Aug 2023 00:42:00 +0000 From: Gabriel Krisman Bertazi To: viro@zeniv.linux.org.uk, brauner@kernel.org, tytso@mit.edu, ebiggers@kernel.org, jaegeuk@kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, Gabriel Krisman Bertazi , Gabriel Krisman Bertazi Subject: [PATCH v5 04/10] fs: Expose name under lookup to d_revalidate hooks Date: Fri, 11 Aug 2023 20:41:40 -0400 Message-ID: <20230812004146.30980-5-krisman@suse.de> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230812004146.30980-1-krisman@suse.de> References: <20230812004146.30980-1-krisman@suse.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org From: Gabriel Krisman Bertazi Negative dentries support on case-insensitive ext4/f2fs will require access to the name under lookup to ensure it matches the dentry. This adds the information on d_revalidate and updates its implementation. This was done through a Coccinelle hook and tested by building with allyesconfig. Signed-off-by: Gabriel Krisman Bertazi --- Changes since v3: - Merge d_revalidate_name with d_revalidate (Christian) - Drop Ted's r-b since patch changed quite a bit. (Me) Changes since v2: - Document d_revalidate_name hook. (Eric) --- Documentation/filesystems/locking.rst | 3 ++- Documentation/filesystems/vfs.rst | 11 ++++++++++- fs/9p/vfs_dentry.c | 5 +++-- fs/afs/dir.c | 6 ++++-- fs/afs/dynroot.c | 4 +++- fs/ceph/dir.c | 3 ++- fs/coda/dir.c | 3 ++- fs/crypto/fname.c | 3 ++- fs/ecryptfs/dentry.c | 5 +++-- fs/exfat/namei.c | 3 ++- fs/fat/namei_vfat.c | 6 ++++-- fs/fuse/dir.c | 3 ++- fs/gfs2/dentry.c | 3 ++- fs/hfs/sysdep.c | 3 ++- fs/jfs/namei.c | 3 ++- fs/kernfs/dir.c | 3 ++- fs/namei.c | 18 ++++++++++-------- fs/nfs/dir.c | 9 ++++++--- fs/ocfs2/dcache.c | 4 +++- fs/orangefs/dcache.c | 3 ++- fs/overlayfs/super.c | 20 ++++++++++++-------- fs/proc/base.c | 6 ++++-- fs/proc/fd.c | 3 ++- fs/proc/generic.c | 6 ++++-- fs/proc/proc_sysctl.c | 3 ++- fs/reiserfs/xattr.c | 3 ++- fs/smb/client/dir.c | 3 ++- fs/vboxsf/dir.c | 4 +++- include/linux/dcache.h | 2 +- include/linux/fscrypt.h | 4 +++- 30 files changed, 103 insertions(+), 52 deletions(-) diff --git a/Documentation/filesystems/locking.rst b/Documentation/filesystems/locking.rst index ed148919e11a..1603c53a1688 100644 --- a/Documentation/filesystems/locking.rst +++ b/Documentation/filesystems/locking.rst @@ -17,7 +17,8 @@ dentry_operations prototypes:: - int (*d_revalidate)(struct dentry *, unsigned int); + int (*d_revalidate)(struct dentry *, const struct qstr *, + unsigned int); int (*d_weak_revalidate)(struct dentry *, unsigned int); int (*d_hash)(const struct dentry *, struct qstr *); int (*d_compare)(const struct dentry *, diff --git a/Documentation/filesystems/vfs.rst b/Documentation/filesystems/vfs.rst index cb2a97e49872..ddd542c2a722 100644 --- a/Documentation/filesystems/vfs.rst +++ b/Documentation/filesystems/vfs.rst @@ -1251,7 +1251,8 @@ defined: .. code-block:: c struct dentry_operations { - int (*d_revalidate)(struct dentry *, unsigned int); + int (*d_revalidate)(struct dentry *, const struct qstr *, + unsigned int); int (*d_weak_revalidate)(struct dentry *, unsigned int); int (*d_hash)(const struct dentry *, struct qstr *); int (*d_compare)(const struct dentry *, @@ -1284,6 +1285,14 @@ defined: they can change and, in d_inode case, even become NULL under us). + Filesystems shouldn't rely on the name under lookup, unless + there are particular filename encoding semantics to be handled + during revalidation. Note the name under lookup can change from + under d_revalidate, so it must be protected with ->d_lock before + accessing. The exception is when revalidating negative dentries + for creation, in which case the parent inode prevents it from + changing. + If a situation is encountered that rcu-walk cannot handle, return -ECHILD and it will be called again in ref-walk mode. diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c index 0c6fa1f53530..de679d9505db 100644 --- a/fs/9p/vfs_dentry.c +++ b/fs/9p/vfs_dentry.c @@ -56,7 +56,8 @@ static void v9fs_dentry_release(struct dentry *dentry) dentry->d_fsdata = NULL; } -static int v9fs_lookup_revalidate(struct dentry *dentry, unsigned int flags) +static int v9fs_lookup_revalidate(struct dentry *dentry, + const struct qstr *name, unsigned int flags) { struct p9_fid *fid; struct inode *inode; @@ -97,7 +98,7 @@ static int v9fs_lookup_revalidate(struct dentry *dentry, unsigned int flags) static int v9fs_lookup_weak_revalidate(struct dentry *dentry, unsigned int flags) { - return v9fs_lookup_revalidate(dentry, flags); + return v9fs_lookup_revalidate(dentry, NULL, flags); } const struct dentry_operations v9fs_cached_dentry_operations = { diff --git a/fs/afs/dir.c b/fs/afs/dir.c index 5219182e52e1..e3ba14512715 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c @@ -21,7 +21,8 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags); static int afs_dir_open(struct inode *inode, struct file *file); static int afs_readdir(struct file *file, struct dir_context *ctx); -static int afs_d_revalidate(struct dentry *dentry, unsigned int flags); +static int afs_d_revalidate(struct dentry *dentry, const struct qstr *name, + unsigned int flags); static int afs_d_delete(const struct dentry *dentry); static void afs_d_iput(struct dentry *dentry, struct inode *inode); static bool afs_lookup_one_filldir(struct dir_context *ctx, const char *name, int nlen, @@ -1084,7 +1085,8 @@ static int afs_d_revalidate_rcu(struct dentry *dentry) * - NOTE! the hit can be a negative hit too, so we can't assume we have an * inode */ -static int afs_d_revalidate(struct dentry *dentry, unsigned int flags) +static int afs_d_revalidate(struct dentry *dentry, const struct qstr *name, + unsigned int flags) { struct afs_vnode *vnode, *dir; struct afs_fid fid; diff --git a/fs/afs/dynroot.c b/fs/afs/dynroot.c index d7d9402ff718..44a8f736eaf8 100644 --- a/fs/afs/dynroot.c +++ b/fs/afs/dynroot.c @@ -247,7 +247,9 @@ const struct inode_operations afs_dynroot_inode_operations = { /* * Dirs in the dynamic root don't need revalidation. */ -static int afs_dynroot_d_revalidate(struct dentry *dentry, unsigned int flags) +static int afs_dynroot_d_revalidate(struct dentry *dentry, + const struct qstr *name, + unsigned int flags) { return 1; } diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 4a2b39d9a61a..dffc115adae0 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c @@ -1758,7 +1758,8 @@ static int dir_lease_is_valid(struct inode *dir, struct dentry *dentry, /* * Check if cached dentry can be trusted. */ -static int ceph_d_revalidate(struct dentry *dentry, unsigned int flags) +static int ceph_d_revalidate(struct dentry *dentry, const struct qstr *name, + unsigned int flags) { int valid = 0; struct dentry *parent; diff --git a/fs/coda/dir.c b/fs/coda/dir.c index 8450b1bd354b..bb2ecac4a7e7 100644 --- a/fs/coda/dir.c +++ b/fs/coda/dir.c @@ -452,7 +452,8 @@ static int coda_readdir(struct file *coda_file, struct dir_context *ctx) } /* called when a cache lookup succeeds */ -static int coda_dentry_revalidate(struct dentry *de, unsigned int flags) +static int coda_dentry_revalidate(struct dentry *de, const struct qstr *name, + unsigned int flags) { struct inode *inode; struct coda_inode_info *cii; diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c index 6eae3f12ad50..d543e4648a0f 100644 --- a/fs/crypto/fname.c +++ b/fs/crypto/fname.c @@ -580,7 +580,8 @@ EXPORT_SYMBOL_GPL(fscrypt_fname_siphash); * Validate dentries in encrypted directories to make sure we aren't potentially * caching stale dentries after a key has been added. */ -int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags) +int fscrypt_d_revalidate(struct dentry *dentry, const struct qstr *name, + unsigned int flags) { struct dentry *dir; int err; diff --git a/fs/ecryptfs/dentry.c b/fs/ecryptfs/dentry.c index acaa0825e9bb..56093648d838 100644 --- a/fs/ecryptfs/dentry.c +++ b/fs/ecryptfs/dentry.c @@ -28,7 +28,8 @@ * Returns 1 if valid, 0 otherwise. * */ -static int ecryptfs_d_revalidate(struct dentry *dentry, unsigned int flags) +static int ecryptfs_d_revalidate(struct dentry *dentry, + const struct qstr *name, unsigned int flags) { struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); int rc = 1; @@ -37,7 +38,7 @@ static int ecryptfs_d_revalidate(struct dentry *dentry, unsigned int flags) return -ECHILD; if (lower_dentry->d_flags & DCACHE_OP_REVALIDATE) - rc = lower_dentry->d_op->d_revalidate(lower_dentry, flags); + rc = lower_dentry->d_op->d_revalidate(lower_dentry, name, flags); if (d_really_is_positive(dentry)) { struct inode *inode = d_inode(dentry); diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c index e0ff9d156f6f..6220046a687b 100644 --- a/fs/exfat/namei.c +++ b/fs/exfat/namei.c @@ -31,7 +31,8 @@ static inline void exfat_d_version_set(struct dentry *dentry, * If it happened, the negative dentry isn't actually negative anymore. So, * drop it. */ -static int exfat_d_revalidate(struct dentry *dentry, unsigned int flags) +static int exfat_d_revalidate(struct dentry *dentry, const struct qstr *name, + unsigned int flags) { int ret; diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index c4d00999a433..73981b0e4ea7 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c @@ -53,7 +53,8 @@ static int vfat_revalidate_shortname(struct dentry *dentry) return ret; } -static int vfat_revalidate(struct dentry *dentry, unsigned int flags) +static int vfat_revalidate(struct dentry *dentry, const struct qstr *name, + unsigned int flags) { if (flags & LOOKUP_RCU) return -ECHILD; @@ -64,7 +65,8 @@ static int vfat_revalidate(struct dentry *dentry, unsigned int flags) return vfat_revalidate_shortname(dentry); } -static int vfat_revalidate_ci(struct dentry *dentry, unsigned int flags) +static int vfat_revalidate_ci(struct dentry *dentry, const struct qstr *name, + unsigned int flags) { if (flags & LOOKUP_RCU) return -ECHILD; diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 35bc174f9ba2..948bbfc1aae4 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -202,7 +202,8 @@ static void fuse_lookup_init(struct fuse_conn *fc, struct fuse_args *args, * the lookup once more. If the lookup results in the same inode, * then refresh the attributes, timeouts and mark the dentry valid. */ -static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags) +static int fuse_dentry_revalidate(struct dentry *entry, + const struct qstr *name, unsigned int flags) { struct inode *inode; struct dentry *parent; diff --git a/fs/gfs2/dentry.c b/fs/gfs2/dentry.c index 2e215e8c3c88..3dd93d36aaf2 100644 --- a/fs/gfs2/dentry.c +++ b/fs/gfs2/dentry.c @@ -30,7 +30,8 @@ * Returns: 1 if the dentry is ok, 0 if it isn't */ -static int gfs2_drevalidate(struct dentry *dentry, unsigned int flags) +static int gfs2_drevalidate(struct dentry *dentry, const struct qstr *name, + unsigned int flags) { struct dentry *parent; struct gfs2_sbd *sdp; diff --git a/fs/hfs/sysdep.c b/fs/hfs/sysdep.c index 2875961fdc10..68fb32f4fbb8 100644 --- a/fs/hfs/sysdep.c +++ b/fs/hfs/sysdep.c @@ -13,7 +13,8 @@ /* dentry case-handling: just lowercase everything */ -static int hfs_revalidate_dentry(struct dentry *dentry, unsigned int flags) +static int hfs_revalidate_dentry(struct dentry *dentry, + const struct qstr *name, unsigned int flags) { struct inode *inode; int diff; diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 9b030297aa64..0d2b5b54e2d8 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c @@ -1573,7 +1573,8 @@ static int jfs_ci_compare(const struct dentry *dentry, return result; } -static int jfs_ci_revalidate(struct dentry *dentry, unsigned int flags) +static int jfs_ci_revalidate(struct dentry *dentry, const struct qstr *name, + unsigned int flags) { /* * This is not negative dentry. Always valid. diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 5a1a4af9d3d2..820988710ce5 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -1084,7 +1084,8 @@ struct kernfs_node *kernfs_create_empty_dir(struct kernfs_node *parent, return ERR_PTR(rc); } -static int kernfs_dop_revalidate(struct dentry *dentry, unsigned int flags) +static int kernfs_dop_revalidate(struct dentry *dentry, + const struct qstr *name, unsigned int flags) { struct kernfs_node *kn; struct kernfs_root *root; diff --git a/fs/namei.c b/fs/namei.c index e56ff39a79bc..7631c762217a 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -853,10 +853,12 @@ static bool try_to_unlazy_next(struct nameidata *nd, struct dentry *dentry) return false; } -static inline int d_revalidate(struct dentry *dentry, unsigned int flags) +static inline int d_revalidate(struct dentry *dentry, + const struct qstr *name, + unsigned int flags) { if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE)) - return dentry->d_op->d_revalidate(dentry, flags); + return dentry->d_op->d_revalidate(dentry, name, flags); else return 1; } @@ -1565,7 +1567,7 @@ static struct dentry *lookup_dcache(const struct qstr *name, { struct dentry *dentry = d_lookup(dir, name); if (dentry) { - int error = d_revalidate(dentry, flags); + int error = d_revalidate(dentry, name, flags); if (unlikely(error <= 0)) { if (!error) d_invalidate(dentry); @@ -1636,19 +1638,19 @@ static struct dentry *lookup_fast(struct nameidata *nd) if (read_seqcount_retry(&parent->d_seq, nd->seq)) return ERR_PTR(-ECHILD); - status = d_revalidate(dentry, nd->flags); + status = d_revalidate(dentry, &nd->last, nd->flags); if (likely(status > 0)) return dentry; if (!try_to_unlazy_next(nd, dentry)) return ERR_PTR(-ECHILD); if (status == -ECHILD) /* we'd been told to redo it in non-rcu mode */ - status = d_revalidate(dentry, nd->flags); + status = d_revalidate(dentry, &nd->last, nd->flags); } else { dentry = __d_lookup(parent, &nd->last); if (unlikely(!dentry)) return NULL; - status = d_revalidate(dentry, nd->flags); + status = d_revalidate(dentry, &nd->last, nd->flags); } if (unlikely(status <= 0)) { if (!status) @@ -1676,7 +1678,7 @@ static struct dentry *__lookup_slow(const struct qstr *name, if (IS_ERR(dentry)) return dentry; if (unlikely(!d_in_lookup(dentry))) { - int error = d_revalidate(dentry, flags); + int error = d_revalidate(dentry, name, flags); if (unlikely(error <= 0)) { if (!error) { d_invalidate(dentry); @@ -3421,7 +3423,7 @@ static struct dentry *lookup_open(struct nameidata *nd, struct file *file, if (d_in_lookup(dentry)) break; - error = d_revalidate(dentry, nd->flags); + error = d_revalidate(dentry, &nd->last, nd->flags); if (likely(error > 0)) break; if (error) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 8f3112e71a6a..be162ef6a24e 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -1805,7 +1805,8 @@ __nfs_lookup_revalidate(struct dentry *dentry, unsigned int flags, return ret; } -static int nfs_lookup_revalidate(struct dentry *dentry, unsigned int flags) +static int nfs_lookup_revalidate(struct dentry *dentry, + const struct qstr *name, unsigned int flags) { return __nfs_lookup_revalidate(dentry, flags, nfs_do_lookup_revalidate); } @@ -1993,7 +1994,8 @@ void nfs_d_prune_case_insensitive_aliases(struct inode *inode) EXPORT_SYMBOL_GPL(nfs_d_prune_case_insensitive_aliases); #if IS_ENABLED(CONFIG_NFS_V4) -static int nfs4_lookup_revalidate(struct dentry *, unsigned int); +static int nfs4_lookup_revalidate(struct dentry *, const struct qstr *name, + unsigned int); const struct dentry_operations nfs4_dentry_operations = { .d_revalidate = nfs4_lookup_revalidate, @@ -2226,7 +2228,8 @@ nfs4_do_lookup_revalidate(struct inode *dir, struct dentry *dentry, return nfs_do_lookup_revalidate(dir, dentry, flags); } -static int nfs4_lookup_revalidate(struct dentry *dentry, unsigned int flags) +static int nfs4_lookup_revalidate(struct dentry *dentry, + const struct qstr *name, unsigned int flags) { return __nfs_lookup_revalidate(dentry, flags, nfs4_do_lookup_revalidate); diff --git a/fs/ocfs2/dcache.c b/fs/ocfs2/dcache.c index 04fc8344063a..277757f4fd2d 100644 --- a/fs/ocfs2/dcache.c +++ b/fs/ocfs2/dcache.c @@ -32,7 +32,9 @@ void ocfs2_dentry_attach_gen(struct dentry *dentry) } -static int ocfs2_dentry_revalidate(struct dentry *dentry, unsigned int flags) +static int ocfs2_dentry_revalidate(struct dentry *dentry, + const struct qstr *name, + unsigned int flags) { struct inode *inode; int ret = 0; /* if all else fails, just return false */ diff --git a/fs/orangefs/dcache.c b/fs/orangefs/dcache.c index 8bbe9486e3a6..435b88007809 100644 --- a/fs/orangefs/dcache.c +++ b/fs/orangefs/dcache.c @@ -94,7 +94,8 @@ static int orangefs_revalidate_lookup(struct dentry *dentry) * * Should return 1 if dentry can still be trusted, else 0. */ -static int orangefs_d_revalidate(struct dentry *dentry, unsigned int flags) +static int orangefs_d_revalidate(struct dentry *dentry, + const struct qstr *name, unsigned int flags) { int ret; unsigned long time = (unsigned long) dentry->d_fsdata; diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index 5b069f1a1e44..1233e38d029d 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -77,7 +77,8 @@ static struct dentry *ovl_d_real(struct dentry *dentry, return dentry; } -static int ovl_revalidate_real(struct dentry *d, unsigned int flags, bool weak) +static int ovl_revalidate_real(struct dentry *d, const struct qstr *name, + unsigned int flags, bool weak) { int ret = 1; @@ -88,7 +89,7 @@ static int ovl_revalidate_real(struct dentry *d, unsigned int flags, bool weak) if (d->d_flags & DCACHE_OP_WEAK_REVALIDATE) ret = d->d_op->d_weak_revalidate(d, flags); } else if (d->d_flags & DCACHE_OP_REVALIDATE) { - ret = d->d_op->d_revalidate(d, flags); + ret = d->d_op->d_revalidate(d, name, flags); if (!ret) { if (!(flags & LOOKUP_RCU)) d_invalidate(d); @@ -99,6 +100,7 @@ static int ovl_revalidate_real(struct dentry *d, unsigned int flags, bool weak) } static int ovl_dentry_revalidate_common(struct dentry *dentry, + const struct qstr *name, unsigned int flags, bool weak) { struct ovl_entry *oe = OVL_E(dentry); @@ -114,22 +116,24 @@ static int ovl_dentry_revalidate_common(struct dentry *dentry, upper = ovl_i_dentry_upper(inode); if (upper) - ret = ovl_revalidate_real(upper, flags, weak); + ret = ovl_revalidate_real(upper, name, flags, weak); for (i = 0; ret > 0 && i < ovl_numlower(oe); i++) - ret = ovl_revalidate_real(lowerstack[i].dentry, flags, weak); + ret = ovl_revalidate_real(lowerstack[i].dentry, name, flags, weak); return ret; } -static int ovl_dentry_revalidate(struct dentry *dentry, unsigned int flags) +static int ovl_dentry_revalidate(struct dentry *dentry, + const struct qstr *name, unsigned int flags) { - return ovl_dentry_revalidate_common(dentry, flags, false); + return ovl_dentry_revalidate_common(dentry, name, flags, false); } -static int ovl_dentry_weak_revalidate(struct dentry *dentry, unsigned int flags) +static int ovl_dentry_weak_revalidate(struct dentry *dentry, + unsigned int flags) { - return ovl_dentry_revalidate_common(dentry, flags, true); + return ovl_dentry_revalidate_common(dentry, NULL, flags, true); } static const struct dentry_operations ovl_dentry_operations = { diff --git a/fs/proc/base.c b/fs/proc/base.c index 05452c3b9872..bdf212c52c8f 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -2005,7 +2005,8 @@ void pid_update_inode(struct task_struct *task, struct inode *inode) * performed a setuid(), etc. * */ -static int pid_revalidate(struct dentry *dentry, unsigned int flags) +static int pid_revalidate(struct dentry *dentry, const struct qstr *name, + unsigned int flags) { struct inode *inode; struct task_struct *task; @@ -2138,7 +2139,8 @@ static int dname_to_vma_addr(struct dentry *dentry, return 0; } -static int map_files_d_revalidate(struct dentry *dentry, unsigned int flags) +static int map_files_d_revalidate(struct dentry *dentry, + const struct qstr *name, unsigned int flags) { unsigned long vm_start, vm_end; bool exact_vma_exists = false; diff --git a/fs/proc/fd.c b/fs/proc/fd.c index b3140deebbbf..efd604fe8d82 100644 --- a/fs/proc/fd.c +++ b/fs/proc/fd.c @@ -136,7 +136,8 @@ static void tid_fd_update_inode(struct task_struct *task, struct inode *inode, security_task_to_inode(task, inode); } -static int tid_fd_revalidate(struct dentry *dentry, unsigned int flags) +static int tid_fd_revalidate(struct dentry *dentry, const struct qstr *name, + unsigned int flags) { struct task_struct *task; struct inode *inode; diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 42ae38ff6e7e..7cb15ab01a5a 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c @@ -216,7 +216,8 @@ void proc_free_inum(unsigned int inum) ida_simple_remove(&proc_inum_ida, inum - PROC_DYNAMIC_FIRST); } -static int proc_misc_d_revalidate(struct dentry *dentry, unsigned int flags) +static int proc_misc_d_revalidate(struct dentry *dentry, + const struct qstr *name, unsigned int flags) { if (flags & LOOKUP_RCU) return -ECHILD; @@ -343,7 +344,8 @@ static const struct file_operations proc_dir_operations = { .iterate_shared = proc_readdir, }; -static int proc_net_d_revalidate(struct dentry *dentry, unsigned int flags) +static int proc_net_d_revalidate(struct dentry *dentry, + const struct qstr *name, unsigned int flags) { return 0; } diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index 5ea42653126e..d067ebff1c74 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c @@ -886,7 +886,8 @@ static const struct inode_operations proc_sys_dir_operations = { .getattr = proc_sys_getattr, }; -static int proc_sys_revalidate(struct dentry *dentry, unsigned int flags) +static int proc_sys_revalidate(struct dentry *dentry, const struct qstr *name, + unsigned int flags) { if (flags & LOOKUP_RCU) return -ECHILD; diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 651027967159..2d09e4cdedd1 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -957,7 +957,8 @@ int reiserfs_permission(struct mnt_idmap *idmap, struct inode *inode, return generic_permission(&nop_mnt_idmap, inode, mask); } -static int xattr_hide_revalidate(struct dentry *dentry, unsigned int flags) +static int xattr_hide_revalidate(struct dentry *dentry, + const struct qstr *name, unsigned int flags) { return -EPERM; } diff --git a/fs/smb/client/dir.c b/fs/smb/client/dir.c index 30b1e1bfd204..0ced1a98de9f 100644 --- a/fs/smb/client/dir.c +++ b/fs/smb/client/dir.c @@ -714,7 +714,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, } static int -cifs_d_revalidate(struct dentry *direntry, unsigned int flags) +cifs_d_revalidate(struct dentry *direntry, const struct qstr *name, + unsigned int flags) { struct inode *inode; int rc; diff --git a/fs/vboxsf/dir.c b/fs/vboxsf/dir.c index 075f15c43c78..81a03a7331a4 100644 --- a/fs/vboxsf/dir.c +++ b/fs/vboxsf/dir.c @@ -191,7 +191,9 @@ const struct file_operations vboxsf_dir_fops = { * This is called during name resolution/lookup to check if the @dentry in * the cache is still valid. the job is handled by vboxsf_inode_revalidate. */ -static int vboxsf_dentry_revalidate(struct dentry *dentry, unsigned int flags) +static int vboxsf_dentry_revalidate(struct dentry *dentry, + const struct qstr *name, + unsigned int flags) { if (flags & LOOKUP_RCU) return -ECHILD; diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 6b351e009f59..9362e4ef0bad 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -126,7 +126,7 @@ enum dentry_d_lock_class }; struct dentry_operations { - int (*d_revalidate)(struct dentry *, unsigned int); + int (*d_revalidate)(struct dentry *, const struct qstr *, unsigned int); int (*d_weak_revalidate)(struct dentry *, unsigned int); int (*d_hash)(const struct dentry *, struct qstr *); int (*d_compare)(const struct dentry *, diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h index c895b12737a1..d8c68a366a2b 100644 --- a/include/linux/fscrypt.h +++ b/include/linux/fscrypt.h @@ -353,7 +353,8 @@ int fscrypt_fname_disk_to_usr(const struct inode *inode, bool fscrypt_match_name(const struct fscrypt_name *fname, const u8 *de_name, u32 de_name_len); u64 fscrypt_fname_siphash(const struct inode *dir, const struct qstr *name); -int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags); +int fscrypt_d_revalidate(struct dentry *dentry, const struct qstr *name, + unsigned int flags); /* bio.c */ bool fscrypt_decrypt_bio(struct bio *bio); @@ -647,6 +648,7 @@ static inline u64 fscrypt_fname_siphash(const struct inode *dir, } static inline int fscrypt_d_revalidate(struct dentry *dentry, + const struct qstr *name, unsigned int flags) { return 1; From patchwork Sat Aug 12 00:41:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gabriel Krisman Bertazi X-Patchwork-Id: 13351605 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7CB19C0015E for ; Sat, 12 Aug 2023 00:42:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237251AbjHLAmI (ORCPT ); Fri, 11 Aug 2023 20:42:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58302 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237190AbjHLAmE (ORCPT ); Fri, 11 Aug 2023 20:42:04 -0400 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A42213582; Fri, 11 Aug 2023 17:42:03 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 68EB61F460; Sat, 12 Aug 2023 00:42:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1691800922; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=9oCLm5O/TfEzHLI4v9CFF2If6jDnpmsmOxID/3lxDto=; b=z6Sp2GC8+jBUk4Xx/A77FekdsXw0LySonxn/vojNIRs8+QDJ3peu6XxH9Z0DFa3dgM1R2p WuecezI0IXifkVqSKW/OcTMwPsEawf2PMfFdc/ynwnn7DaMoilA0/be9ywUHwZcXVyxfSb V0lKoKwDpEdwEGvObRc2J3gLS0G5Mew= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1691800922; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=9oCLm5O/TfEzHLI4v9CFF2If6jDnpmsmOxID/3lxDto=; b=RVwQwTMRI2YS7bafrUHDV4SStZsR5/eJYZVYF02/jr6Kw/TxjEdUBYlMJieDgSUXM22ayd L44McZvMY2uGN1AA== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 31A0113592; Sat, 12 Aug 2023 00:42:02 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id jYNIBlrV1mQZEAAAMHmgww (envelope-from ); Sat, 12 Aug 2023 00:42:02 +0000 From: Gabriel Krisman Bertazi To: viro@zeniv.linux.org.uk, brauner@kernel.org, tytso@mit.edu, ebiggers@kernel.org, jaegeuk@kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, Gabriel Krisman Bertazi , Gabriel Krisman Bertazi Subject: [PATCH v5 05/10] fs: Add DCACHE_CASEFOLDED_NAME flag Date: Fri, 11 Aug 2023 20:41:41 -0400 Message-ID: <20230812004146.30980-6-krisman@suse.de> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230812004146.30980-1-krisman@suse.de> References: <20230812004146.30980-1-krisman@suse.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org From: Gabriel Krisman Bertazi This flag marks a negative or positive dentry as being created after a case-insensitive lookup operation. It is useful to differentiate dentries this way to detect whether the negative dentry can be trusted during a case-insensitive lookup. Reviewed-by: Theodore Ts'o Signed-off-by: Gabriel Krisman Bertazi --- Changes since v4: - Fixup names of functions to reflect flag name change (Eric) Changes since v2: - Rename DCACHE_CASEFOLD_LOOKUP -> DCACHE_CASEFOLDED_NAME (Eric) --- fs/dcache.c | 8 ++++++++ include/linux/dcache.h | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/fs/dcache.c b/fs/dcache.c index 52e6d5fdab6b..269367c1a86c 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1958,6 +1958,14 @@ void d_set_fallthru(struct dentry *dentry) } EXPORT_SYMBOL(d_set_fallthru); +void d_set_casefolded_name(struct dentry *dentry) +{ + spin_lock(&dentry->d_lock); + dentry->d_flags |= DCACHE_CASEFOLDED_NAME; + spin_unlock(&dentry->d_lock); +} +EXPORT_SYMBOL(d_set_casefold_lookup); + static unsigned d_flags_for_inode(struct inode *inode) { unsigned add_flags = DCACHE_REGULAR_TYPE; diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 9362e4ef0bad..ccbb5c4db7ce 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -208,6 +208,7 @@ struct dentry_operations { #define DCACHE_FALLTHRU 0x01000000 /* Fall through to lower layer */ #define DCACHE_NOKEY_NAME 0x02000000 /* Encrypted name encoded without key */ #define DCACHE_OP_REAL 0x04000000 +#define DCACHE_CASEFOLDED_NAME 0x08000000 /* Dentry comes from a casefold directory */ #define DCACHE_PAR_LOOKUP 0x10000000 /* being looked up (with parent locked shared) */ #define DCACHE_DENTRY_CURSOR 0x20000000 @@ -496,6 +497,13 @@ static inline bool d_is_fallthru(const struct dentry *dentry) return dentry->d_flags & DCACHE_FALLTHRU; } +extern void d_set_casefolded_name(struct dentry *dentry); + +static inline bool d_is_casefolded_name(const struct dentry *dentry) +{ + return dentry->d_flags & DCACHE_CASEFOLDED_NAME; +} + extern int sysctl_vfs_cache_pressure; From patchwork Sat Aug 12 00:41:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gabriel Krisman Bertazi X-Patchwork-Id: 13351606 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 50597C001DB for ; Sat, 12 Aug 2023 00:42:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237264AbjHLAmK (ORCPT ); Fri, 11 Aug 2023 20:42:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58308 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236577AbjHLAmF (ORCPT ); Fri, 11 Aug 2023 20:42:05 -0400 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 66E04A6; Fri, 11 Aug 2023 17:42:05 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 2026B1F45A; Sat, 12 Aug 2023 00:42:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1691800924; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=rboAhxFh4vXaAaxXhYnXEsNgIGq+WuMjEQjmzuhhcBA=; b=yPHW/KW99FkobstIfyZ/sDxFi5xpqOFvAkfJ31DfjY7MVOYoI6+eJ+lmeJtNdWd1Ce9I7r 1IquXEvycPUfOm3fUuBkInbFRkqUKFmaYS9AF2JyC7ozZk0EYGCmggZFJvwVKPtvP+HhWq uMmbV7Onl6KA0SGk986x6avE9/tluqQ= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1691800924; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=rboAhxFh4vXaAaxXhYnXEsNgIGq+WuMjEQjmzuhhcBA=; b=LCXLd7R33X9KhxaoePEQheYn/UMXFwBikpRSIXAVpuCAeBdnhjmbpXwoyxCFwYaezWPpyh 0X9c6s8oIRWvKaAQ== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id DCE7B13592; Sat, 12 Aug 2023 00:42:03 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id 7DxOMFvV1mQlEAAAMHmgww (envelope-from ); Sat, 12 Aug 2023 00:42:03 +0000 From: Gabriel Krisman Bertazi To: viro@zeniv.linux.org.uk, brauner@kernel.org, tytso@mit.edu, ebiggers@kernel.org, jaegeuk@kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, Gabriel Krisman Bertazi , Gabriel Krisman Bertazi Subject: [PATCH v5 06/10] libfs: Validate negative dentries in case-insensitive directories Date: Fri, 11 Aug 2023 20:41:42 -0400 Message-ID: <20230812004146.30980-7-krisman@suse.de> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230812004146.30980-1-krisman@suse.de> References: <20230812004146.30980-1-krisman@suse.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org From: Gabriel Krisman Bertazi Introduce a dentry revalidation helper to be used by case-insensitive filesystems to check if it is safe to reuse a negative dentry. A negative dentry is safe to be reused on a case-insensitive lookup if it was created during a case-insensitive lookup and this is not a lookup that will instantiate a dentry. If this is a creation lookup, we also need to make sure the name matches sensitively the name under lookup in order to assure the name preserving semantics. dentry->d_name is only checked by the case-insensitive d_revalidate hook in the LOOKUP_CREATE/LOOKUP_RENAME_TARGET case since, for these cases, d_revalidate is always called with the parent inode at least read-locked, and therefore the name cannot change from under us. d_revalidate is only called in 4 places: lookup_dcache, __lookup_slow, lookup_open and lookup_fast: - lookup_dcache always calls it with zeroed flags, with the exception of when coming from __lookup_hash, which needs the parent locked already, for instance in the open/creation path, which is locked in open_last_lookups. - In __lookup_slow, either the parent inode is read-locked by the caller (lookup_slow), or it is called with no flags (lookup_one*). The read lock suffices to prevent ->d_name modifications, with the exception of one case: __d_unalias, will call __d_move to fix a directory accessible from multiple dentries, which effectively swaps ->d_name while holding only the shared read lock. This happens through this flow: lookup_slow() //LOOKUP_CREATE d_lookup() ->d_lookup() d_splice_alias() __d_unalias() __d_move() Nevertheless, this case is not a problem because negative dentries are not allowed to be moved with __d_move. In addition, d_instantiate shouldn't race with this case because it's callers also acquire the parent inode lock, preventing it from racing with lookup creation, so the dentry cannot become positive and be moved while inside d_revalidate, which would be a problem if a parallel lookup did d_splice_alias. - lookup_open also requires the parent to be locked in the creation case, which is done in open_last_lookups. - lookup_fast will indeed be called with the parent unlocked, but it shouldn't be called with LOOKUP_CREATE. Either it is called in the link_path_walk, where nd->flags doesn't have LOOKUP_CREATE yet or in open_last_lookups. But, in this case, it also never has LOOKUP_CREATE, because it is only called on the !O_CREAT case, which means op->intent doesn't have LOOKUP_CREAT (set in build_open_flags only if O_CREAT is set). Finally, for the LOOKUP_RENAME_TARGET, we are doing a rename, so the parents inodes are also locked. Reviewed-by: Theodore Ts'o Signed-off-by: Gabriel Krisman Bertazi --- Changes since v4: - Drop useless inline declaration (eric) - Refactor to drop extra identation (Christian) - Discuss d_instantiate Changes since v3: - Add comment regarding creation (Eric) - Reorder checks to clarify !flags meaning (Eric) - Add commit message explanaton of the inode read lock wrt. __d_move. (Eric) Changes since v2: - Add comments to all rejection cases (Eric) - safeguard against filesystem creating dentries without LOOKUP flags --- fs/libfs.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/fs/libfs.c b/fs/libfs.c index 8d0b64cfd5da..cb98c4721327 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -1452,9 +1452,66 @@ static int generic_ci_d_hash(const struct dentry *dentry, struct qstr *str) return 0; } +static int generic_ci_d_revalidate(struct dentry *dentry, + const struct qstr *name, + unsigned int flags) +{ + const struct dentry *parent; + const struct inode *dir; + + if (!d_is_negative(dentry)) + return 1; + + parent = READ_ONCE(dentry->d_parent); + dir = READ_ONCE(parent->d_inode); + + if (!dir || !dir_is_casefolded(dir)) + return 1; + + /* + * Negative dentries created prior to turning the directory + * case-insensitive cannot be trusted, since they don't ensure + * any possible case version of the filename doesn't exist. + */ + if (!d_is_casefolded_name(dentry)) + return 0; + + /* + * Filesystems will call into d_revalidate without setting + * LOOKUP_ flags even for file creation (see lookup_one* + * variants). Reject negative dentries in this case, since we + * can't know for sure it won't be used for creation. + */ + if (!flags) + return 0; + + /* + * If the lookup is for creation, then a negative dentry can + * only be reused if it's a case-sensitive match, not just a + * case-insensitive one. This is needed to make the new file be + * created with the name the user specified, preserving case. + */ + if (flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET)) { + /* + * ->d_name won't change from under us in the creation + * path only, since d_revalidate during creation and + * renames is always called with the parent inode + * locked. It isn't the case for all lookup callpaths, + * so ->d_name must not be touched outside + * (LOOKUP_CREATE|LOOKUP_RENAME_TARGET) context. + */ + if (dentry->d_name.len != name->len || + memcmp(dentry->d_name.name, name->name, name->len)) + return 0; + } + + return 1; +} + static const struct dentry_operations generic_ci_dentry_ops = { .d_hash = generic_ci_d_hash, .d_compare = generic_ci_d_compare, + .d_revalidate = generic_ci_d_revalidate, }; #endif From patchwork Sat Aug 12 00:41:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gabriel Krisman Bertazi X-Patchwork-Id: 13351607 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F3808C41513 for ; Sat, 12 Aug 2023 00:42:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237256AbjHLAm2 (ORCPT ); Fri, 11 Aug 2023 20:42:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58344 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237237AbjHLAmI (ORCPT ); Fri, 11 Aug 2023 20:42:08 -0400 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 395FF358E; Fri, 11 Aug 2023 17:42:07 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id E9BAF1F6E6; Sat, 12 Aug 2023 00:42:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1691800925; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=sCB8KBQ2MnwnOXcRfTwBuvP3bZPVD+Fzqq9bmI2qOzc=; b=VEa/yxyUmvLnU8M5rMa6VInz+xIkndwA129DATZ7J2v04V5lRjCVRaNU9uClH1KmhCueBO DoA5DUj/KhhvzeF5q9I4x9Zyc/mY5ZQ8Bdjrvs4SxLUtF34ShMfG5ZW0Mlm/HzNDl3/QQ7 adZfxnggYSDDdLEoa+RCAhOkRBVXsEw= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1691800925; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=sCB8KBQ2MnwnOXcRfTwBuvP3bZPVD+Fzqq9bmI2qOzc=; b=NfuR/N4Fsp58zGGMNAm3rojG/E4y7R9MXU5LcfTHzbnDX0Dyjv4SfG9FxqbMA8SjAwjFRD +wt0cBd4K6kP2lDw== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id B365913592; Sat, 12 Aug 2023 00:42:05 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id ZcjoJV3V1mQnEAAAMHmgww (envelope-from ); Sat, 12 Aug 2023 00:42:05 +0000 From: Gabriel Krisman Bertazi To: viro@zeniv.linux.org.uk, brauner@kernel.org, tytso@mit.edu, ebiggers@kernel.org, jaegeuk@kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, Gabriel Krisman Bertazi , Gabriel Krisman Bertazi Subject: [PATCH v5 07/10] libfs: Chain encryption checks after case-insensitive revalidation Date: Fri, 11 Aug 2023 20:41:43 -0400 Message-ID: <20230812004146.30980-8-krisman@suse.de> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230812004146.30980-1-krisman@suse.de> References: <20230812004146.30980-1-krisman@suse.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org From: Gabriel Krisman Bertazi Support encrypted dentries in generic_ci_d_revalidate by chaining fscrypt_d_revalidate at the tail of the d_revalidate. This allows filesystem to just call generic_ci_d_revalidate and let it handle any case-insensitive dentry (encrypted or not). Signed-off-by: Gabriel Krisman Bertazi --- Changes since v2: - Enable negative dentries of encrypted filesystems (Eric) --- fs/libfs.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/fs/libfs.c b/fs/libfs.c index cb98c4721327..efb245118d10 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -1452,9 +1452,8 @@ static int generic_ci_d_hash(const struct dentry *dentry, struct qstr *str) return 0; } -static int generic_ci_d_revalidate(struct dentry *dentry, - const struct qstr *name, - unsigned int flags) +static int ci_d_revalidate(struct dentry *dentry, const struct qstr *name, + unsigned int flags) { const struct dentry *parent; const struct inode *dir; @@ -1508,6 +1507,15 @@ static int generic_ci_d_revalidate(struct dentry *dentry, return 1; } +static int generic_ci_d_revalidate(struct dentry *dentry, + const struct qstr *name, + unsigned int flags) +{ + if (!ci_d_revalidate(dentry, name, flags)) + return 0; + return fscrypt_d_revalidate(dentry, name, flags); +} + static const struct dentry_operations generic_ci_dentry_ops = { .d_hash = generic_ci_d_hash, .d_compare = generic_ci_d_compare, @@ -1525,7 +1533,7 @@ static const struct dentry_operations generic_encrypted_dentry_ops = { static const struct dentry_operations generic_encrypted_ci_dentry_ops = { .d_hash = generic_ci_d_hash, .d_compare = generic_ci_d_compare, - .d_revalidate = fscrypt_d_revalidate, + .d_revalidate = generic_ci_d_revalidate, }; #endif From patchwork Sat Aug 12 00:41:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gabriel Krisman Bertazi X-Patchwork-Id: 13351608 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 24ED9C001DB for ; Sat, 12 Aug 2023 00:42:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237225AbjHLAm3 (ORCPT ); Fri, 11 Aug 2023 20:42:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33072 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234588AbjHLAmU (ORCPT ); Fri, 11 Aug 2023 20:42:20 -0400 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E4F3D3582; Fri, 11 Aug 2023 17:42:08 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id A7AE91F38A; Sat, 12 Aug 2023 00:42:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1691800927; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=sTxhaqF5sRXfD/Sz/tp3d/xhC2rVXOn+t3d6w8E4rAo=; b=X8tB+eKLTTO897QOvQSA84RZHzPqH9/rqG0UZPdDtiaDP7unm/zP2xCocNDYKUbwpbfsTe Cp5Kzt3MQnBuvdPcAgwy8jaRWuaBG/EXL9V4LJbLhUJit6Ojr4p2qnJAGzSFRBMkpK1SIG mAq5HMRJiKBD4Vwo4DgbJ8+5ww6m08I= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1691800927; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=sTxhaqF5sRXfD/Sz/tp3d/xhC2rVXOn+t3d6w8E4rAo=; b=WgVIEOryp4HKOjylausdq6/ZDFC+LngfMkSsLq62KITN3Vx3He6okdRjHVstf/tRXvDrZy ZzklrOajizMRl0Cg== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 7232013592; Sat, 12 Aug 2023 00:42:07 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id 6vxRFl/V1mQsEAAAMHmgww (envelope-from ); Sat, 12 Aug 2023 00:42:07 +0000 From: Gabriel Krisman Bertazi To: viro@zeniv.linux.org.uk, brauner@kernel.org, tytso@mit.edu, ebiggers@kernel.org, jaegeuk@kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, Gabriel Krisman Bertazi , Gabriel Krisman Bertazi Subject: [PATCH v5 08/10] libfs: Merge encrypted_ci_dentry_ops and ci_dentry_ops Date: Fri, 11 Aug 2023 20:41:44 -0400 Message-ID: <20230812004146.30980-9-krisman@suse.de> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230812004146.30980-1-krisman@suse.de> References: <20230812004146.30980-1-krisman@suse.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org From: Gabriel Krisman Bertazi Now that casefold needs d_revalidate and calls fscrypt_d_revalidate itself, generic_encrypt_ci_dentry_ops and generic_ci_dentry_ops are now equivalent. Merge them together and simplify the setup code. Signed-off-by: Gabriel Krisman Bertazi --- changes since v2: - reword comment for clarity (Eric) --- fs/libfs.c | 45 +++++++++++++-------------------------------- 1 file changed, 13 insertions(+), 32 deletions(-) diff --git a/fs/libfs.c b/fs/libfs.c index efb245118d10..6b15a4f0312f 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -1516,7 +1516,7 @@ static int generic_ci_d_revalidate(struct dentry *dentry, return fscrypt_d_revalidate(dentry, name, flags); } -static const struct dentry_operations generic_ci_dentry_ops = { +static const struct dentry_operations generic_encrypted_ci_dentry_ops = { .d_hash = generic_ci_d_hash, .d_compare = generic_ci_d_compare, .d_revalidate = generic_ci_d_revalidate, @@ -1529,26 +1529,19 @@ static const struct dentry_operations generic_encrypted_dentry_ops = { }; #endif -#if defined(CONFIG_FS_ENCRYPTION) && IS_ENABLED(CONFIG_UNICODE) -static const struct dentry_operations generic_encrypted_ci_dentry_ops = { - .d_hash = generic_ci_d_hash, - .d_compare = generic_ci_d_compare, - .d_revalidate = generic_ci_d_revalidate, -}; -#endif - /** * generic_set_encrypted_ci_d_ops - helper for setting d_ops for given dentry * @dentry: dentry to set ops on * - * Casefolded directories need d_hash and d_compare set, so that the dentries - * contained in them are handled case-insensitively. Note that these operations - * are needed on the parent directory rather than on the dentries in it, and - * while the casefolding flag can be toggled on and off on an empty directory, - * dentry_operations can't be changed later. As a result, if the filesystem has - * casefolding support enabled at all, we have to give all dentries the - * casefolding operations even if their inode doesn't have the casefolding flag - * currently (and thus the casefolding ops would be no-ops for now). + * Casefolded directories need some dentry_operations set, so that the dentries + * contained in them are handled case-insensitively. Note that d_hash and + * d_compare are needed on the parent directory rather than on the dentries in + * it, and while the casefolding flag can be toggled on and off on an empty + * directory, dentry_operations can't be changed later. As a result, if the + * filesystem has casefolding support enabled at all, we have to give all + * dentries the casefolding operations even if their inode doesn't have the + * casefolding flag currently (and thus the casefolding ops would be no-ops for + * now). * * Encryption works differently in that the only dentry operation it needs is * d_revalidate, which it only needs on dentries that have the no-key name flag. @@ -1557,34 +1550,22 @@ static const struct dentry_operations generic_encrypted_ci_dentry_ops = { * Finally, to maximize compatibility with overlayfs (which isn't compatible * with certain dentry operations) and to avoid taking an unnecessary * performance hit, we use custom dentry_operations for each possible - * combination rather than always installing all operations. + * combination of operations rather than always installing them. */ void generic_set_encrypted_ci_d_ops(struct dentry *dentry) { -#ifdef CONFIG_FS_ENCRYPTION - bool needs_encrypt_ops = dentry->d_flags & DCACHE_NOKEY_NAME; -#endif #if IS_ENABLED(CONFIG_UNICODE) - bool needs_ci_ops = dentry->d_sb->s_encoding; -#endif -#if defined(CONFIG_FS_ENCRYPTION) && IS_ENABLED(CONFIG_UNICODE) - if (needs_encrypt_ops && needs_ci_ops) { + if (dentry->d_sb->s_encoding) { d_set_d_op(dentry, &generic_encrypted_ci_dentry_ops); return; } #endif #ifdef CONFIG_FS_ENCRYPTION - if (needs_encrypt_ops) { + if (dentry->d_flags & DCACHE_NOKEY_NAME) { d_set_d_op(dentry, &generic_encrypted_dentry_ops); return; } #endif -#if IS_ENABLED(CONFIG_UNICODE) - if (needs_ci_ops) { - d_set_d_op(dentry, &generic_ci_dentry_ops); - return; - } -#endif } EXPORT_SYMBOL(generic_set_encrypted_ci_d_ops); From patchwork Sat Aug 12 00:41:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gabriel Krisman Bertazi X-Patchwork-Id: 13351610 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5E05BC41513 for ; Sat, 12 Aug 2023 00:42:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237272AbjHLAmc (ORCPT ); Fri, 11 Aug 2023 20:42:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58334 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237219AbjHLAmX (ORCPT ); Fri, 11 Aug 2023 20:42:23 -0400 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8D4103594; Fri, 11 Aug 2023 17:42:10 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 50A761F86B; Sat, 12 Aug 2023 00:42:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1691800929; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=TE/HGdYR1lb+QiAqtg8r3AFyzs792iP/bU+OaFIj2IY=; b=nWA/sjxapi2GZJn3/QC5/3t/4hHthVqC6cUKCcCBiegjU1IkXT0V64FGmTSt2QY8KCQmvy N2QIdW3uAvFlBozL+gr3IYa7vikSlyvZPtFDMefndZpEfvzQ0e8suieRHwxGHncPEBlVft BoORmxz8TvwfOo46/FlUlhEfEH/5Z80= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1691800929; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=TE/HGdYR1lb+QiAqtg8r3AFyzs792iP/bU+OaFIj2IY=; b=mMFVH/KAXrntuYy873XfFNz7tQcw4/W0W5EjKOzR1w1oSev9/c3/SFjyAZwHdTPI3Z9T3g v1bM2TbAp1sdLDDw== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 1AE4D13592; Sat, 12 Aug 2023 00:42:09 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id qc7VAGHV1mQxEAAAMHmgww (envelope-from ); Sat, 12 Aug 2023 00:42:09 +0000 From: Gabriel Krisman Bertazi To: viro@zeniv.linux.org.uk, brauner@kernel.org, tytso@mit.edu, ebiggers@kernel.org, jaegeuk@kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, Gabriel Krisman Bertazi , Gabriel Krisman Bertazi Subject: [PATCH v5 09/10] ext4: Enable negative dentries on case-insensitive lookup Date: Fri, 11 Aug 2023 20:41:45 -0400 Message-ID: <20230812004146.30980-10-krisman@suse.de> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230812004146.30980-1-krisman@suse.de> References: <20230812004146.30980-1-krisman@suse.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org From: Gabriel Krisman Bertazi Instead of invalidating negative dentries during case-insensitive lookups, mark them as such and let them be added to the dcache. d_ci_revalidate is able to properly filter them out if necessary based on the dentry casefold flag. Signed-off-by: Gabriel Krisman Bertazi --- Changes since v4: - Use helper to decide if should set dentry flag. Changes since v2: - Move dentry flag set closer to fscrypt code (Eric) --- fs/ext4/namei.c | 35 ++++------------------------------- 1 file changed, 4 insertions(+), 31 deletions(-) diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 0caf6c730ce3..8d33a74bcc95 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -1759,6 +1759,10 @@ static struct buffer_head *ext4_lookup_entry(struct inode *dir, err = ext4_fname_prepare_lookup(dir, dentry, &fname); generic_set_encrypted_ci_d_ops(dentry); + + if (dir_is_casefolded(dir)) + d_set_casefolded_name(dentry); + if (err == -ENOENT) return NULL; if (err) @@ -1866,16 +1870,6 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsi } } -#if IS_ENABLED(CONFIG_UNICODE) - if (!inode && IS_CASEFOLDED(dir)) { - /* Eventually we want to call d_add_ci(dentry, NULL) - * for negative dentries in the encoding case as - * well. For now, prevent the negative dentry - * from being cached. - */ - return NULL; - } -#endif return d_splice_alias(inode, dentry); } @@ -3206,17 +3200,6 @@ static int ext4_rmdir(struct inode *dir, struct dentry *dentry) ext4_fc_track_unlink(handle, dentry); retval = ext4_mark_inode_dirty(handle, dir); -#if IS_ENABLED(CONFIG_UNICODE) - /* VFS negative dentries are incompatible with Encoding and - * Case-insensitiveness. Eventually we'll want avoid - * invalidating the dentries here, alongside with returning the - * negative dentries at ext4_lookup(), when it is better - * supported by the VFS for the CI case. - */ - if (IS_CASEFOLDED(dir)) - d_invalidate(dentry); -#endif - end_rmdir: brelse(bh); if (handle) @@ -3317,16 +3300,6 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry) goto out_trace; retval = __ext4_unlink(dir, &dentry->d_name, d_inode(dentry), dentry); -#if IS_ENABLED(CONFIG_UNICODE) - /* VFS negative dentries are incompatible with Encoding and - * Case-insensitiveness. Eventually we'll want avoid - * invalidating the dentries here, alongside with returning the - * negative dentries at ext4_lookup(), when it is better - * supported by the VFS for the CI case. - */ - if (IS_CASEFOLDED(dir)) - d_invalidate(dentry); -#endif out_trace: trace_ext4_unlink_exit(dentry, retval); From patchwork Sat Aug 12 00:41:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gabriel Krisman Bertazi X-Patchwork-Id: 13351609 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C3BAFC0015E for ; Sat, 12 Aug 2023 00:42:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237231AbjHLAma (ORCPT ); Fri, 11 Aug 2023 20:42:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58342 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237108AbjHLAm0 (ORCPT ); Fri, 11 Aug 2023 20:42:26 -0400 Received: from smtp-out2.suse.de (smtp-out2.suse.de [IPv6:2001:67c:2178:6::1d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5E85D359C; Fri, 11 Aug 2023 17:42:12 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 08BE71F8A8; Sat, 12 Aug 2023 00:42:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1691800931; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=L5yvPO73LzaHqBcXpBIAiP4zUC13otTzpIxPlCrbM0w=; b=EC5YeMNQ/omLqYo3av20mJjbh2k9LNK3IowuC5aGboOKni0JgVY0XdN+JsXculijkeU6AQ wFrmg9U/6BtZtKHE1Fm/3j5VGcQcnmSsNOAFDyJiRJrKm+cNyE83HrLKFXC2r/S0nsG5Hk kYDPkWCHU/IbvMOHcdK6+QRXeFSmh5w= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1691800931; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=L5yvPO73LzaHqBcXpBIAiP4zUC13otTzpIxPlCrbM0w=; b=srTz7A4/LrUIT2+9dba0oswQ9yiNsW3LG/0YeGeNvlnbmh1sVQ5IQe1qftybeASOvqgoKI V+g8b9b/bPhCymDg== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id BA50113592; Sat, 12 Aug 2023 00:42:10 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id duukJ2LV1mQ1EAAAMHmgww (envelope-from ); Sat, 12 Aug 2023 00:42:10 +0000 From: Gabriel Krisman Bertazi To: viro@zeniv.linux.org.uk, brauner@kernel.org, tytso@mit.edu, ebiggers@kernel.org, jaegeuk@kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, Gabriel Krisman Bertazi , Gabriel Krisman Bertazi Subject: [PATCH v5 10/10] f2fs: Enable negative dentries on case-insensitive lookup Date: Fri, 11 Aug 2023 20:41:46 -0400 Message-ID: <20230812004146.30980-11-krisman@suse.de> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230812004146.30980-1-krisman@suse.de> References: <20230812004146.30980-1-krisman@suse.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org From: Gabriel Krisman Bertazi Instead of invalidating negative dentries during case-insensitive lookups, mark them as such and let them be added to the dcache. d_ci_revalidate is able to properly filter them out if necessary based on the dentry casefold flag. Signed-off-by: Gabriel Krisman Bertazi --- Changes since v4: - Use helper to decide if should set dentry flag. Changes since v2: - Move dentry flag set closer to fscrypt code (Eric) --- fs/f2fs/namei.c | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index bee0568888da..8b8fd4cdf62d 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -533,6 +533,10 @@ static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry, err = f2fs_prepare_lookup(dir, dentry, &fname); generic_set_encrypted_ci_d_ops(dentry); + + if (dir_is_casefolded(dir)) + d_set_casefolded_name(dentry); + if (err == -ENOENT) goto out_splice; if (err) @@ -578,17 +582,6 @@ static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry, goto out_iput; } out_splice: -#if IS_ENABLED(CONFIG_UNICODE) - if (!inode && IS_CASEFOLDED(dir)) { - /* Eventually we want to call d_add_ci(dentry, NULL) - * for negative dentries in the encoding case as - * well. For now, prevent the negative dentry - * from being cached. - */ - trace_f2fs_lookup_end(dir, dentry, ino, err); - return NULL; - } -#endif new = d_splice_alias(inode, dentry); trace_f2fs_lookup_end(dir, !IS_ERR_OR_NULL(new) ? new : dentry, ino, IS_ERR(new) ? PTR_ERR(new) : err); @@ -641,16 +634,6 @@ static int f2fs_unlink(struct inode *dir, struct dentry *dentry) f2fs_delete_entry(de, page, dir, inode); f2fs_unlock_op(sbi); -#if IS_ENABLED(CONFIG_UNICODE) - /* VFS negative dentries are incompatible with Encoding and - * Case-insensitiveness. Eventually we'll want avoid - * invalidating the dentries here, alongside with returning the - * negative dentries at f2fs_lookup(), when it is better - * supported by the VFS for the CI case. - */ - if (IS_CASEFOLDED(dir)) - d_invalidate(dentry); -#endif if (IS_DIRSYNC(dir)) f2fs_sync_fs(sbi->sb, 1); fail: