From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-vk1-f178.google.com (mail-vk1-f178.google.com [209.85.221.178]) (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 F0F6A3CE0BB for ; Tue, 15 Sep 2026 04:12:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.178 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789445537; cv=none; b=m7uzDCrAmhLdi0Mp9Lfn/SFzUjsYs4SgsQppxCvb/QwiaXpMS2EFDVgBWmQnSyCq9G2Ujquc8glQ4fk63UTG+lJ80SOOmhgD7tVAl22mn4ldBGfgieXtQKIrfis9jccRJQPJmK15a9pfPeRwks1oO5/EoMW1h4EiDhR9pW9n7jw= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789445537; c=relaxed/simple; bh=1gmbEigSLHg0i7bT9mw0MD9g5euC0bVT4jLe4Ta7ZW0=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=LmIMdgf399N9nYVwS75YyLm1czGXQEdCQX497emQJjA9qCAYh1I/V2IMXKyR5pg8veY7ydSlfCtZn6oTtCsJ94iMtF4RQOi83T2he/d2HSXZpcN7bsqxxrpiJpJceZy0hg34K9tEQ5Q/a1+P4RTRT19v5w8KoG08H9TKr0ODp3Q= 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=EWrp3DYb; arc=none smtp.client-ip=209.85.221.178 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="EWrp3DYb" Received: by mail-vk1-f178.google.com with SMTP id 71dfb90a1353d-5c84060045aso1759928e0c.0 for ; Mon, 14 Sep 2026 21:12:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789445535; x=1790050335; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to:content-type; bh=vuT48i8nAD7BsuLmGtFIqeLB1ZSfBya8jF/X5lCprRw=; b=EWrp3DYbyQq/XJvhYRbCgMg1G2Mc88BShQWJHOpIGE5aCc8x0qr22QyvgSKlNx1JyW xScdcIwzIQKIWi9ILujgV4xezSKH+QyjNPyHzd6wnUFQiAc85vtCr9g9zwMqEzMf6kj/ H80QQlopMZX7XtlKzMoG8U6eUhbJBN9sLqcYHXZNxv+ivV5QjAk4N2HdJvSFPTOQpcky n8gjb6bpXIv1UziCchcKoxacvdBMNNOH+Pl8ih8rHAX4TDHx8yRCUq4hlJo0XlWti4KR wCokt4QPd4qXsF5oeYp9ka0naxkrWSMBtqyVXmgwkurIkVkLNevcgb/DIrFwh4TwvlNM 54WA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789445535; x=1790050335; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=vuT48i8nAD7BsuLmGtFIqeLB1ZSfBya8jF/X5lCprRw=; b=muQhI4HR4SBRQj+wBM0DfQTDsqx61v4vC3U6BlNLOj2SR+LqkQglJmVni5P3FI2Z06 bdqUC2e9xVcZgxkDpPj1sxLGLTKrJ4PxsBcD/MU07F77DMGdiuX8/99lSHstgvwo1axH tTty5MJ6ccL2/k8hSTZnH+3H9LQtJN+2yWd5OBcyRJ495Mxpxh9oQeJMl8IitIeuDA8b b46LthSLG/Xvs9IzFWyxvwbZUuq7VFRTOHiHe6Fp6tfGSLh6ABVAtLs3k4FT4LgIZwnH /WBSO5szaOMguTqbTGAv5qpx67HDsi1SeCJctwn8H6x60oGg+1cHsFjCHOpaKoYDCixi 8eQw== X-Forwarded-Encrypted: i=1; AKwUvBzSDjjN/EVdXNS0QrVc9NWtAjXAkWGxQ1ZpSB3+BZAP7UiqRdbWtPFUg2JNBStDMvT/2fT5hEwTpO0I59Q=@vger.kernel.org X-Gm-Message-State: AFuF++lBhkrU5QeD0RUBeH5F/etPtlqd17qbDCbQ6amUiGVom0Ir+x9c HWSGjB9cYz8AbCl2NNpIkiF5dfxgpyTVRHjUEKDd2Isq1K54d/aWFmjs X-Gm-Gg: AYBFou060uQydWYhLwptAHM9DpqKPsln5mz6s5RhyDOZWf/ruOegljfm+8EWxJxA2Fe d+ir0B7/PYoyWwLa2yUVwGmTadX53cDPsBLVFyhr7sIFPyqk7VJ96//K2p+h2DLjFqMs6udku55 hG6KxSFjGeDqTfxoclPu2ZkeAbcvn5ULgL7kf8dGcI9XH/o/fCxgxKhl3ESKtiKZDUPccCZWs+U 5+nMKHfSQNgca/jkZb/kfE7bGGqPMcB+/2HJQP8PoyNv09pvLilfvz70TwotBcXS7zJqDNLXd03 Ln2f4z6EtWoa6Tbr2B6GZoBWclgg83ezvDchGD/9/qBPAbyLsbgNB9XnX2SLRLFDuxbq3XiDkeG vKqP+3yT+n8xCRu2jca0Ah63PEY+NDrJ2XjwMXlme1NZ2Laq7U7f2O/SoWCT/zVVrtsV0xvg4PF yOKGsH2ZDglNOTJI23/aTmtF53vM4/sPmgCYjH4KA6rq0NaHtmV+oqhXjAh12MS9lN X-Received: by 2002:a05:6122:469f:b0:5bf:7f98:9657 with SMTP id 71dfb90a1353d-5c981d4c288mr6299213e0c.6.1789445534889; Mon, 14 Sep 2026 21:12:14 -0700 (PDT) Received: from beelink.. ([187.13.206.89]) by smtp.gmail.com with ESMTPSA id 71dfb90a1353d-5c846e05523sm15329021e0c.0.2026.09.14.21.12.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Sep 2026 21:12:14 -0700 (PDT) From: Aldo Ariel Panzardo To: Ryusuke Konishi Cc: Viacheslav Dubeyko , linux-nilfs@vger.kernel.org, linux-kernel@vger.kernel.org, stable@vger.kernel.org, Aldo Ariel Panzardo Subject: [PATCH] nilfs2: fix checkpoint root lifetime on sysfs errors Date: Tue, 15 Sep 2026 01:12:06 -0300 Message-ID: <20260915041206.2430937-1-qwe.aldo@gmail.com> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit nilfs_find_or_create_root() publishes a new root in the checkpoint tree before creating its sysfs object. If sysfs registration fails, the root is freed while it is still reachable from the tree. Merely erasing it in the error path is insufficient because a concurrent lookup may already hold a reference. Serialize root creation and removal, finish sysfs registration before publishing the root, and wait for the embedded kobject release before freeing its container. The wait also makes normal root removal safe when kobject release is delayed. Fixes: dd70edbde262 ("nilfs2: integrate sysfs support into driver") Cc: stable@vger.kernel.org Signed-off-by: Aldo Ariel Panzardo --- fs/nilfs2/the_nilfs.c | 38 +++++++++++++++++++++++++------------- fs/nilfs2/the_nilfs.h | 3 +++ 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c index 7b23e373a..01389dba2 100644 --- a/fs/nilfs2/the_nilfs.c +++ b/fs/nilfs2/the_nilfs.c @@ -71,6 +71,7 @@ struct the_nilfs *alloc_nilfs(struct super_block *sb) spin_lock_init(&nilfs->ns_last_segment_lock); nilfs->ns_cptree = RB_ROOT; spin_lock_init(&nilfs->ns_cptree_lock); + mutex_init(&nilfs->ns_cptree_mutex); init_rwsem(&nilfs->ns_segctor_sem); nilfs->ns_sb_update_freq = NILFS_SB_FREQ; @@ -881,8 +882,15 @@ nilfs_find_or_create_root(struct the_nilfs *nilfs, __u64 cno) if (!new) return NULL; - spin_lock(&nilfs->ns_cptree_lock); + new->cno = cno; + new->ifile = NULL; + new->nilfs = nilfs; + refcount_set(&new->count, 1); + atomic64_set(&new->inodes_count, 0); + atomic64_set(&new->blocks_count, 0); + mutex_lock(&nilfs->ns_cptree_mutex); + spin_lock(&nilfs->ns_cptree_lock); p = &nilfs->ns_cptree.rb_node; parent = NULL; @@ -897,29 +905,28 @@ nilfs_find_or_create_root(struct the_nilfs *nilfs, __u64 cno) } else { refcount_inc(&root->count); spin_unlock(&nilfs->ns_cptree_lock); + mutex_unlock(&nilfs->ns_cptree_mutex); kfree(new); return root; } } - - new->cno = cno; - new->ifile = NULL; - new->nilfs = nilfs; - refcount_set(&new->count, 1); - atomic64_set(&new->inodes_count, 0); - atomic64_set(&new->blocks_count, 0); - - rb_link_node(&new->rb_node, parent, p); - rb_insert_color(&new->rb_node, &nilfs->ns_cptree); - spin_unlock(&nilfs->ns_cptree_lock); err = nilfs_sysfs_create_snapshot_group(new); if (err) { + mutex_unlock(&nilfs->ns_cptree_mutex); + wait_for_completion(&new->snapshot_kobj_unregister); kfree(new); - new = NULL; + return NULL; } + spin_lock(&nilfs->ns_cptree_lock); + rb_link_node(&new->rb_node, parent, p); + rb_insert_color(&new->rb_node, &nilfs->ns_cptree); + + spin_unlock(&nilfs->ns_cptree_lock); + mutex_unlock(&nilfs->ns_cptree_mutex); + return new; } @@ -927,13 +934,18 @@ void nilfs_put_root(struct nilfs_root *root) { struct the_nilfs *nilfs = root->nilfs; + mutex_lock(&nilfs->ns_cptree_mutex); if (refcount_dec_and_lock(&root->count, &nilfs->ns_cptree_lock)) { rb_erase(&root->rb_node, &nilfs->ns_cptree); spin_unlock(&nilfs->ns_cptree_lock); nilfs_sysfs_delete_snapshot_group(root); + mutex_unlock(&nilfs->ns_cptree_mutex); + wait_for_completion(&root->snapshot_kobj_unregister); iput(root->ifile); kfree(root); + } else { + mutex_unlock(&nilfs->ns_cptree_mutex); } } diff --git a/fs/nilfs2/the_nilfs.h b/fs/nilfs2/the_nilfs.h index 4776a70f0..72affad9e 100644 --- a/fs/nilfs2/the_nilfs.h +++ b/fs/nilfs2/the_nilfs.h @@ -68,6 +68,7 @@ enum { * @ns_sufile: segusage file inode * @ns_cptree: rb-tree of all mounted checkpoints (nilfs_root) * @ns_cptree_lock: lock protecting @ns_cptree + * @ns_cptree_mutex: mutex serializing checkpoint root creation and removal * @ns_dirty_files: list of dirty files * @ns_inode_lock: lock protecting @ns_dirty_files * @ns_gc_inodes: dummy inodes to keep live blocks @@ -151,6 +152,8 @@ struct the_nilfs { /* Checkpoint tree */ struct rb_root ns_cptree; spinlock_t ns_cptree_lock; + /* Serialize root creation and removal. */ + struct mutex ns_cptree_mutex; /* Dirty inode list */ struct list_head ns_dirty_files; -- 2.43.0