Received: by 2002:a05:7412:7c14:b0:fa:6e18:a558 with SMTP id ii20csp410236rdb; Mon, 22 Jan 2024 07:58:13 -0800 (PST) X-Google-Smtp-Source: AGHT+IEKuhp5OSaCFsumqTGqDps8k3YnvwkozmLaYDwI2WtVdJ9ZPf32GGu5wkAw/jNuDf7tJsD6 X-Received: by 2002:a05:620a:25d1:b0:783:9c0e:723 with SMTP id y17-20020a05620a25d100b007839c0e0723mr2378144qko.43.1705939093146; Mon, 22 Jan 2024 07:58:13 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1705939093; cv=pass; d=google.com; s=arc-20160816; b=hbFGINUb3h7mfrCM7SalW6TGY9mKAmfQn01ral4z48pNAWJNpBdNgw5q7C+PeQ0kFE THe6MflF3Z0qsqLIxtM6rrqkMC6nkZHUmLdagy2xwFAk/40TmAznHgV4gWCpO7pghUQS aTkUAJ6/dd48PczKHDihzRlSJNXfKhmZxynPgjh9IgquIzuGB0YD2pLvzW1Xxk2pn7kN /M/LXwA6ejwaI/XxSXbSOtg6LO+AB9jDv4YkpDZg7tfuUhMoK21psW0mx0pSFuMK5JbH fK0dPnzgHb6b3VnfP1ymXlV2G5FgdoutWIIkdiZuAtUUTP5E+bzyvCSbEUtuGDYODo3Z k3KA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=d74xpyQxuBxm7oknIN965fSdOe+OkkqICfUSBYCUpbA=; fh=e0HxAyYvfZMcT+zbajL3oaRyKTyFpSmAVcmzaumet54=; b=r/9Cf8RxeuE+dUcQDKcRE07BsjNIuKigRHkCaYdep09jmy3SVqz+A/tZdcWx6LXxqL wWpT4Zr3rVhS2XIwnNVSsqUeYw9W3YPiCxgo04vz32zpkTIIeusAK2SNlT4sXVxe8wQv Vk2ncQ44Js9N9AE7bWuIN8O/J81xDBaCiaPhRMEWnvA4oxH4MlQsIC+FA75z5AufAeR3 4YnPuLtftetOvWdA3UrLehvKP3HreHlKUdT1ZrKQDB+9UyesTk3nmA0wfVtUAVR0o2oN LkjYS1dG3LOHRUfL8l/hXA50fISGADuYkeR2sg3OMu8W6qCnRqMKGcZQKL4087qcDlZD POsQ== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=FPkOEzLA; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-33405-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-33405-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [147.75.199.223]) by mx.google.com with ESMTPS id c27-20020a05620a269b00b007835770698dsi6260450qkp.778.2024.01.22.07.58.12 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 Jan 2024 07:58:13 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-33405-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) client-ip=147.75.199.223; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=FPkOEzLA; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-33405-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-33405-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id E08221C23684 for ; Mon, 22 Jan 2024 15:58:12 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id A2E037E573; Mon, 22 Jan 2024 15:10:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="FPkOEzLA" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 C17C67CF3B; Mon, 22 Jan 2024 15:10:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1705936200; cv=none; b=R6x8TGYUEq/zl0PakxRKAsaaIVDROVdPAgWsEKOhJ+vksc5fULXtSlqUr4ezoyBfXh+QmTHVTCI5KDM2ZfhPG046OKY6bVhPUdrBmGXJ6hb9SkObi0K3sRFTEm9TQiU3YBBH/s8OE0m6KI1bhgJ8D1NOX9DWNrHKHMOfDUd93f0= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1705936200; c=relaxed/simple; bh=oNw3w5nS83B0ZDRRZx4eoZomjkgdKcZdX7qABqD8vuM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FXQSbSkpacjGc5EewBbU18ThoHv5kQkwvx2kA8YHzLy9JEBxYT1G1I+/Yx0iAKtXrZWJHilSBCMJSYa8/qic+1Tj/x8WpiseT3Y3TDAtR875o7tRAIbFHQDcdLI+Zyx8GddRG+X40uohjV7JXfUWBFjdvC3RCzhwkd7F0+dpyJw= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=FPkOEzLA; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id CEC4EC433C7; Mon, 22 Jan 2024 15:09:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1705936200; bh=oNw3w5nS83B0ZDRRZx4eoZomjkgdKcZdX7qABqD8vuM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=FPkOEzLA0O7MbV6dr+WJjXTvY/5V6LymOQaA9+DjM2CmIwvdni0ksvgPEuEfS0Evl OSHffpsw6pjy9h0kRorNWB3Qkcc/hXUvbsTScsuORSEKhVw56jWiSLUq7KWrXDkB/V GTKnLh1TERk2f4rwYp2IaPrCdCGyZh6jzBKvd5AvHE8VPFhordjN+Cvor4MqOulO5j Lue4oRsEwLEuJuGth5ohQBj5hiwdtRs4EuKrgJs5sLXIeH2bRNG32q1cofqyCAl0bj 1CuWN5zoSPLQ+uSsxbqBWryTjhB8yRwyygNkA9vV5CrAGErJNrFNzgPyZEQ3UU9qmf Wg4T29YsKShtw== From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Al Viro , Christian Brauner , Sasha Levin , linux-fsdevel@vger.kernel.org Subject: [PATCH AUTOSEL 6.1 05/53] fast_dput(): handle underflows gracefully Date: Mon, 22 Jan 2024 10:08:06 -0500 Message-ID: <20240122150949.994249-5-sashal@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240122150949.994249-1-sashal@kernel.org> References: <20240122150949.994249-1-sashal@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore X-stable-base: Linux 6.1.74 Content-Transfer-Encoding: 8bit From: Al Viro [ Upstream commit 504e08cebe1d4e1efe25f915234f646e74a364a8 ] 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. Reviewed-by: Christian Brauner Signed-off-by: Al Viro Signed-off-by: Sasha Levin --- fs/dcache.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index 52e6d5fdab6b..b09bc88dbbec 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -787,12 +787,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; } /* @@ -850,6 +850,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; -- 2.43.0