From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=100.103.45.18 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1794048705; b=gj0/T+UK3GTRVJZbtx636YfAw5MPTbg7rK8AIsrzQehOVDP/CnTQ7+fVRLblcIo+qNIf TnLV0/WakHsL3vfB3rUWV5q2oYtmi3tX09/VVNeeoOh1C38lIg7GhKtfqdtNDt196Oh1p ou9aGbMiaCW8SVeqyrdAeMEPCx+XGyHtc2HFWsNCBdBi+eh8F2QwV6qKPCZ7rSyHncZTV qG9cLB484ne8jZCPHbuzZukw7HiLb79GANnl22r94gsJOZHY/ATYTxL+N+cPplesfJiWj pyTPVLAIPj2mglI1WXZcFRTwS+1G2cAPhovDgRoPx+8WtI49AfodrAydV6hqCWuKquw== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1794048705; h=Received:DKIM-Signature:From:To:Cc:Subject:Date:Message-ID:X-Mailer: MIME-Version:Content-Type:Content-Transfer-Encoding; bh=VGLZuKLFAiMkv14M65VPsrGcmNPrUIBU/hMmovx7TFw=; b=iZYBF3GkqRpTojglrqpD8pYbCPdQV3VRAlIkCJhJLN4A7USkGss5WcLMVas1cl16NmEx es2vhLLhKFA+WBGSQfc/y9TkEeYdUhNeZ9asAqus0CusZ2B55QeKmpec2AzYWv8BlRRkX cShABCfkjER/M5woE0mbj3ERXELoaIoGQByLsSTwdD5YglA//ca/Q4GmI1kaAkdBLBILX DkyvWTF+0NonIJs+e2vCwqkb2PRZZXsISqCpAfXRnAOCRLiBbcVcNSRatFMK/wgvoqwGj +wJj0UslVqhiIk9zuSr/5KmKU3nWWkwa6eW4TbgjdCC5uLNpOaacleopYMDZpYyw6cw== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b=Ds9r8l9N; arc=none smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 065FA606D805 for ; Sat, 7 Nov 2026 10:51:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b=Ds9r8l9N Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4EEF11F0089F; Sat, 7 Nov 2026 10:51:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1794048704; bh=VGLZuKLFAiMkv14M65VPsrGcmNPrUIBU/hMmovx7TFw=; h=From:To:Cc:Subject:Date; b=Ds9r8l9NWvBqpN7Dd5cUtQS7+U6mceGUREpMCCzVFsQg5yhZ9cNIiuq17soWkXQ/R XyR8VLSAtqk1UI94qNWprKUViHp7i4jzmekSdZ8RvE5mcvV4Na615pqsdL25GBZJ6n YMeObcNhnfkEh3edmdf1vyW9/eBtQ5hbnBIa3B20FNhvJOXC/GYmpBiVyX+ZMU3U/v 53LA1pDfrtvKE4n4eeqDXbLS1p6AEcJeBYVwR5VMa+DpECy+Mu3nI9xCYGo9ZQVteM m5lhblawUJmyHRo36OtdR8vvokHUk2wToOaR0bQOHCtdAvjQKiBN65Vk1eL0IS/4Xg rsWvJcv7eZANQ== From: Sasha Levin To: zenghongling@kylinos.cn, liubaolin@kylinos.cn, hyc.lee@gmail.com, linkinjeon@kernel.org Cc: stable@vger.kernel.org Subject: FAILED: patch "[PATCH] ntfs: set the volume dirty bit unconditionally on metadata changes" failed to apply to 6.1-stable tree Date: Sat, 7 Nov 2026 05:51:42 -0500 Message-ID: <20261107055142-failed-6.1-55af94ca0ee3@kernel.org> X-Mailer: git-send-email 2.53.0 X-Mailing-List: stable@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The patch below does not apply to the 6.1-stable tree. If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to . To reproduce the conflict and resubmit, you may use the following commands: git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.1.y git checkout FETCH_HEAD git cherry-pick -x 55af94ca0ee3512c08d12ffbbb948229da4e1565 # git commit -s git send-email --to '' --in-reply-to '20261107055142-failed-6.1-55af94ca0ee3@kernel.org' --subject-prefix 'PATCH 6.1.y' 'HEAD^..' Thanks, Sasha ------------------ original commit in Linus's tree ------------------ >From 55af94ca0ee3512c08d12ffbbb948229da4e1565 Mon Sep 17 00:00:00 2001 From: Hongling Zeng Date: Mon, 21 Sep 2026 23:13:19 +0900 Subject: [PATCH] ntfs: set the volume dirty bit unconditionally on metadata changes The callers in file.c and namei.c skip ntfs_set_volume_flags() when the in-memory vol_flags already show VOLUME_IS_DIRTY, but that check runs without any lock: if it observes the bit set and ntfs_sync_fs() clears it under the mrec_lock before the caller's metadata update completes, the set is skipped and the volume can end up clean on disk despite the modification, so chkdsk will not run on the next mount. Drop the caller-side checks and call ntfs_set_volume_flags() unconditionally: ntfs_write_volume_flags() already skips the write under the mrec_lock when the combined value is unchanged. That unconditional call costs one mrec_lock acquisition per metadata operation even in the already-dirty steady state; it cannot be avoided, because deciding to skip the call without the lock is itself what allows a concurrent ntfs_sync_fs() clear to lose the set. The IOCB_NOWAIT path in ntfs_file_write_iter() goes through the same sleeping call: a RWF_NOWAIT write can block in the marking, as it already could before this change whenever the volume appeared clean. Giving that path a non-blocking variant is left as follow-up work. The callers keep the pre-existing behavior of proceeding when the marking fails, so the dirty bit remains best-effort. This closes the variant where the set is skipped outright. A clear for a concurrent, error-free sync can still land between the set and the end of the metadata operation; that mark-at-start lifecycle is pre-existing and is not changed by this patch. Reported-by: Baolin Liu Cc: stable@vger.kernel.org Signed-off-by: Hongling Zeng Reviewed-by: Hyunchul Lee Reviewed-by: Baolin Liu Signed-off-by: Namjae Jeon --- fs/ntfs/file.c | 20 +++++++++++--------- fs/ntfs/namei.c | 24 ++++++++---------------- 2 files changed, 19 insertions(+), 25 deletions(-) diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c index 2b6588a4ee73c..e8b056c3e4ccd 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c @@ -341,8 +341,7 @@ int ntfs_setattr(const struct mnt_idmap *idmap, struct dentry *dentry, goto out; } - if (!(vol->vol_flags & VOLUME_IS_DIRTY)) - ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY); + ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY); if (ia_valid & ATTR_SIZE) { err = ntfs_setattr_size(vi, attr); @@ -636,8 +635,13 @@ static ssize_t ntfs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) goto out_lock; } - if (!(vol->vol_flags & VOLUME_IS_DIRTY)) - ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY); + /* + * The volume must be marked dirty before the modification is made, + * without an unlocked check of the in-memory flag: ntfs_sync_fs() + * can clear the bit concurrently and the modification would then + * land on a volume that is clean on disk. + */ + ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY); pos = iocb->ki_pos; count = ret; @@ -1169,11 +1173,9 @@ static long ntfs_fallocate(struct file *file, int mode, loff_t offset, loff_t le return err; } - if (!(vol->vol_flags & VOLUME_IS_DIRTY)) { - err = ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY); - if (err) - return err; - } + err = ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY); + if (err) + return err; inode_lock(vi); if (NInoCompressed(ni) || NInoEncrypted(ni) || NInoWofCompressed(ni)) { diff --git a/fs/ntfs/namei.c b/fs/ntfs/namei.c index 2cde39da6beec..028efad7d9c0f 100644 --- a/fs/ntfs/namei.c +++ b/fs/ntfs/namei.c @@ -756,8 +756,7 @@ static int ntfs_create(const struct mnt_idmap *idmap, struct inode *dir, return err; } - if (!(vol->vol_flags & VOLUME_IS_DIRTY)) - ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY); + ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY); ni = __ntfs_create(idmap, dir, uname, uname_len, S_IFREG | mode, 0, NULL, 0); kmem_cache_free(ntfs_name_cache, uname); @@ -1031,8 +1030,7 @@ static int ntfs_unlink(struct inode *dir, struct dentry *dentry) return err; } - if (!(vol->vol_flags & VOLUME_IS_DIRTY)) - ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY); + ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY); err = ntfs_delete(ni, NTFS_I(dir), uname, uname_len, true); if (err) @@ -1075,8 +1073,7 @@ static struct dentry *ntfs_mkdir(const struct mnt_idmap *idmap, struct inode *di return ERR_PTR(err); } - if (!(vol->vol_flags & VOLUME_IS_DIRTY)) - ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY); + ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY); ni = __ntfs_create(idmap, dir, uname, uname_len, mode, 0, NULL, 0); kmem_cache_free(ntfs_name_cache, uname); @@ -1117,8 +1114,7 @@ static int ntfs_rmdir(struct inode *dir, struct dentry *dentry) return err; } - if (!(vol->vol_flags & VOLUME_IS_DIRTY)) - ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY); + ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY); err = ntfs_delete(ni, NTFS_I(dir), uname, uname_len, true); if (err) @@ -1304,8 +1300,7 @@ static int ntfs_rename(const struct mnt_idmap *idmap, struct inode *old_dir, new_dir_first = is_subdir(new_dentry->d_parent, old_dentry->d_parent); - if (!(vol->vol_flags & VOLUME_IS_DIRTY)) - ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY); + ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY); mutex_lock_nested(&old_ni->mrec_lock, NTFS_INODE_MUTEX_NORMAL); if (new_ni) @@ -1428,8 +1423,7 @@ static int ntfs_symlink(const struct mnt_idmap *idmap, struct inode *dir, goto out; } - if (!(vol->vol_flags & VOLUME_IS_DIRTY)) - ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY); + ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY); ni = __ntfs_create(idmap, dir, usrc, usrc_len, S_IFLNK | 0777, 0, symname, symlen); @@ -1473,8 +1467,7 @@ static int ntfs_mknod(const struct mnt_idmap *idmap, struct inode *dir, return err; } - if (!(vol->vol_flags & VOLUME_IS_DIRTY)) - ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY); + ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY); switch (mode & S_IFMT) { case S_IFCHR: @@ -1520,8 +1513,7 @@ static int ntfs_link(struct dentry *old_dentry, struct inode *dir, return -ENOMEM; } - if (!(vol->vol_flags & VOLUME_IS_DIRTY)) - ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY); + ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY); ihold(vi); mutex_lock_nested(&ni->mrec_lock, NTFS_INODE_MUTEX_NORMAL); -- 2.53.0