From nobody Sat Jun 13 20:58:05 2026 Received: from mail-pg1-f175.google.com (mail-pg1-f175.google.com [209.85.215.175]) (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 971CC480959 for ; Tue, 5 May 2026 15:04:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777993481; cv=none; b=pn/N0oN+Qcq6mjmxb7/L8yNf5prHTTrjVsSvm7zqJtSSnBSxGXkFH/1Ro1ppkLFsizNfP2jyiNhYDLia32CKrPp3+GtMGRppLmKMfbxdaRAdFmEvAgMgMvgZnxknKAXFkQOQOx5+2/DWCgrfXdnZd3TMOhnAyssKQoQmdKspnuU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777993481; c=relaxed/simple; bh=35W9MGRBQy3NN7T/b6sGeBJOmJ9U0hR+hzRvsoKeJn8=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=CX+F1iVppeUbycvTyksFJhiQl2e8EJWf/FHfPQODebHE2ZUQo7f/Vdk0uxCOhhypQedLaUHxRf4hBLJfTYhGH7biBf3LXN+/afmBi+gH12/ka1e45O46ingGyorLU3qVhq7Yyp7N+wrRKSWZvRY4xfO3tGrzSkFggfeZKgeeQSc= 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=pGkVzFbr; arc=none smtp.client-ip=209.85.215.175 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="pGkVzFbr" Received: by mail-pg1-f175.google.com with SMTP id 41be03b00d2f7-c8025f1c227so1784173a12.2 for ; Tue, 05 May 2026 08:04:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1777993480; x=1778598280; 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; bh=PviP35FxgDybG9yzmuWK7gpaWbNS4nDJvxK+CcvKG5w=; b=pGkVzFbraBFVYkIsPJDHdQts0DW9Nda+eeDrLqVe7VU/v3X5z3H7LNUS+GUNSR5fOw T67ihWUL6dCqAMV0y5ygrNQuXAr6emjltmnz51WV2nh4qmMIhIUO1REMmouCNySkaMnu MG4tDGQ3Sdvtry+4VvHvp4FTvV75yIauOfWkbT+8pcSXq5vh9sJf0CFBd/TbXOz4P45y 1o8aY/a3HUAJu3sK7mqo5ULy0McMOq4sitYxn37TpRpCXE+UgKW9FmwZjM+uxRLYCt6L g4zOurI+lmEbMG446VWhGUvUOar91K9gAR/L7bIkuAdSoXF7tdE6+FwpWvyZXx7R+a0N bfzg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777993480; x=1778598280; 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; bh=PviP35FxgDybG9yzmuWK7gpaWbNS4nDJvxK+CcvKG5w=; b=f+T2wu5iXJyEGBy+V7v5eSD3ROwtXnK0YTDlDWnjnfecEO1TJKxIt7xhAHMGxVtfFx UplcbS0WlTOiGkrry0Hzs8yGbS9MunwwPl6K07TX42uR19ir0+M0b+IRAGwvChmxOwX9 24hqMqEazpFbQoGgQEq1RjEOh/v/8qsxK3DZQRm2Zgs3YXjfAlU42zBcN831FuFX9R37 34qT9a/OrHJlOPp+mhnIPmE1D4oxCqXNaR3lTwasfRUZJfJ+u8tRiXoWq8Xm+AkCws/8 +Z8jj1pmyeF+3HggjBlvbz7K4CXq4QIbudYtqFpek0sJuD7R80ivnQ5TKljZhNRkRoTD WIbQ== X-Forwarded-Encrypted: i=1; AFNElJ8jhVDJWQhQ8G9+wya+DO3NQJ2Bs1KIgRu9/+dHkzsLBtUYgazz6rSMsh+dZzeIM6IOyLxBQx8ZDCi9MII=@vger.kernel.org X-Gm-Message-State: AOJu0YwRpAcaDvAQ+pNYGJbvh63Pimiu/B3uc4skY1PBvagRVCaFzPqP 6L84g0oylVV1ad+mKh62vJw7VTvL/7f6YPJ+26cw9C2LN/yIrXMwG6cC X-Gm-Gg: AeBDieuEQNyMQvnEuxnNXffjBudT8tmQ+QIMMIWxwKLIpUavdJ94x2Zbpms2V8Ac/rn M4xQQsREzTTHHE3PSA4rmELqR6a8DdFQs331lgOD0xJZqtwl+OIDxr4rxA5S1fvVk4TjKiUwcaz D+LD8FKmnxIEOQnoXL9Q8M2QCfmYoRs6fb3gtreAJeS1y3qxIUcfLGbAnxpBRaozA9aIPvKI56J EZqRV+yOTfbi+sRCXGxW+klb+xTmq/wv3lwMmrt/bn2AFsYkNErZo2u0nDYJrWPQX94I8fgzQIQ XjW68t/JBdJpIBOeUTsHUugPE6JrTTFca7xuFkys/8trpkS/jqCEjrc+gNUvt+qH8H7/0xRiw6O fRyogivu/e5PMmXwpKM8xUIejpctXbsRgUc8Hc7q9/vsuYQg14OZ2OIxiPzj6fFFA4/raj+XwII 33h4YTel5IUkE2Thr/LRQvpr1kQok5 X-Received: by 2002:a17:903:390d:b0:2ba:7181:7059 with SMTP id d9443c01a7336-2ba7181767dmr5221185ad.27.1777993479748; Tue, 05 May 2026 08:04:39 -0700 (PDT) Received: from localhost ([111.228.63.84]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2b9cae3b169sm145217955ad.63.2026.05.05.08.04.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 May 2026 08:04:39 -0700 (PDT) From: Cen Zhang To: shaggy@kernel.org Cc: gregkh@linuxfoundation.org, jfs-discussion@lists.sourceforge.net, linux-kernel@vger.kernel.org, baijiaju1990@gmail.com, Cen Zhang Subject: [PATCH] jfs: serialize remount option snapshots Date: Tue, 5 May 2026 23:04:18 +0800 Message-Id: <20260505150418.1706865-1-zzzccc427@gmail.com> X-Mailer: git-send-email 2.34.1 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" JFS initializes a reconfigure fs_context by copying the current superblock mount-option state before the VFS takes sb->s_umount for the actual reconfigure operation. Another remount can therefore update the JFS option fields in jfs_reconfigure() while jfs_init_options() is copying them. The affected fields are copied as a group so that unspecified remount options inherit the current state. Reading them concurrently with the publisher can create a mixed snapshot that never existed as a complete JFS option state, for example combining a discard flag from one remount with a minblks_trim value from another. Add a small JFS-private mutex and use it only around the remount option snapshot and publication of the scalar option fields. The existing VFS superblock lock continues to serialize the reconfigure operation itself; this mutex covers the earlier context-initialization gap without taking sb->s_umount recursively. Signed-off-by: Cen Zhang --- fs/jfs/jfs_incore.h | 1 + fs/jfs/super.c | 53 +++++++++++++++++++++++++++++---------------- 2 files changed, 35 insertions(+), 19 deletions(-) diff --git a/fs/jfs/jfs_incore.h b/fs/jfs/jfs_incore.h index 5aaafed..b222468 100644 --- a/fs/jfs/jfs_incore.h +++ b/fs/jfs/jfs_incore.h @@ -189,6 +189,7 @@ struct jfs_sb_info { /* Formerly in ipbmap */ struct bmap *bmap; /* incore bmap descriptor */ struct nls_table *nls_tab; /* current codepage */ + struct mutex remount_mutex; /* serializes scalar option copy/update */ struct inode *direct_inode; /* metadata inode */ uint state; /* mount/recovery state */ unsigned long flag; /* mount time flags */ diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 61575f7..2e4177f 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -247,6 +247,13 @@ struct jfs_context { s64 newLVSize; }; =20 +static void jfs_update_remount_flag(struct jfs_sb_info *sbi, int flag) +{ + mutex_lock(&sbi->remount_mutex); + sbi->flag =3D flag; + mutex_unlock(&sbi->remount_mutex); +} + static int jfs_parse_param(struct fs_context *fc, struct fs_parameter *par= am) { struct jfs_context *ctx =3D fc->fs_private; @@ -362,6 +369,7 @@ static int jfs_reconfigure(struct fs_context *fc) { struct jfs_context *ctx =3D fc->fs_private; struct super_block *sb =3D fc->root->d_sb; + struct jfs_sb_info *sbi =3D JFS_SBI(sb); int readonly =3D fc->sb_flags & SB_RDONLY; int rc =3D 0; int flag =3D ctx->flag; @@ -369,15 +377,17 @@ static int jfs_reconfigure(struct fs_context *fc) =20 sync_filesystem(sb); =20 - /* Transfer results of parsing to the sbi */ - JFS_SBI(sb)->flag =3D ctx->flag; - JFS_SBI(sb)->uid =3D ctx->uid; - JFS_SBI(sb)->gid =3D ctx->gid; - JFS_SBI(sb)->umask =3D ctx->umask; - JFS_SBI(sb)->minblks_trim =3D ctx->minblks_trim; + /* Transfer results of parsing to the sbi. */ + mutex_lock(&sbi->remount_mutex); + sbi->flag =3D ctx->flag; + sbi->uid =3D ctx->uid; + sbi->gid =3D ctx->gid; + sbi->umask =3D ctx->umask; + sbi->minblks_trim =3D ctx->minblks_trim; + mutex_unlock(&sbi->remount_mutex); if (ctx->nls_map !=3D (void *) -1) { - unload_nls(JFS_SBI(sb)->nls_tab); - JFS_SBI(sb)->nls_tab =3D ctx->nls_map; + unload_nls(sbi->nls_tab); + sbi->nls_tab =3D ctx->nls_map; } ctx->nls_map =3D NULL; =20 @@ -403,9 +413,9 @@ static int jfs_reconfigure(struct fs_context *fc) * Invalidate any previously read metadata. fsck may have * changed the on-disk data since we mounted r/o */ - truncate_inode_pages(JFS_SBI(sb)->direct_inode->i_mapping, 0); + truncate_inode_pages(sbi->direct_inode->i_mapping, 0); =20 - JFS_SBI(sb)->flag =3D flag; + jfs_update_remount_flag(sbi, flag); ret =3D jfs_mount_rw(sb, 1); =20 /* mark the fs r/w for quota activity */ @@ -419,21 +429,21 @@ static int jfs_reconfigure(struct fs_context *fc) if (rc < 0) return rc; rc =3D jfs_umount_rw(sb); - JFS_SBI(sb)->flag =3D flag; + jfs_update_remount_flag(sbi, flag); return rc; } - if ((JFS_SBI(sb)->flag & JFS_NOINTEGRITY) !=3D (flag & JFS_NOINTEGRITY)) { + if ((sbi->flag & JFS_NOINTEGRITY) !=3D (flag & JFS_NOINTEGRITY)) { if (!sb_rdonly(sb)) { rc =3D jfs_umount_rw(sb); if (rc) return rc; =20 - JFS_SBI(sb)->flag =3D flag; + jfs_update_remount_flag(sbi, flag); ret =3D jfs_mount_rw(sb, 1); return ret; } } - JFS_SBI(sb)->flag =3D flag; + jfs_update_remount_flag(sbi, flag); =20 return 0; } @@ -453,6 +463,8 @@ static int jfs_fill_super(struct super_block *sb, struc= t fs_context *fc) if (!sbi) return -ENOMEM; =20 + mutex_init(&sbi->remount_mutex); + sb->s_fs_info =3D sbi; sb->s_max_links =3D JFS_LINK_MAX; sb->s_time_min =3D 0; @@ -870,14 +882,17 @@ static void jfs_init_options(struct fs_context *fc, s= truct jfs_context *ctx) { if (fc->purpose =3D=3D FS_CONTEXT_FOR_RECONFIGURE) { struct super_block *sb =3D fc->root->d_sb; + struct jfs_sb_info *sbi =3D JFS_SBI(sb); =20 /* Copy over current option values and mount flags */ - ctx->uid =3D JFS_SBI(sb)->uid; - ctx->gid =3D JFS_SBI(sb)->gid; - ctx->umask =3D JFS_SBI(sb)->umask; + mutex_lock(&sbi->remount_mutex); + ctx->uid =3D sbi->uid; + ctx->gid =3D sbi->gid; + ctx->umask =3D sbi->umask; + ctx->minblks_trim =3D sbi->minblks_trim; + ctx->flag =3D sbi->flag; + mutex_unlock(&sbi->remount_mutex); ctx->nls_map =3D (void *)-1; - ctx->minblks_trim =3D JFS_SBI(sb)->minblks_trim; - ctx->flag =3D JFS_SBI(sb)->flag; =20 } else { /*