summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2025-01-17 00:53:37 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2025-05-14 22:40:55 -0400
commit20be746bbc18698a8252f0be4fa7dcfb0ed48f90 (patch)
treed261a00622222ba9af0ccaa9a16f6e4cdb2816c7
parentf8e77914dac472d6a8a2f4e2d3da67f056581630 (diff)
ufs: reject multiple conflicting -o ufstype=... on mount
Have ufs_parse_options() refuse to change an already set flavour, and move the "can't change the flavour" logics on remount there, while we are at it - the only difference is that flavour is already set. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/ufs/super.c25
1 files changed, 14 insertions, 11 deletions
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index 6a3a11c7e8ca..33704b8d769d 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -380,7 +380,7 @@ static const match_table_t tokens = {
{Opt_err, NULL}
};
-static int ufs_parse_options(char *options, unsigned *flavour, unsigned *on_err)
+static int ufs_parse_options(char *options, unsigned *flavour, unsigned *on_err, bool remount)
{
char * p;
@@ -392,6 +392,7 @@ static int ufs_parse_options(char *options, unsigned *flavour, unsigned *on_err)
while ((p = strsep(&options, ",")) != NULL) {
substring_t args[MAX_OPT_ARGS];
int token;
+ unsigned int old = *flavour;
if (!*p)
continue;
@@ -444,6 +445,15 @@ static int ufs_parse_options(char *options, unsigned *flavour, unsigned *on_err)
pr_err("Invalid option: \"%s\" or missing value\n", p);
return 0;
}
+ if (*flavour == old)
+ continue;
+ if (!old)
+ continue;
+ if (remount)
+ pr_err("ufstype can't be changed during remount\n");
+ else
+ pr_err("conflicting ufstype options\n");
+ return 0;
}
return 1;
}
@@ -795,7 +805,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent)
*/
sbi->s_flavour = 0;
sbi->s_on_err = UFS_MOUNT_ONERROR_LOCK;
- if (!ufs_parse_options(data, &sbi->s_flavour, &sbi->s_on_err)) {
+ if (!ufs_parse_options(data, &sbi->s_flavour, &sbi->s_on_err, false)) {
pr_err("wrong mount options\n");
goto failed;
}
@@ -1295,16 +1305,9 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
* Allow the "check" option to be passed as a remount option.
* It is not possible to change ufstype option during remount
*/
- ufstype = 0;
+ ufstype = UFS_SB(sb)->s_flavour;
on_err = UFS_MOUNT_ONERROR_LOCK;
- if (!ufs_parse_options(data, &ufstype, &on_err)) {
- mutex_unlock(&UFS_SB(sb)->s_lock);
- return -EINVAL;
- }
- if (!ufstype)
- ufstype = UFS_SB(sb)->s_flavour;
- else if (ufstype != UFS_SB(sb)->s_flavour) {
- pr_err("ufstype can't be changed during remount\n");
+ if (!ufs_parse_options(data, &ufstype, &on_err, true)) {
mutex_unlock(&UFS_SB(sb)->s_lock);
return -EINVAL;
}