mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v5] ntfs: mount hibernated volumes read-only regardless of errors=
@ 2026-09-20  2:59 Hongling Zeng
  2026-09-20 11:25 ` liubaolin
  0 siblings, 1 reply; 6+ messages in thread
From: Hongling Zeng @ 2026-09-20  2:59 UTC (permalink / raw)
  To: linkinjeon, hyc.lee
  Cc: ntfs, linux-kernel, zhongling0719, Hongling Zeng, stable

The hibernation check in load_system_files() only converts the
superblock to read-only under errors=remount-ro.  With the default
errors=continue (and with errors=panic), a hibernated volume is
mounted read-write and the mount-time $LogFile emptying writes to it,
although a hibernated volume must not be written to at all.

Drop the on_errors term so that a hibernated volume, or a volume whose
hibernation state cannot be determined, always mounts read-only.
NVolErrors() is still recorded, so ntfs_reconfigure() keeps refusing
remounts to read-write, and the $LogFile emptying is skipped by its
!sb_rdonly() check.

The check itself must not apply the errors= policy either: it runs
before SB_RDONLY is set, and ntfs_lookup_inode_by_name() and
ntfs_iget() call ntfs_error() internally on corruption or I/O errors,
which under errors=panic would panic the machine before the read-only
fallback has made its decision.  Run the check with the super block
temporarily marked read-only, which makes ntfs_handle_error() ignore
any ntfs_error() issued on this path; the super block is not
published yet at this point, so the temporary flag is not visible
elsewhere.

Restore read-write access only if the check succeeded and no errors
were recorded earlier during the mount, e.g. when loading the LogFile,
so that a volume with recorded errors stays read-only, matching what
ntfs_reconfigure() enforces for remounts, and a message is logged for
that case.

Fixes: 6251f0b0de7d ("ntfs: update super block operations")
Cc: stable@vger.kernel.org
Signed-off-by: Hongling Zeng <zenghongling@kylinos.cn>
---
Change in v5:
 -Rework the errors=panic handling per review feedback.
---
 fs/ntfs/super.c | 36 +++++++++++++++++++++++++++++++-----
 1 file changed, 31 insertions(+), 5 deletions(-)

diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index f4a73e45773d..ab91cd1a8515 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -1398,6 +1398,7 @@ static bool load_system_files(struct ntfs_volume *vol)
 	struct ntfs_attr_search_ctx *ctx;
 	struct restart_page_header *rp;
 	int err;
+	bool temporary_ro = false;
 
 	ntfs_debug("Entering.");
 	/* Get mft mirror inode compare the contents of $MFT and $MFTMirr. */
@@ -1572,8 +1573,20 @@ static bool load_system_files(struct ntfs_volume *vol)
 	 * NVolErrors() without setting the dirty volume flag and mount
 	 * read-only.  This will prevent read-write remounting and it will also
 	 * prevent all writes.
+	 *
+	 * The check runs with the super block temporarily marked read-only, so
+	 * that ntfs_error() calls issued internally by ntfs_lookup_inode_by_name()
+	 * and ntfs_iget() cannot trigger errors=panic before the read-only
+	 * fallback has run.  The super block is not published yet, so the flag
+	 * is not visible elsewhere.
 	 */
+	if (!sb_rdonly(sb)) {
+		sb->s_flags |= SB_RDONLY;
+		temporary_ro = true;
+	}
 	err = check_windows_hibernation_status(vol);
+	if (temporary_ro && !err && !NVolErrors(vol))
+		sb->s_flags &= ~SB_RDONLY;
 	if (unlikely(err)) {
 		static const char *es1a = "Failed to determine if Windows is hibernated";
 		static const char *es1b = "Windows is hibernated";
@@ -1581,12 +1594,25 @@ static bool load_system_files(struct ntfs_volume *vol)
 		const char *es1;
 
 		es1 = err < 0 ? es1a : es1b;
-		/* If a read-write mount, convert it to a read-only mount. */
-		if (!sb_rdonly(sb) && vol->on_errors == ON_ERRORS_REMOUNT_RO) {
-			sb->s_flags |= SB_RDONLY;
-			ntfs_error(sb, "%s.  Mounting read-only%s", es1, es2);
-		}
+		/*
+		 * A Windows hibernation image is not a filesystem error, so
+		 * this is a safety interlock rather than something the
+		 * errors= policy may downgrade.  The super block is already
+		 * read-only here: the temporary flag taken for the check
+		 * above is not restored when the check failed.
+		 */
+		ntfs_error(sb, "%s.  Mounting read-only%s", es1, es2);
 		NVolSetErrors(vol);
+	} else if (unlikely(temporary_ro && sb_rdonly(sb))) {
+		static const char *es1 = "Errors were recorded during mount";
+		static const char *es2 = ".  Run chkdsk.";
+
+		/*
+		 * Errors were recorded during the check or earlier, e.g. when
+		 * loading the LogFile.  Stay read-only, like ntfs_reconfigure()
+		 * does for volumes with recorded errors.
+		 */
+		ntfs_error(sb, "%s.  Mounting read-only%s", es1, es2);
 	}
 
 	/* If (still) a read-write mount, empty the logfile. */
-- 
2.25.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-09-22  1:27 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-20  2:59 [PATCH v5] ntfs: mount hibernated volumes read-only regardless of errors= Hongling Zeng
2026-09-20 11:25 ` liubaolin
2026-09-21  7:57   ` Hyunchul Lee
2026-09-21  9:30     ` dd
2026-09-22  0:16       ` liubaolin
2026-09-22  1:26       ` Hyunchul Lee

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®