From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 A13CC52940C for ; Tue, 29 Sep 2026 13:52:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790689958; cv=none; b=Pk40HEfbcsbOgwL5a5dvcUKGgIS4jvJW8B9Px0SUQwCWrT9iVTq4URBhvVg2HbWBArYctD6QV/HGmvlzJJXI3kRb5OAGJfAntqaCtTGqcYd35EclNHzmecaQp90hIsUSQqLAlAMcQt23YC0BJludLdsUl7vWc9aYFqGiY5aYy3E= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790689958; c=relaxed/simple; bh=odhkW+JOwDwNWuIunbgYenOKBsMV8ELlBcmSqg2Z8NI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ueiyXlUUIkQg/x4AmlWgdVUctcRk9gfoB+gkoZzP9R6qAlnhpGgDI+2x2wKv6T+96b0+jf3MnpdF2qoaIkvdCB4Y2pm3+3JrfwGHM1W3Z5KE1oIoGAy9GBeRVaFmfYjX4EJfJsAphmXZ0bFr9s+o1Eouis6CpCtOSojOHu77qts= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=bnY/FEmw; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="bnY/FEmw" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B64F41F000FF; Tue, 29 Sep 2026 13:52:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1790689952; bh=ZaIAEaBYwfSGYzQ8T4EsxOUf5kIV2Az2NQglkFb+Nb4=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=bnY/FEmwHoCCtejNWnuSA04wRLZMijgXmbBI6rcGEkrUUKsJOh/11D8wY50yQ6PPr mxOUsoio4aMTXpLIgN3ENbzir9TYhx8n0ZGPZXhsJzdZblhBVzn45P+pjWpXApVAo1 2OqceOVDNvwr3oal6cc/Dk/O7VNho/OsHVjg2NfdIqf09sNi7kb4dh1uN5bSqySl1g rjd2aFqATBjOuY5bJkRDEtc8dCAOocVlVA6Syx4maY/m7Yz9jVbrf6GBRzKPkU/CVd D40SGrqrb4fTgMIZQTUjFKd8M4ylZl1HXDLG7MC6xjJVPkjMhoklP7A5IoIGUhyA31 KGUFJxqaQt4Ug== From: Sasha Levin To: stable@vger.kernel.org Cc: Christian Brauner , Jan Kara , Sasha Levin Subject: [PATCH 7.2.y 1/3] super: convert s_count to refcount_t s_passive Date: Tue, 29 Sep 2026 09:52:28 -0400 Message-ID: <20260929135230.3522081-1-sashal@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <2026092911-clunky-same-c5c5@gregkh> References: <2026092911-clunky-same-c5c5@gregkh> Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Christian Brauner [ Upstream commit 3ec9800c2d33c783dd3b27d4cc3bb22b9385f828 ] The superblock carries two counters: s_active, the active reference count that keeps the filesystem usable, and s_count, the passive reference count that merely keeps the structure itself alive. Turn the passive count into a refcount_t and rename it to s_passive to make the pairing with s_active obvious. Everything is still serialized by sb_lock, so there is no functional change; the conversion buys the usual refcount_t saturation and underflow checking. The following patches start dropping passive references without holding sb_lock and make the device-to-superblock table hold one passive reference per registered entry, which a plain integer cannot support. Link: https://patch.msgid.link/20260616-work-super-bdev_holder_global-v2-2-7df6b864028e@kernel.org Reviewed-by: Jan Kara Signed-off-by: Christian Brauner (Amutable) Stable-dep-of: 2d2a2d7aa987 ("super: make iterate_supers_type() deletion-safe") Signed-off-by: Sasha Levin --- fs/super.c | 18 +++++++++--------- include/linux/fs/super_types.h | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/fs/super.c b/fs/super.c index a257b154f7f7f..dae21bf03e1cd 100644 --- a/fs/super.c +++ b/fs/super.c @@ -103,7 +103,7 @@ static bool super_flags(const struct super_block *sb, unsigned int flags) * creation will succeed and SB_BORN is set by vfs_get_tree() or we're * woken and we'll see SB_DYING. * - * The caller must have acquired a temporary reference on @sb->s_count. + * The caller must have acquired a temporary reference on @sb->s_passive. * * Return: The function returns true if SB_BORN was set and with * s_umount held. The function returns false if SB_DYING was @@ -368,7 +368,7 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags, spin_lock_init(&s->s_inode_wblist_lock); fserror_mount(s); - s->s_count = 1; + refcount_set(&s->s_passive, 1); atomic_set(&s->s_active, 1); mutex_init(&s->s_vfs_rename_mutex); lockdep_set_class(&s->s_vfs_rename_mutex, &type->s_vfs_rename_key); @@ -408,7 +408,7 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags, */ static void __put_super(struct super_block *s) { - if (!--s->s_count) { + if (refcount_dec_and_test(&s->s_passive)) { list_del_init(&s->s_list); WARN_ON(s->s_dentry_lru.node); WARN_ON(s->s_inode_lru.node); @@ -530,7 +530,7 @@ static bool grab_super(struct super_block *sb) { bool locked; - sb->s_count++; + refcount_inc(&sb->s_passive); spin_unlock(&sb_lock); locked = super_lock_excl(sb); if (locked) { @@ -557,7 +557,7 @@ static bool grab_super(struct super_block *sb) * lock held in read mode in case of success. On successful return, * the caller must drop the s_umount lock when done. * - * Note that unlike get_super() et.al. this one does *not* bump ->s_count. + * Note that unlike get_super() et.al. this one does *not* bump ->s_passive. * The reason why it's safe is that we are OK with doing trylock instead * of down_read(). There's a couple of places that are OK with that, but * it's very much not a general-purpose interface. @@ -859,7 +859,7 @@ static void __iterate_supers(void (*f)(struct super_block *, void *), void *arg, sb = next_super(sb, flags)) { if (super_flags(sb, SB_DYING)) continue; - sb->s_count++; + refcount_inc(&sb->s_passive); spin_unlock(&sb_lock); if (flags & SUPER_ITER_UNLOCKED) { @@ -904,7 +904,7 @@ void iterate_supers_type(struct file_system_type *type, if (super_flags(sb, SB_DYING)) continue; - sb->s_count++; + refcount_inc(&sb->s_passive); spin_unlock(&sb_lock); locked = super_lock_shared(sb); @@ -936,7 +936,7 @@ struct super_block *user_get_super(dev_t dev, bool excl) if (sb->s_dev != dev) continue; - sb->s_count++; + refcount_inc(&sb->s_passive); spin_unlock(&sb_lock); locked = super_lock(sb, excl); @@ -1376,7 +1376,7 @@ static struct super_block *bdev_super_lock(struct block_device *bdev, bool excl) /* Make sure sb doesn't go away from under us */ spin_lock(&sb_lock); - sb->s_count++; + refcount_inc(&sb->s_passive); spin_unlock(&sb_lock); mutex_unlock(&bdev->bd_holder_lock); diff --git a/include/linux/fs/super_types.h b/include/linux/fs/super_types.h index ef7941e9dc79a..68747182abf9a 100644 --- a/include/linux/fs/super_types.h +++ b/include/linux/fs/super_types.h @@ -145,7 +145,7 @@ struct super_block { unsigned long s_magic; struct dentry *s_root; struct rw_semaphore s_umount; - int s_count; + refcount_t s_passive; atomic_t s_active; #ifdef CONFIG_SECURITY void *s_security; -- 2.53.0