From: liubaolin <liubaolin12138@163.com>
To: Hongling Zeng <zenghongling@kylinos.cn>,
linkinjeon@kernel.org, hyc.lee@gmail.com
Cc: ntfs@lists.linux.dev, linux-kernel@vger.kernel.org,
zhongling0719@126.com, Baolin Liu <liubaolin@kylinos.cn>,
stable@vger.kernel.org
Subject: Re: [PATCH v13 4/7] ntfs: persist the dirty state after the final put_super() commits
Date: Thu, 17 Sep 2026 05:18:00 +0800 [thread overview]
Message-ID: <e45017e8-cf0c-4a97-8ae9-03b27ebd840d@163.com> (raw)
In-Reply-To: <20260915083252.812126-5-zenghongling@kylinos.cn>
在 2026/9/15 16:32, Hongling Zeng 写道:
> The just-in-case mftmirr/mft commits and the final write_inode_now()
> in ntfs_put_super() can record NVolErrors() after the dirty state has
> been persisted, so errors from those points would leave the volume
> unmounted with a clean on-disk dirty bit - contradicting the "cannot
> unmount clean" guarantee ntfs_sync_volume_dirty_state() is meant to
> provide.
>
> Move the persistence to the end of ntfs_put_super(): keep the gated
> re-commits and the tail commits where they are, run
> ntfs_sync_volume_dirty_state() and the $Volume commit after the last
> write_inode_now(), and release vol->vol_ino only after the sync.
>
> The release order of the special inodes matters for the $Volume
> commit: writing the $Volume record mirrors it through
> ntfs_sync_mft_mirror() (record number 3 is below vol->mftmirr_size),
> which fails with -EIO and leaves the mirror stale once
> vol->mftmirr_ino is gone, so the mirror inode is released only after
> that commit. vol->vol_ino is then put before vol->mft_ino is dropped:
> if the commit failed before it could clear the dirty flag,
> ntfs_evict_big_inode() commits the inode again on its way out, and
> __ntfs_write_inode() resolves the runlist through vol->mft_ino.
>
> Reported-by: Baolin Liu <liubaolin@kylinos.cn>
> Cc: stable@vger.kernel.org
> Signed-off-by: Hongling Zeng <zenghongling@kylinos.cn>
> ---
> fs/ntfs/super.c | 75 ++++++++++++++++++++++++++++++++++---------------
> 1 file changed, 52 insertions(+), 23 deletions(-)
>
> diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
> index 733565953302..3574c224fe28 100644
> --- a/fs/ntfs/super.c
> +++ b/fs/ntfs/super.c
> @@ -1812,26 +1812,13 @@ static void ntfs_put_super(struct super_block *sb)
> ntfs_commit_inode(vol->mft_ino);
>
> /*
> - * If a read-write mount, persist the error state in the volume flags:
> - * mark the volume clean if no volume errors have occurred, and make
> - * sure VOLUME_IS_DIRTY is on disk if any have, so chkdsk runs on the
> - * next mount. Also, re-commit all affected inodes.
> + * If a read-write mount, re-commit all affected inodes once more.
> + * The dirty state itself is persisted at the end of ntfs_put_super(),
> + * after the last commits and the final write_inode_now(): those can
> + * still record errors via __ntfs_write_inode(), and the sync must
> + * evaluate NVolErrors() with the last setter already run.
> */
> if (!sb_rdonly(sb)) {
> - if (ntfs_sync_volume_dirty_state(vol)) {
> - ntfs_warning(sb,
> - "Failed to sync dirty bit in volume information flags. Run chkdsk.");
> - } else if (NVolErrors(vol)) {
> - /*
> - * The dirty bit is on disk now; only warn when the
> - * sync actually succeeded, or this message would
> - * contradict the one above.
> - */
> - ntfs_warning(sb,
> - "Volume has errors. Leaving volume marked dirty. Run chkdsk.");
> - }
> - /* Commits the updated volume flags if they were written. */
> - ntfs_commit_inode(vol->vol_ino);
> if (!NVolErrors(vol)) {
> ntfs_commit_inode(vol->root_ino);
> if (vol->mftmirr_ino)
> @@ -1840,9 +1827,6 @@ static void ntfs_put_super(struct super_block *sb)
> }
> }
>
> - iput(vol->vol_ino);
> - vol->vol_ino = NULL;
> -
> /* NTFS 3.0+ specific clean up. */
> if (vol->major_ver >= 3) {
> if (vol->extend_ino) {
> @@ -1872,8 +1856,6 @@ static void ntfs_put_super(struct super_block *sb)
> /* Re-commit the mft mirror and mft just in case. */
> ntfs_commit_inode(vol->mftmirr_ino);
> ntfs_commit_inode(vol->mft_ino);
> - iput(vol->mftmirr_ino);
> - vol->mftmirr_ino = NULL;
> }
> /*
> * We should have no dirty inodes left, due to
> @@ -1883,6 +1865,53 @@ static void ntfs_put_super(struct super_block *sb)
> ntfs_commit_inode(vol->mft_ino);
> write_inode_now(vol->mft_ino, 1);
>
> + /*
> + * If a read-write mount, persist the error state in the volume flags:
> + * mark the volume clean if no volume errors have occurred, and make
> + * sure VOLUME_IS_DIRTY is on disk if any have, so chkdsk runs on the
> + * next mount.
> + */
> + if (!sb_rdonly(sb)) {
> + if (ntfs_sync_volume_dirty_state(vol)) {
> + ntfs_warning(sb,
> + "Failed to sync dirty bit in volume information flags. Run chkdsk.");
> + } else if (NVolErrors(vol)) {
> + /*
> + * The dirty bit is on disk now; only warn when the
> + * sync actually succeeded, or this message would
> + * contradict the one above.
> + */
> + ntfs_warning(sb,
> + "Volume has errors. Leaving volume marked dirty. Run chkdsk.");
> + }
> + /*
> + * Commits the updated volume flags if they were written.
> + * The mft mirror must still be around for this: the
> + * $Volume record (mft record number 3, below
> + * vol->mftmirr_size) is mirrored by write_mft_record()
> + * through ntfs_sync_mft_mirror(), which fails with -EIO
> + * and leaves the mirror stale once vol->mftmirr_ino is
> + * gone, so the mirror inode is only released after this
> + * commit.
> + */
> + ntfs_commit_inode(vol->vol_ino);
> + }
> +
> + /*
> + * Release $Volume while the mft inode is still available: if the
> + * commit above failed before it could clear the dirty flag,
> + * ntfs_evict_big_inode() commits the inode again on its way out,
> + * and __ntfs_write_inode() needs vol->mft_ino to look up the
> + * runlist of the record to write.
> + */
> + iput(vol->vol_ino);
> + vol->vol_ino = NULL;
> +
> + if (vol->mftmirr_ino) {
> + iput(vol->mftmirr_ino);
> + vol->mftmirr_ino = NULL;
> + }
> +
> iput(vol->mft_ino);
> vol->mft_ino = NULL;
> blkdev_issue_flush(sb->s_bdev);
Looks good to me.
Reviewed-by: Baolin Liu <liubaolin@kylinos.cn>
next prev parent reply other threads:[~2026-09-16 21:18 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-15 8:32 [PATCH v13 0/7] ntfs: fix volume flag races and persist the recorded error state Hongling Zeng
2026-09-15 8:32 ` [PATCH v13 1/7] ntfs: fix volume flag update races Hongling Zeng
2026-09-16 20:23 ` liubaolin
2026-09-15 8:32 ` [PATCH v13 2/7] ntfs: set the volume dirty bit unconditionally on metadata changes Hongling Zeng
2026-09-16 20:23 ` liubaolin
2026-09-15 8:32 ` [PATCH v13 3/7] ntfs: sync the volume dirty bit with the recorded error state Hongling Zeng
2026-09-16 20:23 ` liubaolin
2026-09-16 21:17 ` liubaolin
2026-09-15 8:32 ` [PATCH v13 4/7] ntfs: persist the dirty state after the final put_super() commits Hongling Zeng
2026-09-16 21:18 ` liubaolin [this message]
2026-09-15 8:32 ` [PATCH v13 5/7] ntfs: do not clear the volume dirty bit during sync Hongling Zeng
2026-09-16 21:18 ` liubaolin
2026-09-15 8:32 ` [PATCH v13 6/7] ntfs: check the dirty-state commit on remount and unmount Hongling Zeng
2026-09-16 21:18 ` liubaolin
2026-09-15 8:32 ` [PATCH v13 7/7] ntfs: fail remount on sync errors and keep the dirty bit on SB_FORCE Hongling Zeng
2026-09-16 21:18 ` liubaolin
2026-09-16 0:42 ` [PATCH v13 0/7] ntfs: fix volume flag races and persist the recorded error state Hyunchul Lee
2026-09-16 21:36 ` liubaolin
2026-09-16 23:36 ` Namjae Jeon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=e45017e8-cf0c-4a97-8ae9-03b27ebd840d@163.com \
--to=liubaolin12138@163.com \
--cc=hyc.lee@gmail.com \
--cc=linkinjeon@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=liubaolin@kylinos.cn \
--cc=ntfs@lists.linux.dev \
--cc=stable@vger.kernel.org \
--cc=zenghongling@kylinos.cn \
--cc=zhongling0719@126.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®