From nobody Thu Apr 2 12:13:03 2026 Received: from mail-wm1-f46.google.com (mail-wm1-f46.google.com [209.85.128.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A17ED387357 for ; Sun, 29 Mar 2026 17:20:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774804827; cv=none; b=moJxH/7J3rEIoNiNsTIZfV9UQc4sy7UNgI9UI3+3HMGOirFXw0buwmIDxxwLIqbU8Z3PACUQJNJ5VHJ3zqx8LFLKncbhJwhvhTPleK9+JOn04mPRihfryncDT0IiftxiDuVDv0Z/vFOM2PjYBZelkvHwNgCiJmg7emyJjMdE1F4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774804827; c=relaxed/simple; bh=aDru4qjl/iYVBfN5B5xn9JTcaAG/lsaOLojHF6nk8UQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=LN1527ljBOW3pNsrZ8OZnrAL6wp/ZqIUHHZa+6o2lNI+Rbb6qd5EsGXWfQtk+k58a9sO/CXk4x3ZVy80Ki85RF6rRU+Q5hv4cXM+9HAPcCT3OPEPE8H1zVtKxNzwmzBLK+rNuMrszcw/pwtZHP5ao5YrFyKzmx3aHDlmhEMXenM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=s2bYDMpU; arc=none smtp.client-ip=209.85.128.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="s2bYDMpU" Received: by mail-wm1-f46.google.com with SMTP id 5b1f17b1804b1-48557c8ad47so28253545e9.0 for ; Sun, 29 Mar 2026 10:20:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1774804821; x=1775409621; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=tEImE9v8UsSlxEU0A2Tuvpp3kv2Is3KLwcc3BUa1x8Y=; b=s2bYDMpUKTbn49VtJb3RwtATDdzh9MsfJewiHhG9t9nD5vFxp2KlbIQDX5X9TouXa/ 99tcpKJhrUZBY7im241ZlAFzOuWOf+QVYJZjRrI3VTK2hutlVb8qGKFOKIfdXy4GQPyr wR5HRH/WloKyfzTiUPJfDAvwI8RpNU5EDtxifvuQY938TPNdxrU510kTXu3yLyVBPLM1 MIPsVBR8cowJyHuMhyl4tTQXV3aJrYowjgn22gwmey4UHHrOLw2JC94RPWZxx9Tbjy31 SfmWsVRIJpHeA5iv72qWmX41OmoxiKcx6fc18h38W3XVZx4hCtg7cUmo7WP9is5ETQM+ Xj4Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774804821; x=1775409621; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=tEImE9v8UsSlxEU0A2Tuvpp3kv2Is3KLwcc3BUa1x8Y=; b=JE79b2eZ/04OUXJDZVz95y002B8fzuE1kbrjL5imzNHMWwmf90ggq7GcGx+z9WNgRt xFNWx0ihFj2QjT3ZwuRxn5M4miBGVkC4Cfmh4Q/4dTIR3Qdl1pdsSyl8637p4PfW2O3k nk9G68r6qbS8j0+H+QJnh8lS7gk1j9Lhq10y9cpzFfoA5jcS81NF/q1PNC3IlBVTPYe/ jyhjogrDDIopEdg8XzpjJdX03RAJ3ed+VBn1681flLXgV4+I1rkaSnu+3niIRM2dvzEC QrhdrU6R7HZQ+k7oCr/7XpzpbtjHUOdw4umPK7hr3xRf9Mw/11CF/WBrp5J8WmqopXSx IRZw== X-Forwarded-Encrypted: i=1; AJvYcCV2O+TAjFkNVCGIhR8qGBU0BGIYIb2R6/fUEWYvqk461lOh7ZgTDM2ThojxWk8/x6f0t2bfJVK1fzKCb4U=@vger.kernel.org X-Gm-Message-State: AOJu0YxbRcmxsCF38DA93yD+rXeYY/M4d3UU2GShhLEw6jy59B8U5Iwy CKN0kIudbzTjHnF3beF0ETpCeOLYf8mtgbKa1i71k9l/EY5S997urgmR X-Gm-Gg: ATEYQzxbSjzGG8ldlqc3K63LgkVzIrQMQlmmFssNRwBXD6huPXfJZqMHGx8u0+Lenup S2lEIOfBXbg3lUCC9Pqaz4J67wU+3hh+Ylrxu7DlXlcoDpLBLH3ybT/s1E3iiy3BhmFoA65cakp 1N396WtO3My/JqC1NieLmrrCpuqqWhoqAYjPny58127ZcQXMYxBvAVjRflEicWMfj0UczjCQkq1 pD1RoTAqEtkInr1D/DPnJRtprYppoz7FhXnY3Vt9URdJoCEssxvj4brq8GbRP97/dEYrjgg8C82 zdyNbD48/psnnBG0aHuqhJOqu8wOwIQaPIx4uucjrnvM7W5rn/4e7httymW3AyTUHkHI7eUYEn9 TQdcyU2SFEPzLe1F4ChELZD/TVVttP2S+eB3fwbt6ZoR3ZFMfeS2hp+TB+YJjxceR53s0qItmUm NH3UwTuU7ORXQQuIHN8c5Ka6vMpB9+QMxuy+VGKjdcZpjMylH61RXWFyKg18eCZbnTj6dvA0dXV w== X-Received: by 2002:a05:600c:64c3:b0:477:6d96:b3e5 with SMTP id 5b1f17b1804b1-48727d59bb9mr164125175e9.7.1774804820679; Sun, 29 Mar 2026 10:20:20 -0700 (PDT) Received: from f.. (cst-prg-89-171.cust.vodafone.cz. [46.135.89.171]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4873cd7d039sm9776805e9.15.2026.03.29.10.20.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 29 Mar 2026 10:20:20 -0700 (PDT) From: Mateusz Guzik To: brauner@kernel.org Cc: viro@zeniv.linux.org.uk, jack@suse.cz, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, Mateusz Guzik Subject: [PATCH v3 6/7] fs: locklessly bump refs in igrab as long as it does not transition 0->1 Date: Sun, 29 Mar 2026 19:20:01 +0200 Message-ID: <20260329172002.3557801-7-mjguzik@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260329172002.3557801-1-mjguzik@gmail.com> References: <20260329172002.3557801-1-mjguzik@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The bump is gated by I_FREEING | I_WILL_FREE, but these flags can only legally show up if the count is 0. Consequently if the value is at least 1 and it succesfully CAS'ed to something higher, the flags must not be there. I verified all places which look at the refcount either only care about it staying 0 (and have the lock enforce it) or don't hold the inode lock to begin with. Thus the patch retains the invariant for correct consumers and does not make things worse for the rest. Signed-off-by: Mateusz Guzik --- fs/inode.c | 5 +++++ include/linux/fs.h | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/fs/inode.c b/fs/inode.c index a417abc64822..c7585924d5c8 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -1582,6 +1582,11 @@ EXPORT_SYMBOL(ihold); =20 struct inode *igrab(struct inode *inode) { + if (atomic_add_unless(&inode->i_count, 1, 0)) { + VFS_BUG_ON_INODE(inode_state_read_once(inode) & (I_FREEING | I_WILL_FREE= ), inode); + return inode; + } + spin_lock(&inode->i_lock); if (!(inode_state_read(inode) & (I_FREEING | I_WILL_FREE))) { __iget(inode); diff --git a/include/linux/fs.h b/include/linux/fs.h index 07363fce4406..119e0a3d2f42 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2234,8 +2234,8 @@ static inline int icount_read_once(const struct inode= *inode) } =20 /* - * returns the refcount on the inode. The lock guarantees no new references - * are added, but references can be dropped as long as the result is > 0. + * returns the refcount on the inode. The lock guarantees no 0->1 or 1->0 = transitions + * of the count are going to take place, otherwise it changes arbitrarily. */ static inline int icount_read(const struct inode *inode) { --=20 2.48.1