Received: by 2002:a05:6a10:9848:0:0:0:0 with SMTP id x8csp2978654pxf; Sun, 28 Mar 2021 07:49:15 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwLJhvJpd+Q0OhF/OJnLsygr29BcLGqnKvEKopBXUwxfb1l0lkszBctp1aSRecCEZvQjavG X-Received: by 2002:a17:906:8a65:: with SMTP id hy5mr25066342ejc.250.1616942955185; Sun, 28 Mar 2021 07:49:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1616942955; cv=none; d=google.com; s=arc-20160816; b=VsqYmoneE3ZqTGKWWkR5UWMNrbwq5qO9SDocZp1O85HGeKHAX6graE23vOGVap+1Oi tftcnQSHuBXHu9jTffPK489D1UZYrlhfqwL6BY7CVSIMWoRY4OADhT506M6m/92YtZdL WabHDAXEwsI6spB8tCCq5MfVHojVjBUz23z126grCdAyhSLmvujlq1iN6s7f03DAJBnD wgb/+l/0TWYAD9+oPhFUWUeeVI/Cdxaw64yhfSbsE9RcV58uB024x+pigDtc++4sQmUr ++oPkc1BgVmvzF4IIzYz1yBqxwz4ZyE53Z2k/rJpZD/eeBz1Dgb/G0Wxg3i0Pip3PmP1 O8Yw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=gcBa8LpB132GckVMeypT70c76X/WTbpPd+vx3FK0Mxg=; b=bw6rFNpj08GHg33jzR65n207VGC0IQjLmdiOTGnkeBpThEchj0izKCCdWFF7dVKph3 GeGjwYko8A6DjdcJd43UjpLjsM3JUpPUM0LzYfo0MD8czPFXphlFLZWkv6vP5QQPeQ0e XTGQq4fe1o9uQ4l1WhZ/FQoTwgRvKkdIsiawYakerurm+uhXAXx8GWTivg0dYPcqTxRq QOGXc0/vH8pUI9p5K5+CFdqWeqAG2Fkr8gaZ9+W7qiqgUiAp9mWkVmrV5BtiEE+MI0Nr Mbj1LY1jpt+qjRRIl6HRZP36IH8QbFvsE6SpnhjSInsh6s8UDyigAzykBV2t2J7YKON7 Gurw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=collabora.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id ds7si12255613ejc.534.2021.03.28.07.48.52; Sun, 28 Mar 2021 07:49:15 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=collabora.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231375AbhC1Oo5 (ORCPT + 99 others); Sun, 28 Mar 2021 10:44:57 -0400 Received: from bhuna.collabora.co.uk ([46.235.227.227]:33608 "EHLO bhuna.collabora.co.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230526AbhC1Oo0 (ORCPT ); Sun, 28 Mar 2021 10:44:26 -0400 Received: from [127.0.0.1] (localhost [127.0.0.1]) (Authenticated sender: tonyk) with ESMTPSA id C8BF11F4418B From: =?UTF-8?q?Andr=C3=A9=20Almeida?= To: Alexander Viro , Theodore Ts'o , Andreas Dilger , Jaegeuk Kim , Chao Yu Cc: krisman@collabora.com, kernel@collabora.com, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-ext4@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, Daniel Rosenberg , Chao Yu , =?UTF-8?q?Andr=C3=A9=20Almeida?= Subject: [PATCH 1/3] fs/dcache: Add d_clear_dir_neg_dentries() Date: Sun, 28 Mar 2021 11:43:54 -0300 Message-Id: <20210328144356.12866-2-andrealmeid@collabora.com> X-Mailer: git-send-email 2.31.0 In-Reply-To: <20210328144356.12866-1-andrealmeid@collabora.com> References: <20210328144356.12866-1-andrealmeid@collabora.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org For directories with negative dentries that are becoming case-insensitive dirs, we need to remove all those negative dentries, otherwise they will become dangling dentries. During the creation of a new file, if a d_hash collision happens and the names match in a case-insensitive way, the name of the file will be the name defined at the negative dentry, that may be different from the specified by the user. To prevent this from happening, we need to remove all dentries in a directory. Given that the directory must be empty before we call this function we are sure that all dentries there will be negative. Create a function to remove all negative dentries from a directory, to be used as explained above by filesystems that support case-insensitive lookups. Signed-off-by: André Almeida --- fs/dcache.c | 27 +++++++++++++++++++++++++++ include/linux/dcache.h | 1 + 2 files changed, 28 insertions(+) diff --git a/fs/dcache.c b/fs/dcache.c index 7d24ff7eb206..fafb3016d6fd 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1723,6 +1723,33 @@ void d_invalidate(struct dentry *dentry) } EXPORT_SYMBOL(d_invalidate); +/** + * d_clear_dir_neg_dentries - Remove negative dentries in an inode + * @dir: Directory to clear negative dentries + * + * For directories with negative dentries that are becoming case-insensitive + * dirs, we need to remove all those negative dentries, otherwise they will + * become dangling dentries. During the creation of a new file, if a d_hash + * collision happens and the names match in a case-insensitive, the name of + * the file will be the name defined at the negative dentry, that can be + * different from the specified by the user. To prevent this from happening, we + * need to remove all dentries in a directory. Given that the directory must be + * empty before we call this function we are sure that all dentries there will + * be negative. + */ +void d_clear_dir_neg_dentries(struct inode *dir) +{ + struct dentry *alias, *dentry; + + hlist_for_each_entry(alias, &dir->i_dentry, d_u.d_alias) { + list_for_each_entry(dentry, &alias->d_subdirs, d_child) { + d_drop(dentry); + dput(dentry); + } + } +} +EXPORT_SYMBOL(d_clear_dir_neg_dentries); + /** * __d_alloc - allocate a dcache entry * @sb: filesystem it will belong to diff --git a/include/linux/dcache.h b/include/linux/dcache.h index c1e48014106f..c43cd0be077f 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -250,6 +250,7 @@ extern void shrink_dcache_sb(struct super_block *); extern void shrink_dcache_parent(struct dentry *); extern void shrink_dcache_for_umount(struct super_block *); extern void d_invalidate(struct dentry *); +extern void d_clear_dir_neg_dentries(struct inode *); /* only used at mount-time */ extern struct dentry * d_make_root(struct inode *); -- 2.31.0