From patchwork Wed Nov 1 06:20:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13442540 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1EC574C6D for ; Wed, 1 Nov 2023 06:21:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="n6n/YGdr" Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [IPv6:2a03:a000:7:0:5054:ff:fe1c:15ff]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E6B09F4 for ; Tue, 31 Oct 2023 23:21:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=dULO1MrYIGKbdAvnmF64PNnJJ6Gu1Nu6TZCBBlHRCiU=; b=n6n/YGdrepzzVQEFhfkoD3ZqXA +rR24fzJy37d/MT6xJYm6zKB3/KMs26ap4kDdh1xG5xMqdqlgjvTCxyTYfLd82e9r3LP7EOdzbVlU rGu8yOj543fmaA6ZQS7awZTBJ28zMvenqQa7XAZZK/ZOMhKT+84f10YdQcGVjRoQNsjtLOSA/Ndzw 6GBwNIxzlFOxnAxiV6ZGp7GI69d+as4hbGYaO1TTNQAGWowUVsAYj8A8OGepLv7tnOg+f8eXfsFAz oZeneiw8F/AfxJOYhDlPjclk8KAAWoQ6JscvHD6tEIJ67GZ4wuQjFSleWpUZlNGnNhrOXEMZA21hd MSNHGGjw==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1qy4bA-008paw-1I; Wed, 01 Nov 2023 06:21:04 +0000 From: Al Viro To: Linus Torvalds Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH 01/15] fast_dput(): having ->d_delete() is not reason to delay refcount decrement Date: Wed, 1 Nov 2023 06:20:50 +0000 Message-Id: <20231101062104.2104951-1-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231031061226.GC1957730@ZenIV> References: <20231031061226.GC1957730@ZenIV> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro ->d_delete() is a way for filesystem to tell that dentry is not worth keeping cached. It is not guaranteed to be called every time a dentry has refcount drop down to zero; it is not guaranteed to be called before dentry gets evicted. In other words, it is not suitable for any kind of keeping track of dentry state. None of the in-tree filesystems attempt to use it that way, fortunately. So the contortions done by fast_dput() (as well as dentry_kill()) are not warranted. fast_dput() certainly should treat having ->d_delete() instance as "can't assume we'll be keeping it", but that's not different from the way we treat e.g. DCACHE_DONTCACHE (which is rather similar to making ->d_delete() returns true when called). Signed-off-by: Al Viro --- fs/dcache.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index 25ac74d30bff..5ec14df04f11 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -768,15 +768,7 @@ static inline bool fast_dput(struct dentry *dentry) unsigned int d_flags; /* - * If we have a d_op->d_delete() operation, we sould not - * let the dentry count go to zero, so use "put_or_lock". - */ - if (unlikely(dentry->d_flags & DCACHE_OP_DELETE)) - return lockref_put_or_lock(&dentry->d_lockref); - - /* - * .. otherwise, we can try to just decrement the - * lockref optimistically. + * try to decrement the lockref optimistically. */ ret = lockref_put_return(&dentry->d_lockref); @@ -830,7 +822,7 @@ static inline bool fast_dput(struct dentry *dentry) */ smp_rmb(); d_flags = READ_ONCE(dentry->d_flags); - d_flags &= DCACHE_REFERENCED | DCACHE_LRU_LIST | + d_flags &= DCACHE_REFERENCED | DCACHE_LRU_LIST | DCACHE_OP_DELETE | DCACHE_DISCONNECTED | DCACHE_DONTCACHE; /* Nothing to do? Dropping the reference was all we needed? */ From patchwork Wed Nov 1 06:20:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13442541 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0AE574C67 for ; Wed, 1 Nov 2023 06:21:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="H6lAplmW" Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [IPv6:2a03:a000:7:0:5054:ff:fe1c:15ff]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2646BF7 for ; Tue, 31 Oct 2023 23:21:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=3I+Y9jWk7ME9G/i4K7RrRWTK8KeuuIOzpJCBsZA1NCM=; b=H6lAplmWd+JfFKUOiNYDxGmLPt BWJFq6UqsCKxCD4SBCHutW7Ez7czPd3luRwJrjseNw2jcDtfO3+cal5ktKb+V9bgOFo6QjDKu8x5w 2F1Ew1EtJ7Tl8tYVhT5dZl0nu/iNILQRRbeFcQmEu8Ib4uV2k2Fimmc1hasZ2uBS4dsqI8SrlYEE0 YnWxsKLgKjqWXxZ9Y9CwwigauOg1aVM51iPTQLEAdV+8JSNb7uIVugyd4CTnYnoT+qh8x+7sjzMeJ KcUlXLlFummG3UWvy1Bihl3ELyABI717tdLMPMSwO69gO53bRLYUejdTThlgjGVbdx4dQIbJCNcNK 0gCWkH5Q==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1qy4bA-008pb0-2G; Wed, 01 Nov 2023 06:21:04 +0000 From: Al Viro To: Linus Torvalds Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH 02/15] fast_dput(): handle underflows gracefully Date: Wed, 1 Nov 2023 06:20:51 +0000 Message-Id: <20231101062104.2104951-2-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231101062104.2104951-1-viro@zeniv.linux.org.uk> References: <20231031061226.GC1957730@ZenIV> <20231101062104.2104951-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro If refcount is less than 1, we should just warn, unlock dentry and return true, so that the caller doesn't try to do anything else. Taking care of that leaves the rest of "lockref_put_return() has failed" case equivalent to "decrement refcount and rejoin the normal slow path after the point where we grab ->d_lock". NOTE: lockref_put_return() is strictly a fastpath thing - unlike the rest of lockref primitives, it does not contain a fallback. Caller (and it looks like fast_dput() is the only legitimate one in the entire kernel) has to do that itself. Reasons for lockref_put_return() failures: * ->d_lock held by somebody * refcount <= 0 * ... or an architecture not supporting lockref use of cmpxchg - sparc, anything non-SMP, config with spinlock debugging... We could add a fallback, but it would be a clumsy API - we'd have to distinguish between: (1) refcount > 1 - decremented, lock not held on return (2) refcount < 1 - left alone, probably no sense to hold the lock (3) refcount is 1, no cmphxcg - decremented, lock held on return (4) refcount is 1, cmphxcg supported - decremented, lock *NOT* held on return. We want to return with no lock held in case (4); that's the whole point of that thing. We very much do not want to have the fallback in case (3) return without a lock, since the caller might have to retake it in that case. So it wouldn't be more convenient than doing the fallback in the caller and it would be very easy to screw up, especially since the test coverage would suck - no way to test (3) and (4) on the same kernel build. Signed-off-by: Al Viro --- fs/dcache.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index 5ec14df04f11..ddc534b39c22 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -779,12 +779,12 @@ static inline bool fast_dput(struct dentry *dentry) */ if (unlikely(ret < 0)) { spin_lock(&dentry->d_lock); - if (dentry->d_lockref.count > 1) { - dentry->d_lockref.count--; + if (WARN_ON_ONCE(dentry->d_lockref.count <= 0)) { spin_unlock(&dentry->d_lock); return true; } - return false; + dentry->d_lockref.count--; + goto locked; } /* @@ -842,6 +842,7 @@ static inline bool fast_dput(struct dentry *dentry) * else could have killed it and marked it dead. Either way, we * don't need to do anything else. */ +locked: if (dentry->d_lockref.count) { spin_unlock(&dentry->d_lock); return true; From patchwork Wed Nov 1 06:20:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13442547 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 22AF14C7B for ; Wed, 1 Nov 2023 06:21:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="o8vLs/i+" Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [IPv6:2a03:a000:7:0:5054:ff:fe1c:15ff]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 54955FC for ; Tue, 31 Oct 2023 23:21:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=VlJsWlAclT+yLzchi4E3P/hJdL5zj/z1kNqnZqk4gRw=; b=o8vLs/i+QS4XbPSxqik+8Q4V9t Pm3LtgCWSZ1FLgnAFIASMwogU4Osc9khn1PT5uuwgsNLjvEYLlj2Uvl3IbSZqQHUqEmCkAWSMTXtK lMjCcC5SWrWGWH7lGNTZ4SqXvASsrlJuugjfMgcjUj+bCDO+9pFdT+49ztQ6FjoP9CiiLMHfphVGP 6orQm1ZBx+7fHP5laRl4xiGUp5ZY6pCcO56AIMlntOo6JNs/4OoxZeiYBNI/kEWooyCT15h6SmyNm Yw6kG5fTlJ3IVnfZon2BvbOqRIIL4ofXyF4TdmMS5E5viTepUANt8rduIxZeEktSR66FAEaSG3eYB qhqKoQHw==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1qy4bA-008pb4-2g; Wed, 01 Nov 2023 06:21:04 +0000 From: Al Viro To: Linus Torvalds Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH 03/15] fast_dput(): new rules for refcount Date: Wed, 1 Nov 2023 06:20:52 +0000 Message-Id: <20231101062104.2104951-3-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231101062104.2104951-1-viro@zeniv.linux.org.uk> References: <20231031061226.GC1957730@ZenIV> <20231101062104.2104951-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro Currently the "need caller to do more work" path in fast_dput() has refcount decremented, then, with ->d_lock held and refcount verified to have reached 0 fast_dput() forcibly resets the refcount to 1. Move that resetting refcount to 1 into the callers; later in the series it will be massaged out of existence. Signed-off-by: Al Viro --- fs/dcache.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index ddc534b39c22..4108312f2426 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -847,13 +847,6 @@ static inline bool fast_dput(struct dentry *dentry) spin_unlock(&dentry->d_lock); return true; } - - /* - * Re-get the reference we optimistically dropped. We hold the - * lock, and we just tested that it was zero, so we can just - * set it to 1. - */ - dentry->d_lockref.count = 1; return false; } @@ -896,6 +889,7 @@ void dput(struct dentry *dentry) } /* Slow case: now with the dentry lock held */ + dentry->d_lockref.count = 1; rcu_read_unlock(); if (likely(retain_dentry(dentry))) { @@ -930,6 +924,7 @@ void dput_to_list(struct dentry *dentry, struct list_head *list) return; } rcu_read_unlock(); + dentry->d_lockref.count = 1; if (!retain_dentry(dentry)) __dput_to_list(dentry, list); spin_unlock(&dentry->d_lock); From patchwork Wed Nov 1 06:20:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13442544 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 22AA44C77 for ; Wed, 1 Nov 2023 06:21:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="uOpuA62q" Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [IPv6:2a03:a000:7:0:5054:ff:fe1c:15ff]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 65AE8103 for ; Tue, 31 Oct 2023 23:21:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=PB+QJiXgv7sl+bi1VPVybedtn0XOVtO2m/ve7LmZ9Uo=; b=uOpuA62qeF33kd5aTwUvz7n0SU sn2Rn5E/VzV8e7j0ahY0LPKGPc7JgTYkU/yhhP8NSJ6iBYm+tts7jfRuba68PvHxATqsZb3690qv1 DjrxNknil1J9Ilf4/lfPwSmttdKY2RSy3mGWlKbpoUxh6pWy45J6XxPo0dqLQT6B2A/OPTDymNAcf AuJxeEPSp9Ctaz0DQYWLsb/rUrYBvs5ZpXgTXXxW6MQeyHaCc9IWpvo9Cb2d83YiNiO0YKN4CnGiO pkaBsNNpkhSOIhnq1b3ii5shURgt1hA3sFOuSo6CUq71HXzmS3fXiB5X7wAeYGhOk9W6tdB1ZJu0D 0DaBSTRA==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1qy4bB-008pb9-04; Wed, 01 Nov 2023 06:21:05 +0000 From: Al Viro To: Linus Torvalds Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH 04/15] __dput_to_list(): do decrement of refcount in the caller Date: Wed, 1 Nov 2023 06:20:53 +0000 Message-Id: <20231101062104.2104951-4-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231101062104.2104951-1-viro@zeniv.linux.org.uk> References: <20231031061226.GC1957730@ZenIV> <20231101062104.2104951-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro ... and rename it to to_shrink_list(), seeing that it no longer does dropping any references Signed-off-by: Al Viro --- fs/dcache.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index 4108312f2426..3a160717620b 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -902,16 +902,13 @@ void dput(struct dentry *dentry) } EXPORT_SYMBOL(dput); -static void __dput_to_list(struct dentry *dentry, struct list_head *list) +static void to_shrink_list(struct dentry *dentry, struct list_head *list) __must_hold(&dentry->d_lock) { - if (dentry->d_flags & DCACHE_SHRINK_LIST) { - /* let the owner of the list it's on deal with it */ - --dentry->d_lockref.count; - } else { + if (!(dentry->d_flags & DCACHE_SHRINK_LIST)) { if (dentry->d_flags & DCACHE_LRU_LIST) d_lru_del(dentry); - if (!--dentry->d_lockref.count) + if (!dentry->d_lockref.count) d_shrink_add(dentry, list); } } @@ -925,8 +922,10 @@ void dput_to_list(struct dentry *dentry, struct list_head *list) } rcu_read_unlock(); dentry->d_lockref.count = 1; - if (!retain_dentry(dentry)) - __dput_to_list(dentry, list); + if (!retain_dentry(dentry)) { + --dentry->d_lockref.count; + to_shrink_list(dentry, list); + } spin_unlock(&dentry->d_lock); } @@ -1184,8 +1183,10 @@ void shrink_dentry_list(struct list_head *list) rcu_read_unlock(); d_shrink_del(dentry); parent = dentry->d_parent; - if (parent != dentry) - __dput_to_list(parent, list); + if (parent != dentry) { + --parent->d_lockref.count; + to_shrink_list(parent, list); + } __dentry_kill(dentry); } } @@ -1631,8 +1632,10 @@ void shrink_dcache_parent(struct dentry *parent) } else { rcu_read_unlock(); parent = data.victim->d_parent; - if (parent != data.victim) - __dput_to_list(parent, &data.dispose); + if (parent != data.victim) { + --parent->d_lockref.count; + to_shrink_list(parent, &data.dispose); + } __dentry_kill(data.victim); } } From patchwork Wed Nov 1 06:20:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13442543 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 721914C7D for ; Wed, 1 Nov 2023 06:21:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="MEy9hrrp" Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [IPv6:2a03:a000:7:0:5054:ff:fe1c:15ff]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 753CD107 for ; Tue, 31 Oct 2023 23:21:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=SvPxrMZFAiSVcjZWENm2ZenEXh8APeZaBdN2UZkjwDo=; b=MEy9hrrpouORBCSjxbR+1Mk/t4 4odDq918z9AKf5e7no7jg/ShROfE0/IRA5V0zcBPggSTuMLpZlUbfyA4n70S/EcyUk/x4nOxZ2oGq J7ulQ0JIuWdxg72TtPwWxrvtwGvykFvnu+eCw89yvT/UnUfZH2DLoLG2K/V0a34FRc/mEY6GkAC/I PyJ4QCpRf2QZ7nW/WT4NxKg6Fx2F7/zTKdCXc6WLuMjh6ZPfFy89yG5W8g75wDqD6XaKtm0OWH8n+ Zy8jOlLUPu9XHvkHaPXqXmlHML2jyLyKmkqCcFLttHfF+IZ3XhHFCp11Z7BVWTwr/Gc1PVHqLHJ5n +LBVw3/g==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1qy4bB-008pbD-0T; Wed, 01 Nov 2023 06:21:05 +0000 From: Al Viro To: Linus Torvalds Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH 05/15] retain_dentry(): lift decrement of ->d_count into callers Date: Wed, 1 Nov 2023 06:20:54 +0000 Message-Id: <20231101062104.2104951-5-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231101062104.2104951-1-viro@zeniv.linux.org.uk> References: <20231031061226.GC1957730@ZenIV> <20231101062104.2104951-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro Signed-off-by: Al Viro --- fs/dcache.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/dcache.c b/fs/dcache.c index 3a160717620b..0114b5195535 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -680,7 +680,6 @@ static inline bool retain_dentry(struct dentry *dentry) return false; /* retain; LRU fodder */ - dentry->d_lockref.count--; if (unlikely(!(dentry->d_flags & DCACHE_LRU_LIST))) d_lru_add(dentry); else if (unlikely(!(dentry->d_flags & DCACHE_REFERENCED))) @@ -744,6 +743,8 @@ static struct dentry *dentry_kill(struct dentry *dentry) } else if (likely(!retain_dentry(dentry))) { __dentry_kill(dentry); return parent; + } else { + dentry->d_lockref.count--; } /* we are keeping it, after all */ if (inode) @@ -893,6 +894,7 @@ void dput(struct dentry *dentry) rcu_read_unlock(); if (likely(retain_dentry(dentry))) { + dentry->d_lockref.count--; spin_unlock(&dentry->d_lock); return; } @@ -925,6 +927,8 @@ void dput_to_list(struct dentry *dentry, struct list_head *list) if (!retain_dentry(dentry)) { --dentry->d_lockref.count; to_shrink_list(dentry, list); + } else { + --dentry->d_lockref.count; } spin_unlock(&dentry->d_lock); } From patchwork Wed Nov 1 06:20:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13442546 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8BEB84C9D for ; Wed, 1 Nov 2023 06:21:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="KZ9rrlK/" Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [IPv6:2a03:a000:7:0:5054:ff:fe1c:15ff]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B7E6D109 for ; Tue, 31 Oct 2023 23:21:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=bVAC0xn/T//BfwlaeunxSYF+WLil1xBRbyJlVwXrimo=; b=KZ9rrlK/37OftthbMYIHj35NVO U2MPqS6MfRmCHf3SS90oA4P2dasHYlacKGSjWiqiakNA78wHLNZxz7OXYOD+sU0nCoL7w7a7vgYzj 9KXPY8QPIRkxVX75no96H/uKabr+ou1/9jpUQyAURAnMI+RhRsEolg2YJR+lNcTQILESKkrWXJLUK fNadKDsrjC155MW+X4zc3QWmYurd/ruv9ileL9qaD/uQBXDyN/vMya+4Slfb9SLTMWd/EDQ8kHB/+ NxivTy9E5B1/waIWrZ5b4DxRfKxFWG8V9l3IqGjatdlb9CPRej+hpj57/UA0qQzaH+fL5NWbPrs8g lr/IEbdA==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1qy4bB-008pbI-0n; Wed, 01 Nov 2023 06:21:05 +0000 From: Al Viro To: Linus Torvalds Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH 06/15] __dentry_kill(): get consistent rules for ->d_count Date: Wed, 1 Nov 2023 06:20:55 +0000 Message-Id: <20231101062104.2104951-6-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231101062104.2104951-1-viro@zeniv.linux.org.uk> References: <20231031061226.GC1957730@ZenIV> <20231101062104.2104951-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro Currently we call it with ->d_count equal to 1 when called from dentry_kill(); all other callers have ->d_count equal to 0. Make it always be called with zero ->d_count; on this step we just decrement it before the calls in dentry_kill(). That is safe, since all places that care about the value of ->d_count either do that under ->d_lock or hold a reference to dentry in question. Either is sufficient to prevent observing a dentry immediately prior to __dentry_kill() call from dentry_kill(). Signed-off-by: Al Viro --- fs/dcache.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/dcache.c b/fs/dcache.c index 0114b5195535..c89337ae30ce 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -729,6 +729,7 @@ static struct dentry *dentry_kill(struct dentry *dentry) goto slow_positive; } } + dentry->d_lockref.count--; __dentry_kill(dentry); return parent; @@ -741,6 +742,7 @@ static struct dentry *dentry_kill(struct dentry *dentry) if (unlikely(dentry->d_lockref.count != 1)) { dentry->d_lockref.count--; } else if (likely(!retain_dentry(dentry))) { + dentry->d_lockref.count--; __dentry_kill(dentry); return parent; } else { From patchwork Wed Nov 1 06:20:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13442542 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9A1E65224 for ; Wed, 1 Nov 2023 06:21:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="KwiIsE6J" Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [IPv6:2a03:a000:7:0:5054:ff:fe1c:15ff]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 047D910A for ; Tue, 31 Oct 2023 23:21:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=V//OsntlN/Gep20c5b55GzSyavMNgG4NgGG0fgQjpcU=; b=KwiIsE6Jce/0SVmi7gjQIn1rE5 Dgi4yrEBZTxJE8Hwm4S4ui0ST0VMU3KMP7QMcykvsBh0PvkA1CThdiedShpM/z5WBvYR1QEckS0XJ h9k7lajhluf5m8AXHSZkVrUjXtE26dUi0auzX9DeqkxRH5R7EKtdISUq0VVUY2/MZw2gzp21vyA8D 0AYUngX0ce5ttwCfinOCAVC/9ciFQ3a6ken2bytQNTtKCnxPPi9uPbw/JVoXPqrMbgXDcmTr062iY aopjNWM9l0H/3GH9PXojhNVUOgiIm5RkAsei0F37uDEsJCtPASVAKcR/ry92saB42PzlqELrMyz4v KUXyb7RA==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1qy4bB-008pbN-1Q; Wed, 01 Nov 2023 06:21:05 +0000 From: Al Viro To: Linus Torvalds Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH 07/15] dentry_kill(): don't bother with retain_dentry() on slow path Date: Wed, 1 Nov 2023 06:20:56 +0000 Message-Id: <20231101062104.2104951-7-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231101062104.2104951-1-viro@zeniv.linux.org.uk> References: <20231031061226.GC1957730@ZenIV> <20231101062104.2104951-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro We have already checked it and dentry used to look not worthy of keeping. The only hard obstacle to evicting dentry is non-zero refcount; everything else is advisory - e.g. memory pressure could evict any dentry found with refcount zero. On the slow path in dentry_kill() we had dropped and regained ->d_lock; we must recheck the refcount, but everything else is not worth bothering with. Note that filesystem can not count upon ->d_delete() being called for dentry - not even once. Again, memory pressure (as well as d_prune_aliases(), or attempted rmdir() of ancestor, or...) will not call ->d_delete() at all. So from the correctness point of view we are fine doing the check only once. And it makes things simpler down the road. Signed-off-by: Al Viro --- fs/dcache.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index c89337ae30ce..7931f5108581 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -739,14 +739,10 @@ static struct dentry *dentry_kill(struct dentry *dentry) spin_lock(&dentry->d_lock); parent = lock_parent(dentry); got_locks: - if (unlikely(dentry->d_lockref.count != 1)) { - dentry->d_lockref.count--; - } else if (likely(!retain_dentry(dentry))) { - dentry->d_lockref.count--; + dentry->d_lockref.count--; + if (likely(dentry->d_lockref.count == 0)) { __dentry_kill(dentry); return parent; - } else { - dentry->d_lockref.count--; } /* we are keeping it, after all */ if (inode) From patchwork Wed Nov 1 06:20:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13442553 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4BE92525C for ; Wed, 1 Nov 2023 06:21:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="i1Seu3Z3" Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [IPv6:2a03:a000:7:0:5054:ff:fe1c:15ff]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0940B10C for ; Tue, 31 Oct 2023 23:21:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=Lkp+2fm9lMJNrMAa25F2i48vZRPL8r1UmkUGziNmOMk=; b=i1Seu3Z39FiN0LqmCJDhmuxVTk nZ5P8VhCQ2wI1EYv5IUNZhq5gXm+F0H/35tEW16hP0zMmNETuL4Zv3t8RFAYzevONIngYEmefzGvu FgaZpqlmpWbBpraR8D31vi0ZKUf1JemILnzl4cR7o4i/+feNWyQgQdkdFaSHFQGlGbH2xpdSmFJ6C 7d6ai8BuQJbnb+JoXFWtZZ9eRJr+ZyNbjT191AB9ivwPYTLcXj4Z1ApdiGrO8XLtesE3ghLziHwtq 03YD9fFR6wFc8Ji1rW3qwlq/rFYDZ12KvZqfd5YB37c5WEMqRPZvlEbHAlxDa9dMhO6Cjzrd3bP4o 9QgK/5lQ==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1qy4bB-008pbT-2A; Wed, 01 Nov 2023 06:21:05 +0000 From: Al Viro To: Linus Torvalds Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH 08/15] Call retain_dentry() with refcount 0 Date: Wed, 1 Nov 2023 06:20:57 +0000 Message-Id: <20231101062104.2104951-8-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231101062104.2104951-1-viro@zeniv.linux.org.uk> References: <20231031061226.GC1957730@ZenIV> <20231101062104.2104951-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro Instead of bumping it from 0 to 1, calling retain_dentry(), then decrementing it back to 0 (with ->d_lock held all the way through), just leave refcount at 0 through all of that. It will have a visible effect for ->d_delete() - now it can be called with refcount 0 instead of 1 and it can no longer play silly buggers with dropping/regaining ->d_lock. Not that any in-tree instances tried to (it's pretty hard to get right). Any out-of-tree ones will have to adjust (assuming they need any changes). Note that we do not need to extend rcu-critical area here - we have verified that refcount is non-negative after having grabbed ->d_lock, so nobody will be able to free dentry until they get into __dentry_kill(), which won't happen until they manage to grab ->d_lock. Signed-off-by: Al Viro --- fs/dcache.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index 7931f5108581..30bebec591db 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -888,15 +888,14 @@ void dput(struct dentry *dentry) } /* Slow case: now with the dentry lock held */ - dentry->d_lockref.count = 1; rcu_read_unlock(); if (likely(retain_dentry(dentry))) { - dentry->d_lockref.count--; spin_unlock(&dentry->d_lock); return; } + dentry->d_lockref.count = 1; dentry = dentry_kill(dentry); } } @@ -921,13 +920,8 @@ void dput_to_list(struct dentry *dentry, struct list_head *list) return; } rcu_read_unlock(); - dentry->d_lockref.count = 1; - if (!retain_dentry(dentry)) { - --dentry->d_lockref.count; + if (!retain_dentry(dentry)) to_shrink_list(dentry, list); - } else { - --dentry->d_lockref.count; - } spin_unlock(&dentry->d_lock); } From patchwork Wed Nov 1 06:20:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13442545 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 48BF95259 for ; Wed, 1 Nov 2023 06:21:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="lSmNgkBD" Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [IPv6:2a03:a000:7:0:5054:ff:fe1c:15ff]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 525EF10D for ; Tue, 31 Oct 2023 23:21:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=zpdnSFVugoDtmYk3R2KgP33Suti6PPLm/8GkpqINmE0=; b=lSmNgkBD+li+gSyezQY7Eq4CxI Lr4G/yapEImmI35E+hJvEiUdkfIr2mt2wry6VQkXnw1J2o5UsxWxEQo5JfMt0GIzhdCnQ9PodPyAm Pch+n+ClcsK0gtl86Srlf44W94cIAJtP9hU6XuYlJ+a2XmzauTuAOh1+FnrYXNPsQR76p7cI9oBQM koedFHn2NeMjj0uOdYXpeL34dAdG8z2cGYwc05QtMzDFXcZ/OA7CAqCR0wkPwczzR7A3HiVFdhUhK 9dOcd4hZil7zIxFHPBOY6DVd0CbQNYDcoZofgSmL5eMTh7t81gyjgNVeCeiaS3FZk6m/6VUpyChKv vzp1PkFw==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1qy4bB-008pbX-2T; Wed, 01 Nov 2023 06:21:05 +0000 From: Al Viro To: Linus Torvalds Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH 09/15] fold the call of retain_dentry() into fast_dput() Date: Wed, 1 Nov 2023 06:20:58 +0000 Message-Id: <20231101062104.2104951-9-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231101062104.2104951-1-viro@zeniv.linux.org.uk> References: <20231031061226.GC1957730@ZenIV> <20231101062104.2104951-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro Calls of retain_dentry() happen immediately after getting false from fast_dput() and getting true from retain_dentry() is treated the same way as non-zero refcount would be treated by fast_dput() - unlock dentry and bugger off. Doing that in fast_dput() itself is simpler. Signed-off-by: Al Viro --- fs/dcache.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index 30bebec591db..6f79d452af81 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -757,6 +757,8 @@ static struct dentry *dentry_kill(struct dentry *dentry) * Try to do a lockless dput(), and return whether that was successful. * * If unsuccessful, we return false, having already taken the dentry lock. + * In that case refcount is guaranteed to be zero and we have already + * decided that it's not worth keeping around. * * The caller needs to hold the RCU read lock, so that the dentry is * guaranteed to stay around even if the refcount goes down to zero! @@ -842,7 +844,7 @@ static inline bool fast_dput(struct dentry *dentry) * don't need to do anything else. */ locked: - if (dentry->d_lockref.count) { + if (dentry->d_lockref.count || retain_dentry(dentry)) { spin_unlock(&dentry->d_lock); return true; } @@ -889,12 +891,6 @@ void dput(struct dentry *dentry) /* Slow case: now with the dentry lock held */ rcu_read_unlock(); - - if (likely(retain_dentry(dentry))) { - spin_unlock(&dentry->d_lock); - return; - } - dentry->d_lockref.count = 1; dentry = dentry_kill(dentry); } @@ -920,8 +916,7 @@ void dput_to_list(struct dentry *dentry, struct list_head *list) return; } rcu_read_unlock(); - if (!retain_dentry(dentry)) - to_shrink_list(dentry, list); + to_shrink_list(dentry, list); spin_unlock(&dentry->d_lock); } From patchwork Wed Nov 1 06:20:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13442549 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E9DB6566E for ; Wed, 1 Nov 2023 06:21:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="cqVS6SNq" Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [IPv6:2a03:a000:7:0:5054:ff:fe1c:15ff]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5E60B10F for ; Tue, 31 Oct 2023 23:21:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=DbXu/yKnLFvwPGdykH6QtLSjR3cIIUUzTgydfqY0+gA=; b=cqVS6SNq0yQ37eoUPCQhJXz6LX ZiNbFV9EkwyJy4PAJu0d22NmG57+nz6Qj6b7GW+ELeQlhjgVvHyw66RVJQiOIDDyxfdI7LEXzxD0A V4Mn13R6+JxgDACU5+Vj304EmUz8sKymiZu8FiegTUt0K+ZyiOkp96UhSxa5DtMeKGkQgiSbq/iyB D+pcKYurDTa3MI352YXWR3nJZfYcnJH25wIm5XDpLvnJRRKkiFgW939agOrtbUkplieGN/JNsup1B Q7vzLqVG0SqAmBsw1Ekxz3eEBtxYMXdlPlqHHaBOmqbxycr3u6GMo2NIbTVPBwhRcmKJNj/PitOL3 YeXUJOFQ==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1qy4bB-008pbd-30; Wed, 01 Nov 2023 06:21:05 +0000 From: Al Viro To: Linus Torvalds Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH 10/15] don't try to cut corners in shrink_lock_dentry() Date: Wed, 1 Nov 2023 06:20:59 +0000 Message-Id: <20231101062104.2104951-10-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231101062104.2104951-1-viro@zeniv.linux.org.uk> References: <20231031061226.GC1957730@ZenIV> <20231101062104.2104951-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro That is to say, do *not* treat the ->d_inode or ->d_parent changes as "it's hard, return false; somebody must have grabbed it, so even if has zero refcount, we don't need to bother killing it - final dput() from whoever grabbed it would've done everything". First of all, that is not guaranteed. It might have been dropped by dput_to_list(), which would've found it already on a shrink list (ours) and decided that they don't need to put it on their shrink list. What's more, dentry_kill() is doing pretty much the same thing, cutting its own set of corners (it assumes that dentry can't go from positive to negative, so inode can change but only once and only in one direction). Doing that right allows to get rid of that not-quite-duplication and removes the only reason to play silly buggers with re-incrementing refcount before dentry_kill(). Replacement is called lock_for_kill(); called under rcu_read_lock and with ->d_lock held. If it returns false, dentry has non-zero refcount and the same locks are held. If it returns true, dentry has zero refcount and its parent and inode (if any) are locked. Part of __lock_parent() had been lifted into lock_parent() to allow its reuse. Now it's called with rcu_read_lock already held and dentry already unlocked. Signed-off-by: Al Viro --- fs/dcache.c | 159 ++++++++++++++++++++++------------------------------ 1 file changed, 66 insertions(+), 93 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index 6f79d452af81..5fd6162cd994 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -625,8 +625,6 @@ static void __dentry_kill(struct dentry *dentry) static struct dentry *__lock_parent(struct dentry *dentry) { struct dentry *parent; - rcu_read_lock(); - spin_unlock(&dentry->d_lock); again: parent = READ_ONCE(dentry->d_parent); spin_lock(&parent->d_lock); @@ -642,7 +640,6 @@ static struct dentry *__lock_parent(struct dentry *dentry) spin_unlock(&parent->d_lock); goto again; } - rcu_read_unlock(); if (parent != dentry) spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); else @@ -657,7 +654,64 @@ static inline struct dentry *lock_parent(struct dentry *dentry) return NULL; if (likely(spin_trylock(&parent->d_lock))) return parent; - return __lock_parent(dentry); + rcu_read_lock(); + spin_unlock(&dentry->d_lock); + parent = __lock_parent(dentry); + rcu_read_unlock(); + return parent; +} + +/* + * Lock a dentry for feeding it to __dentry_kill(). + * Called under rcu_read_lock() and dentry->d_lock; the former + * guarantees that nothing we access will be freed under us. + * Note that dentry is *not* protected from concurrent dentry_kill(), + * d_delete(), etc. + * + * Return false if dentry is busy. Otherwise, return true and have + * that dentry's inode and parent both locked. + */ + +static bool lock_for_kill(struct dentry *dentry) +{ + struct inode *inode = dentry->d_inode; + struct dentry *parent = dentry->d_parent; + + if (unlikely(dentry->d_lockref.count)) + return false; + + if (inode && unlikely(!spin_trylock(&inode->i_lock))) + goto slow; + if (dentry == parent) + return true; + if (likely(spin_trylock(&parent->d_lock))) + return true; + + if (inode) + spin_unlock(&inode->i_lock); +slow: + spin_unlock(&dentry->d_lock); + + for (;;) { + if (inode) + spin_lock(&inode->i_lock); + parent = __lock_parent(dentry); + if (likely(inode == dentry->d_inode)) + break; + if (inode) + spin_unlock(&inode->i_lock); + inode = dentry->d_inode; + spin_unlock(&dentry->d_lock); + if (parent) + spin_unlock(&parent->d_lock); + } + if (likely(!dentry->d_lockref.count)) + return true; + if (inode) + spin_unlock(&inode->i_lock); + if (parent) + spin_unlock(&parent->d_lock); + return false; } static inline bool retain_dentry(struct dentry *dentry) @@ -710,45 +764,16 @@ EXPORT_SYMBOL(d_mark_dontcache); static struct dentry *dentry_kill(struct dentry *dentry) __releases(dentry->d_lock) { - struct inode *inode = dentry->d_inode; - struct dentry *parent = NULL; - if (inode && unlikely(!spin_trylock(&inode->i_lock))) - goto slow_positive; - - if (!IS_ROOT(dentry)) { - parent = dentry->d_parent; - if (unlikely(!spin_trylock(&parent->d_lock))) { - parent = __lock_parent(dentry); - if (likely(inode || !dentry->d_inode)) - goto got_locks; - /* negative that became positive */ - if (parent) - spin_unlock(&parent->d_lock); - inode = dentry->d_inode; - goto slow_positive; - } - } dentry->d_lockref.count--; - __dentry_kill(dentry); - return parent; - -slow_positive: - spin_unlock(&dentry->d_lock); - spin_lock(&inode->i_lock); - spin_lock(&dentry->d_lock); - parent = lock_parent(dentry); -got_locks: - dentry->d_lockref.count--; - if (likely(dentry->d_lockref.count == 0)) { + rcu_read_lock(); + if (likely(lock_for_kill(dentry))) { + struct dentry *parent = dentry->d_parent; + rcu_read_unlock(); __dentry_kill(dentry); - return parent; + return parent != dentry ? parent : NULL; } - /* we are keeping it, after all */ - if (inode) - spin_unlock(&inode->i_lock); - if (parent) - spin_unlock(&parent->d_lock); + rcu_read_unlock(); spin_unlock(&dentry->d_lock); return NULL; } @@ -1100,58 +1125,6 @@ void d_prune_aliases(struct inode *inode) } EXPORT_SYMBOL(d_prune_aliases); -/* - * Lock a dentry from shrink list. - * Called under rcu_read_lock() and dentry->d_lock; the former - * guarantees that nothing we access will be freed under us. - * Note that dentry is *not* protected from concurrent dentry_kill(), - * d_delete(), etc. - * - * Return false if dentry has been disrupted or grabbed, leaving - * the caller to kick it off-list. Otherwise, return true and have - * that dentry's inode and parent both locked. - */ -static bool shrink_lock_dentry(struct dentry *dentry) -{ - struct inode *inode; - struct dentry *parent; - - if (dentry->d_lockref.count) - return false; - - inode = dentry->d_inode; - if (inode && unlikely(!spin_trylock(&inode->i_lock))) { - spin_unlock(&dentry->d_lock); - spin_lock(&inode->i_lock); - spin_lock(&dentry->d_lock); - if (unlikely(dentry->d_lockref.count)) - goto out; - /* changed inode means that somebody had grabbed it */ - if (unlikely(inode != dentry->d_inode)) - goto out; - } - - parent = dentry->d_parent; - if (IS_ROOT(dentry) || likely(spin_trylock(&parent->d_lock))) - return true; - - spin_unlock(&dentry->d_lock); - spin_lock(&parent->d_lock); - if (unlikely(parent != dentry->d_parent)) { - spin_unlock(&parent->d_lock); - spin_lock(&dentry->d_lock); - goto out; - } - spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); - if (likely(!dentry->d_lockref.count)) - return true; - spin_unlock(&parent->d_lock); -out: - if (inode) - spin_unlock(&inode->i_lock); - return false; -} - void shrink_dentry_list(struct list_head *list) { while (!list_empty(list)) { @@ -1160,7 +1133,7 @@ void shrink_dentry_list(struct list_head *list) dentry = list_entry(list->prev, struct dentry, d_lru); spin_lock(&dentry->d_lock); rcu_read_lock(); - if (!shrink_lock_dentry(dentry)) { + if (!lock_for_kill(dentry)) { bool can_free = false; rcu_read_unlock(); d_shrink_del(dentry); @@ -1617,7 +1590,7 @@ void shrink_dcache_parent(struct dentry *parent) if (data.victim) { struct dentry *parent; spin_lock(&data.victim->d_lock); - if (!shrink_lock_dentry(data.victim)) { + if (!lock_for_kill(data.victim)) { spin_unlock(&data.victim->d_lock); rcu_read_unlock(); } else { From patchwork Wed Nov 1 06:21:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13442552 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CF3BA53B1 for ; Wed, 1 Nov 2023 06:21:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="IF/ET1os" Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [IPv6:2a03:a000:7:0:5054:ff:fe1c:15ff]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6F940110 for ; Tue, 31 Oct 2023 23:21:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=5+41tHy7ARJSzJbpFvlMd/+F3I2wESoLEQET99y7ENA=; b=IF/ET1osNBXHMSXZTgh0s22czi UzzfdfolujQUIWQMGdxi/E3G7HQ/JBwG/fyXioe7W5IFhvTBXoxIq7wWMY/bMS8UlSCGC0400gFr+ zjsL9FdOzR8ghCY0J4HdyfOfkxB4GG/YQu6o9k4R9gVa4HPDV0CfIbxiMMei+Hwsr74LlIjdlp8G6 igsguH9glo9bRuhnI2utCEYxeEHKyNXmAwDBIvX3FJ37W7ZfBvlXwfvJzVYfSS0OGp/cp/4BuHYrS tJWbE4UQ4QPsQ6UHf47vGp9rbUHPQgyCqsrYkg1l/twdGKue0zlMkJg+1ZAzgi71iF9tV0a/3lAzQ 8xZimZnA==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1qy4bC-008pbj-0F; Wed, 01 Nov 2023 06:21:06 +0000 From: Al Viro To: Linus Torvalds Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH 11/15] fold dentry_kill() into dput() Date: Wed, 1 Nov 2023 06:21:00 +0000 Message-Id: <20231101062104.2104951-11-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231101062104.2104951-1-viro@zeniv.linux.org.uk> References: <20231031061226.GC1957730@ZenIV> <20231101062104.2104951-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro Signed-off-by: Al Viro --- fs/dcache.c | 37 ++++++++++++------------------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index 5fd6162cd994..5114514b13da 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -756,28 +756,6 @@ void d_mark_dontcache(struct inode *inode) } EXPORT_SYMBOL(d_mark_dontcache); -/* - * Finish off a dentry we've decided to kill. - * dentry->d_lock must be held, returns with it unlocked. - * Returns dentry requiring refcount drop, or NULL if we're done. - */ -static struct dentry *dentry_kill(struct dentry *dentry) - __releases(dentry->d_lock) -{ - - dentry->d_lockref.count--; - rcu_read_lock(); - if (likely(lock_for_kill(dentry))) { - struct dentry *parent = dentry->d_parent; - rcu_read_unlock(); - __dentry_kill(dentry); - return parent != dentry ? parent : NULL; - } - rcu_read_unlock(); - spin_unlock(&dentry->d_lock); - return NULL; -} - /* * Try to do a lockless dput(), and return whether that was successful. * @@ -915,9 +893,18 @@ void dput(struct dentry *dentry) } /* Slow case: now with the dentry lock held */ - rcu_read_unlock(); - dentry->d_lockref.count = 1; - dentry = dentry_kill(dentry); + if (likely(lock_for_kill(dentry))) { + struct dentry *parent = dentry->d_parent; + rcu_read_unlock(); + __dentry_kill(dentry); + if (dentry == parent) + return; + dentry = parent; + } else { + rcu_read_unlock(); + spin_unlock(&dentry->d_lock); + return; + } } } EXPORT_SYMBOL(dput); From patchwork Wed Nov 1 06:21:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13442548 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3F2DB567B for ; Wed, 1 Nov 2023 06:21:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="PzjSPrlX" Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [IPv6:2a03:a000:7:0:5054:ff:fe1c:15ff]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A162D115 for ; Tue, 31 Oct 2023 23:21:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=9or3l6Cp/vSjabqxKVwqFh+NlAwQ4vZcxCP3EWANQAs=; b=PzjSPrlXxrkx8iw6JQa1B4ajo6 BWIK3yAIxiaZRq9dvIKg2C5+mpsgQmQ0DIcDgVTNOPLPNNNQwnX5PZeTSpSu+FJ+CHdYTf/TBwp6S mteMCzK8Nh3ZAwVlhaKlkRIootALRquNMGrSd01670aAD9u2voZP7fjI5G0TVLPNR+MN8II4bN4e3 Z+K73eYs++uIr6aSmc1et94qNPzc0R4Z49F+f1+mnuGjDOJb7icpOqu02DRh3otjYLATcP2b7BUW2 yyVFcaiYV2uUIaiAeLlx8CP9Ja7qridHRWujzhTLWfZrJslCBm0ZZoWBZdxrOm/nUVTsZNsQHh8e4 LLk50Ecw==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1qy4bC-008pbo-0f; Wed, 01 Nov 2023 06:21:06 +0000 From: Al Viro To: Linus Torvalds Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH 12/15] get rid of __dget() Date: Wed, 1 Nov 2023 06:21:01 +0000 Message-Id: <20231101062104.2104951-12-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231101062104.2104951-1-viro@zeniv.linux.org.uk> References: <20231031061226.GC1957730@ZenIV> <20231101062104.2104951-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro fold into the sole remaining caller Signed-off-by: Al Viro --- fs/dcache.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index 5114514b13da..49b3fd27559f 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -938,11 +938,6 @@ static inline void __dget_dlock(struct dentry *dentry) dentry->d_lockref.count++; } -static inline void __dget(struct dentry *dentry) -{ - lockref_get(&dentry->d_lockref); -} - struct dentry *dget_parent(struct dentry *dentry) { int gotref; @@ -992,7 +987,7 @@ static struct dentry * __d_find_any_alias(struct inode *inode) if (hlist_empty(&inode->i_dentry)) return NULL; alias = hlist_entry(inode->i_dentry.first, struct dentry, d_u.d_alias); - __dget(alias); + lockref_get(&alias->d_lockref); return alias; } From patchwork Wed Nov 1 06:21:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13442554 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 63DE15680 for ; Wed, 1 Nov 2023 06:21:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="UGTSWsCL" Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [IPv6:2a03:a000:7:0:5054:ff:fe1c:15ff]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D8FE7118 for ; Tue, 31 Oct 2023 23:21:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=a2WT2+Nor5ArukZaydSgJmmgdwCRxURWcNILbRX7aiw=; b=UGTSWsCLP8cagzaZ16jwbMWSxq vFKCLp9wzg9gxuuueY0fz0rZ5OghQAdnpzIJ5oC9h9TQ6OXJhu3/Bwa0s89/aYLC1sZ1SLszlpsAL tTnKAPaC4wWRZUOePLr5ab7gVif3VihAilDvdmS8gnnWmbYN9wtgg2irl+Ru+q/njaLRAGOy4xExx QszBQNpJEq+/sHH4n3zLch3UrNQ9bMCmUj52QApLdVJP7Rkoy4LEXSYNwkJWNLItW++jT5xw7fW7/ cbmFSfM3GgNukSxH9YDXsaG/bqEX6G5Za12aEYpB/8dBg01BInS8LnSs3NIFTpBAmfBWYSLzyIXcC zvEsaPyw==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1qy4bC-008pbt-1J; Wed, 01 Nov 2023 06:21:06 +0000 From: Al Viro To: Linus Torvalds Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH 13/15] shrink_dentry_list(): no need to check that dentry refcount is marked dead Date: Wed, 1 Nov 2023 06:21:02 +0000 Message-Id: <20231101062104.2104951-13-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231101062104.2104951-1-viro@zeniv.linux.org.uk> References: <20231031061226.GC1957730@ZenIV> <20231101062104.2104951-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro ... we won't see DCACHE_MAY_FREE on anything that is *not* dead and checking d_flags is just as cheap as checking d_count. Signed-off-by: Al Viro --- fs/dcache.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index 49b3fd27559f..19f6eb6f2bde 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1116,11 +1116,10 @@ void shrink_dentry_list(struct list_head *list) spin_lock(&dentry->d_lock); rcu_read_lock(); if (!lock_for_kill(dentry)) { - bool can_free = false; + bool can_free; rcu_read_unlock(); d_shrink_del(dentry); - if (dentry->d_lockref.count < 0) - can_free = dentry->d_flags & DCACHE_MAY_FREE; + can_free = dentry->d_flags & DCACHE_MAY_FREE; spin_unlock(&dentry->d_lock); if (can_free) dentry_free(dentry); From patchwork Wed Nov 1 06:21:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13442550 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B8B8D5690 for ; Wed, 1 Nov 2023 06:21:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="Jr+ZZ8Ah" Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [IPv6:2a03:a000:7:0:5054:ff:fe1c:15ff]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 14910119 for ; Tue, 31 Oct 2023 23:21:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=Ec0+hq0KYAliWa6/Vo79r/vvLGP1Ij7F88cec1tangk=; b=Jr+ZZ8AhaKDvO6jpkpKem1R1RU apgXwlzhweUErsu5B68F3oqi477dZtuwHj++gSr+vsi5zZAwH48/e4Td9LdHii8qsxicB97oCnbPz 52b2kRtRZKsIXthDr8I8V12f5U3QCgK9kFpf4SqJiZohS8p2iy7lFCRz1r9xUfKVeste29bvX7eLa 668d0a7NTfxDRh6iMOb7MLgLTKR+Qnpm4gDFdcLpGfDYEvkEbMiEbdOdsuWTW+BhYrYXgv56E02XO 8u0BOs1OjEIEaRsEtGmNEjiy4imfLrvLhYP4kapaoB/yBBcGFfQbXOGXkBIEfOLOPO5xoA6F51qWC OL8I1i2g==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1qy4bC-008pbz-1j; Wed, 01 Nov 2023 06:21:06 +0000 From: Al Viro To: Linus Torvalds Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH 14/15] to_shrink_list(): call only if refcount is 0 Date: Wed, 1 Nov 2023 06:21:03 +0000 Message-Id: <20231101062104.2104951-14-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231101062104.2104951-1-viro@zeniv.linux.org.uk> References: <20231031061226.GC1957730@ZenIV> <20231101062104.2104951-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro The only thing it does if refcount is not zero is d_lru_del(); no point, IMO, seeing that plain dput() does nothing of that sort... Signed-off-by: Al Viro --- fs/dcache.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index 19f6eb6f2bde..7c763a8c916b 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -915,8 +915,7 @@ __must_hold(&dentry->d_lock) if (!(dentry->d_flags & DCACHE_SHRINK_LIST)) { if (dentry->d_flags & DCACHE_LRU_LIST) d_lru_del(dentry); - if (!dentry->d_lockref.count) - d_shrink_add(dentry, list); + d_shrink_add(dentry, list); } } @@ -1128,10 +1127,8 @@ void shrink_dentry_list(struct list_head *list) rcu_read_unlock(); d_shrink_del(dentry); parent = dentry->d_parent; - if (parent != dentry) { - --parent->d_lockref.count; + if (parent != dentry && !--parent->d_lockref.count) to_shrink_list(parent, list); - } __dentry_kill(dentry); } } @@ -1577,10 +1574,9 @@ void shrink_dcache_parent(struct dentry *parent) } else { rcu_read_unlock(); parent = data.victim->d_parent; - if (parent != data.victim) { - --parent->d_lockref.count; + if (parent != data.victim && + !--parent->d_lockref.count) to_shrink_list(parent, &data.dispose); - } __dentry_kill(data.victim); } } From patchwork Wed Nov 1 06:21:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13442551 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D35CE5691 for ; Wed, 1 Nov 2023 06:21:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="QQi1QDIA" Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [IPv6:2a03:a000:7:0:5054:ff:fe1c:15ff]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1753011A for ; Tue, 31 Oct 2023 23:21:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=lXzU4kGM9Zq1fG+oyulDDSAjEI0h3w6xOu+7dOr/nFo=; b=QQi1QDIAY8J6WnoAM9tJydU0QS J+teJA4fTDlzSSPYJLwfnWCkBJtqpZix/XdTq43jJHFSiEMSi/VurI9Y6GI9Ba11Ch2K/RP95kBfB VS+LfqK4l77VK/9T+J+JfMUQZ3KXPZeWi305wKAgIYcLFesY6Vdo8kSSrE6qg9x8owCeXfUPu4RYg evvPCho4YjAhUSqiv+HuTR8iOqRfWNgo/8WRRCPS7YcwfKKm+7WlgJfkogrr6sRhGDIFkJr5hWH3V 1BK3CLZ3FRTzHKiW/RChNYecuh2ImAwSVOcFP4dsxkMgBuae2X2HGJpIeJqUg4i56QfTBAn5UPEC9 fs5/Gk3w==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1qy4bC-008pc5-27; Wed, 01 Nov 2023 06:21:06 +0000 From: Al Viro To: Linus Torvalds Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH 15/15] switch select_collect{,2}() to use of to_shrink_list() Date: Wed, 1 Nov 2023 06:21:04 +0000 Message-Id: <20231101062104.2104951-15-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231101062104.2104951-1-viro@zeniv.linux.org.uk> References: <20231031061226.GC1957730@ZenIV> <20231101062104.2104951-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro Signed-off-by: Al Viro --- fs/dcache.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index 7c763a8c916b..c47d08da390f 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1491,13 +1491,9 @@ static enum d_walk_ret select_collect(void *_data, struct dentry *dentry) if (dentry->d_flags & DCACHE_SHRINK_LIST) { data->found++; - } else { - if (dentry->d_flags & DCACHE_LRU_LIST) - d_lru_del(dentry); - if (!dentry->d_lockref.count) { - d_shrink_add(dentry, &data->dispose); - data->found++; - } + } else if (!dentry->d_lockref.count) { + to_shrink_list(dentry, &data->dispose); + data->found++; } /* * We can return to the caller if we have found some (this @@ -1518,17 +1514,13 @@ static enum d_walk_ret select_collect2(void *_data, struct dentry *dentry) if (data->start == dentry) goto out; - if (dentry->d_flags & DCACHE_SHRINK_LIST) { - if (!dentry->d_lockref.count) { + if (!dentry->d_lockref.count) { + if (dentry->d_flags & DCACHE_SHRINK_LIST) { rcu_read_lock(); data->victim = dentry; return D_WALK_QUIT; } - } else { - if (dentry->d_flags & DCACHE_LRU_LIST) - d_lru_del(dentry); - if (!dentry->d_lockref.count) - d_shrink_add(dentry, &data->dispose); + to_shrink_list(dentry, &data->dispose); } /* * We can return to the caller if we have found some (this