Received: by 2002:a05:6a10:9848:0:0:0:0 with SMTP id x8csp4350009pxf; Tue, 30 Mar 2021 05:55:39 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyVdRdBWzLecTji1uxOZFm1wlEsmS1qAKtOG74keDuFK046/OPBoyU3WH0wSNrt2O8VXLen X-Received: by 2002:a17:906:8043:: with SMTP id x3mr32682905ejw.149.1617108939592; Tue, 30 Mar 2021 05:55:39 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1617108939; cv=none; d=google.com; s=arc-20160816; b=KFV1LqgU1BkiGS6G42wf18/RCqGBmZOsXAC4aOnXg4gfNX1zVVbcbJiG7xqedoBiwd yDNktoFZqNh/uty0Qwcxsnw3h5dQpfH2XBDOq52yvLyKsRBTrof+A63UyCVcO4hHN7l+ 5voF9L/BXn1U4UDxnPdleByn+jWFzzCv3go1f9KUL3KDU74FXlRS5RCrmm+KiDrg6ETw 9Zq26KWr+OSr1MbXhHzQlE8OxmxVps81R2ntcPqrmEmM9GYhMKYMxSO0yPG9VWzb+9g3 ciQ0W3hRo5l6KcoNXganLXeV2fyUx0SgDrrkoBAKv4gpcvZfVzpUMfViNC1IWjRxihem 2NFA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:content-language :in-reply-to:mime-version:user-agent:date:message-id:from:references :cc:to:subject; bh=11ux4kf1HOJE1PM70FWR5cHivxrNcC7/rQgBNzJB4vE=; b=IGlts7DkIZN8ZibEjIwECtxwKtuGJU6H4gnrr75okxmEczFoEwat426rtzLtomBtrX 9tQnxaWVC+osET0VC/TPJrMh4Sd8RrP7rt/ffhzIusMM20EOCnyqFk6mRCECBOMvKPp5 59IlW1VczQTW96//S2oaFivLwfugKWV9AcjkRb3n7d/E11keLsk5rxU3irfwuL5Tf/YC CxfBJysPCUXxf9/l2ZGv8Lle8V0CST6w6MehT/45c0xNvHR2EUdu1NhSHG2aQR399RV6 q4jL3M9GPmBEOy3ntoY4g25odo7nwdWY5a80+QCTlTWZKbftvr362Maz3xlhV5QWyzg9 mkQQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-ext4-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-ext4-owner@vger.kernel.org; dmarc=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 j19si14229742edp.531.2021.03.30.05.55.15; Tue, 30 Mar 2021 05:55:39 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-ext4-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-ext4-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-ext4-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=collabora.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232034AbhC3Mya (ORCPT + 99 others); Tue, 30 Mar 2021 08:54:30 -0400 Received: from bhuna.collabora.co.uk ([46.235.227.227]:41120 "EHLO bhuna.collabora.co.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231910AbhC3MyK (ORCPT ); Tue, 30 Mar 2021 08:54:10 -0400 Received: from [127.0.0.1] (localhost [127.0.0.1]) (Authenticated sender: tonyk) with ESMTPSA id 8DE8A1F44E69 Subject: Re: [PATCH 1/3] fs/dcache: Add d_clear_dir_neg_dentries() To: Eric Biggers Cc: Alexander Viro , Theodore Ts'o , Andreas Dilger , Jaegeuk Kim , Chao Yu , kernel@collabora.com, Daniel Rosenberg , linux-kernel@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org, krisman@collabora.com References: <20210328144356.12866-1-andrealmeid@collabora.com> <20210328144356.12866-2-andrealmeid@collabora.com> From: =?UTF-8?Q?Andr=c3=a9_Almeida?= Message-ID: <8ea3ba8e-2699-8786-5ca3-33ee3c70961b@collabora.com> Date: Tue, 30 Mar 2021 09:54:01 -0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.9.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org Hi Eric, Às 22:48 de 29/03/21, Eric Biggers escreveu: > On Sun, Mar 28, 2021 at 11:43:54AM -0300, André Almeida wrote: >> 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); > > As Al already pointed out, this doesn't work as intended, for a number of > different reasons. > > Did you consider just using shrink_dcache_parent()? That already does what you > are trying to do here, I think. When I wrote this patch, I didn't know it, but after Al Viro comments I get back to the code and found it, and it seems do do what I intend indeed, and my test is happy as well. > > The harder part (which I don't think you've considered) is how to ensure that > all negative dentries really get invalidated even if there are lookups of them > happening concurrently. Concurrent lookups can take temporary references to the > negative dentries, preventing them from being invalidated. > I didn't consider that, thanks for the feedback. So this means that those lookups will increase the refcount of the dentry, and it will only get really invalidated when refcount reaches 0? Or do would I need to call d_invalidate() again, until I succeed? > - Eric >