From: Ali Ahmet Memis <ali@iusegentoo.com>
To: Alexander Viro <viro@zeniv.linux.org.uk>,
Christian Brauner <brauner@kernel.org>
Cc: Jan Kara <jack@suse.cz>,
linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH 07/10] ufs: revalidate filesystem state before remounting read-write
Date: Sat, 1 Aug 2026 22:55:27 +0000 [thread overview]
Message-ID: <20260801225530.148386-8-ali@iusegentoo.com> (raw)
In-Reply-To: <20260801225530.148386-1-ali@iusegentoo.com>
ufs_fill_super() inspects fs_clean and, for the Solaris flavours, the
state timestamp, and forces SB_RDONLY when the filesystem was not shut
down cleanly. The remount path never repeats that work. Going from
read-only to read-write only checks that the flavour has write support
at all and that the cylinder groups can be read:
if (!ufs_read_cylinder_structures(sb)) {
...
}
sb->s_flags &= ~SB_RDONLY;
So the decision taken at mount time can simply be undone:
mount -t ufs -o ufstype=ufs2,rw bad.img /mnt # forced read-only
mount -o remount,rw /mnt # writable again
touch /mnt/x
A filesystem that is active, bad or in need of fsck becomes writable
after all, which makes the check at mount time close to meaningless.
Move the state test into ufs_state_allows_write() and call it from both
places, returning -EROFS from the remount when it fails. Linux never
writes fs_clean itself outside of the error paths, so the value the
helper sees on remount is still the one that came off the disk.
No change in which filesystems are accepted at mount time.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Ali Ahmet Memis <ali@iusegentoo.com>
---
fs/ufs/super.c | 95 +++++++++++++++++++++++++++++++-------------------
1 file changed, 59 insertions(+), 36 deletions(-)
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index c4831a8b9b3f..4b0e9196fa41 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -713,6 +713,60 @@ static u64 ufs_max_bytes(struct super_block *sb)
return res << uspi->s_bshift;
}
+/*
+ * Does the recorded state of the filesystem allow us to write to it?
+ * Called both when mounting and when remounting read-write.
+ */
+static bool ufs_state_allows_write(struct super_block *sb)
+{
+ struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
+ struct ufs_super_block_first *usb1 = ubh_get_usb_first(uspi);
+ struct ufs_super_block_third *usb3 = ubh_get_usb_third(uspi);
+
+ switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) {
+ case UFS_ST_44BSD:
+ case UFS_ST_OLD:
+ break;
+ case UFS_ST_SUN:
+ case UFS_ST_SUNOS:
+ case UFS_ST_SUNx86:
+ if (ufs_get_fs_state(sb, usb1, usb3) !=
+ UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time)) {
+ pr_err("%s(): fs needs fsck\n", __func__);
+ return false;
+ }
+ break;
+ default:
+ pr_err("%s(): fs needs fsck\n", __func__);
+ return false;
+ }
+
+ switch (usb1->fs_clean) {
+ case UFS_FSCLEAN:
+ UFSD("fs is clean\n");
+ return true;
+ case UFS_FSSTABLE:
+ UFSD("fs is stable\n");
+ return true;
+ case UFS_FSLOG:
+ UFSD("fs is logging fs\n");
+ return true;
+ case UFS_FSOSF1:
+ UFSD("fs is DEC OSF/1\n");
+ return true;
+ case UFS_FSACTIVE:
+ pr_err("%s(): fs is active\n", __func__);
+ return false;
+ case UFS_FSBAD:
+ pr_err("%s(): fs is bad\n", __func__);
+ return false;
+ default:
+ pr_err("%s(): can't grok fs_clean 0x%x\n",
+ __func__, usb1->fs_clean);
+ return false;
+ }
+}
+
static int ufs_fill_super(struct super_block *sb, struct fs_context *fc)
{
struct ufs_fs_context *ctx = fc->fs_private;
@@ -1049,43 +1103,8 @@ static int ufs_fill_super(struct super_block *sb, struct fs_context *fc)
* Check, if file system was correctly unmounted.
* If not, make it read only.
*/
- if (((flags & UFS_ST_MASK) == UFS_ST_44BSD) ||
- ((flags & UFS_ST_MASK) == UFS_ST_OLD) ||
- (((flags & UFS_ST_MASK) == UFS_ST_SUN ||
- (flags & UFS_ST_MASK) == UFS_ST_SUNOS ||
- (flags & UFS_ST_MASK) == UFS_ST_SUNx86) &&
- (ufs_get_fs_state(sb, usb1, usb3) == (UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time))))) {
- switch(usb1->fs_clean) {
- case UFS_FSCLEAN:
- UFSD("fs is clean\n");
- break;
- case UFS_FSSTABLE:
- UFSD("fs is stable\n");
- break;
- case UFS_FSLOG:
- UFSD("fs is logging fs\n");
- break;
- case UFS_FSOSF1:
- UFSD("fs is DEC OSF/1\n");
- break;
- case UFS_FSACTIVE:
- pr_err("%s(): fs is active\n", __func__);
- sb->s_flags |= SB_RDONLY;
- break;
- case UFS_FSBAD:
- pr_err("%s(): fs is bad\n", __func__);
- sb->s_flags |= SB_RDONLY;
- break;
- default:
- pr_err("%s(): can't grok fs_clean 0x%x\n",
- __func__, usb1->fs_clean);
- sb->s_flags |= SB_RDONLY;
- break;
- }
- } else {
- pr_err("%s(): fs needs fsck\n", __func__);
+ if (!ufs_state_allows_write(sb))
sb->s_flags |= SB_RDONLY;
- }
/*
* Read ufs_super_block into internal data structures
@@ -1291,6 +1310,10 @@ static int ufs_reconfigure(struct fs_context *fc)
mutex_unlock(&UFS_SB(sb)->s_lock);
return -EINVAL;
}
+ if (!ufs_state_allows_write(sb)) {
+ mutex_unlock(&UFS_SB(sb)->s_lock);
+ return -EROFS;
+ }
if (!ufs_read_cylinder_structures(sb)) {
pr_err("failed during remounting\n");
mutex_unlock(&UFS_SB(sb)->s_lock);
--
2.55.0
next prev parent reply other threads:[~2026-08-01 22:56 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-01 22:55 [PATCH 00/10] ufs: correctness fixes for valid on-disk filesystems Ali Ahmet Memis
2026-08-01 22:55 ` [PATCH 01/10] ufs: name the modern UFS2 superblock fields Ali Ahmet Memis
2026-08-01 22:55 ` [PATCH 02/10] ufs: use i_size to detect fast symlinks Ali Ahmet Memis
2026-08-01 22:55 ` [PATCH 03/10] ufs: free UFS2 external attribute blocks on inode deletion Ali Ahmet Memis
2026-08-01 22:55 ` [PATCH 04/10] ufs: do not inherit file flags from the parent directory Ali Ahmet Memis
2026-08-01 22:55 ` [PATCH 05/10] ufs: honour on-disk immutable and append-only flags Ali Ahmet Memis
2026-08-01 22:55 ` [PATCH 06/10] ufs: fix fragment relocation offsets within a folio Ali Ahmet Memis
2026-08-01 22:55 ` Ali Ahmet Memis [this message]
2026-08-01 22:55 ` [PATCH 08/10] ufs: refuse read-write mount when fsck or journal replay is needed Ali Ahmet Memis
2026-08-01 22:55 ` [PATCH 09/10] ufs: refuse read-write mount of filesystems with active snapshots Ali Ahmet Memis
2026-08-01 22:55 ` [PATCH 10/10] ufs: refuse read-write mount of check-hashed filesystems Ali Ahmet Memis
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=20260801225530.148386-8-ali@iusegentoo.com \
--to=ali@iusegentoo.com \
--cc=brauner@kernel.org \
--cc=jack@suse.cz \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=viro@zeniv.linux.org.uk \
/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®