* [PATCH 0/2] ext2: convert to the new mount API
@ 2025-02-23 19:57 Eric Sandeen
2025-02-23 19:57 ` [PATCH 1/2] " Eric Sandeen
2025-02-23 19:57 ` [PATCH 2/2] ext2: create ext2_msg_fc for use during parsing Eric Sandeen
0 siblings, 2 replies; 7+ messages in thread
From: Eric Sandeen @ 2025-02-23 19:57 UTC (permalink / raw)
To: jack; +Cc: linux-ext4
First patch allows ext2_msg to take a NULL sb since we don't have
that during option parsing - ext4 does the same.
Second patch lets it take an fc instead; it strikes me as a little
messy and I won't be offended if it's not wanted. :)
Thanks,
-Eric
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/2] ext2: convert to the new mount API
2025-02-23 19:57 [PATCH 0/2] ext2: convert to the new mount API Eric Sandeen
@ 2025-02-23 19:57 ` Eric Sandeen
2025-02-24 16:02 ` Jan Kara
2025-02-23 19:57 ` [PATCH 2/2] ext2: create ext2_msg_fc for use during parsing Eric Sandeen
1 sibling, 1 reply; 7+ messages in thread
From: Eric Sandeen @ 2025-02-23 19:57 UTC (permalink / raw)
To: jack; +Cc: linux-ext4, Eric Sandeen
Convert ext2 to the new mount API.
Note that this makes the sb= option more accepting than it was before;
previosly, sb= was only accepted if it was the first specified option.
Now it can exist anywhere, and if respecified, the last specified value
is used.
Parse-time messages here are sent to ext2_msg with a NULL sb, and
ext2_msg is adjusted to accept that, as ext4 does today as well.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
---
fs/ext2/ext2.h | 1 +
fs/ext2/super.c | 571 ++++++++++++++++++++++++++----------------------
2 files changed, 310 insertions(+), 262 deletions(-)
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index f38bdd46e4f7..4025f875252a 100644
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -368,6 +368,7 @@ struct ext2_inode {
#define EXT2_MOUNT_ERRORS_CONT 0x000010 /* Continue on errors */
#define EXT2_MOUNT_ERRORS_RO 0x000020 /* Remount fs ro on errors */
#define EXT2_MOUNT_ERRORS_PANIC 0x000040 /* Panic on errors */
+#define EXT2_MOUNT_ERRORS_MASK 0x000070
#define EXT2_MOUNT_MINIX_DF 0x000080 /* Mimics the Minix statfs */
#define EXT2_MOUNT_NOBH 0x000100 /* No buffer_heads */
#define EXT2_MOUNT_NO_UID32 0x000200 /* Disable 32-bit UIDs */
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 37f7ce56adce..cb6253656eb2 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -23,7 +23,8 @@
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/blkdev.h>
-#include <linux/parser.h>
+#include <linux/fs_context.h>
+#include <linux/fs_parser.h>
#include <linux/random.h>
#include <linux/buffer_head.h>
#include <linux/exportfs.h>
@@ -40,7 +41,6 @@
#include "acl.h"
static void ext2_write_super(struct super_block *sb);
-static int ext2_remount (struct super_block * sb, int * flags, char * data);
static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf);
static int ext2_sync_fs(struct super_block *sb, int wait);
static int ext2_freeze(struct super_block *sb);
@@ -92,7 +92,10 @@ void ext2_msg(struct super_block *sb, const char *prefix,
vaf.fmt = fmt;
vaf.va = &args;
- printk("%sEXT2-fs (%s): %pV\n", prefix, sb->s_id, &vaf);
+ if (sb)
+ printk("%sEXT2-fs (%s): %pV\n", prefix, sb->s_id, &vaf);
+ else
+ printk("%sEXT2-fs: %pV\n", prefix, &vaf);
va_end(args);
}
@@ -346,7 +349,6 @@ static const struct super_operations ext2_sops = {
.freeze_fs = ext2_freeze,
.unfreeze_fs = ext2_unfreeze,
.statfs = ext2_statfs,
- .remount_fs = ext2_remount,
.show_options = ext2_show_options,
#ifdef CONFIG_QUOTA
.quota_read = ext2_quota_read,
@@ -402,230 +404,217 @@ static const struct export_operations ext2_export_ops = {
.get_parent = ext2_get_parent,
};
-static unsigned long get_sb_block(void **data)
-{
- unsigned long sb_block;
- char *options = (char *) *data;
-
- if (!options || strncmp(options, "sb=", 3) != 0)
- return 1; /* Default location */
- options += 3;
- sb_block = simple_strtoul(options, &options, 0);
- if (*options && *options != ',') {
- printk("EXT2-fs: Invalid sb specification: %s\n",
- (char *) *data);
- return 1;
- }
- if (*options == ',')
- options++;
- *data = (void *) options;
- return sb_block;
-}
-
enum {
- Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid,
- Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic,
- Opt_err_ro, Opt_nouid32, Opt_debug,
- Opt_oldalloc, Opt_orlov, Opt_nobh, Opt_user_xattr, Opt_nouser_xattr,
- Opt_acl, Opt_noacl, Opt_xip, Opt_dax, Opt_ignore, Opt_err, Opt_quota,
- Opt_usrquota, Opt_grpquota, Opt_reservation, Opt_noreservation
+ Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid, Opt_resgid, Opt_resuid,
+ Opt_sb, Opt_errors, Opt_nouid32, Opt_debug, Opt_oldalloc, Opt_orlov,
+ Opt_nobh, Opt_user_xattr, Opt_acl, Opt_xip, Opt_dax, Opt_ignore,
+ Opt_quota, Opt_usrquota, Opt_grpquota, Opt_reservation,
+};
+
+static const struct constant_table ext2_param_errors[] = {
+ {"continue", EXT2_MOUNT_ERRORS_CONT},
+ {"panic", EXT2_MOUNT_ERRORS_PANIC},
+ {"remount-ro", EXT2_MOUNT_ERRORS_RO},
+ {}
+};
+
+const struct fs_parameter_spec ext2_param_spec[] = {
+ fsparam_flag ("bsddf", Opt_bsd_df),
+ fsparam_flag ("minixdf", Opt_minix_df),
+ fsparam_flag ("grpid", Opt_grpid),
+ fsparam_flag ("bsdgroups", Opt_grpid),
+ fsparam_flag ("nogrpid", Opt_nogrpid),
+ fsparam_flag ("sysvgroups", Opt_nogrpid),
+ fsparam_gid ("resgid", Opt_resgid),
+ fsparam_uid ("resuid", Opt_resuid),
+ fsparam_u32 ("sb", Opt_sb),
+ fsparam_enum ("errors", Opt_errors, ext2_param_errors),
+ fsparam_flag ("nouid32", Opt_nouid32),
+ fsparam_flag ("debug", Opt_debug),
+ fsparam_flag ("oldalloc", Opt_oldalloc),
+ fsparam_flag ("orlov", Opt_orlov),
+ fsparam_flag ("nobh", Opt_nobh),
+ fsparam_flag_no ("user_xattr", Opt_user_xattr),
+ fsparam_flag_no ("acl", Opt_acl),
+ fsparam_flag ("xip", Opt_xip),
+ fsparam_flag ("dax", Opt_dax),
+ fsparam_flag ("grpquota", Opt_grpquota),
+ fsparam_flag ("noquota", Opt_ignore),
+ fsparam_flag ("quota", Opt_quota),
+ fsparam_flag ("usrquota", Opt_usrquota),
+ fsparam_flag_no ("reservation", Opt_reservation),
+ {}
};
-static const match_table_t tokens = {
- {Opt_bsd_df, "bsddf"},
- {Opt_minix_df, "minixdf"},
- {Opt_grpid, "grpid"},
- {Opt_grpid, "bsdgroups"},
- {Opt_nogrpid, "nogrpid"},
- {Opt_nogrpid, "sysvgroups"},
- {Opt_resgid, "resgid=%u"},
- {Opt_resuid, "resuid=%u"},
- {Opt_sb, "sb=%u"},
- {Opt_err_cont, "errors=continue"},
- {Opt_err_panic, "errors=panic"},
- {Opt_err_ro, "errors=remount-ro"},
- {Opt_nouid32, "nouid32"},
- {Opt_debug, "debug"},
- {Opt_oldalloc, "oldalloc"},
- {Opt_orlov, "orlov"},
- {Opt_nobh, "nobh"},
- {Opt_user_xattr, "user_xattr"},
- {Opt_nouser_xattr, "nouser_xattr"},
- {Opt_acl, "acl"},
- {Opt_noacl, "noacl"},
- {Opt_xip, "xip"},
- {Opt_dax, "dax"},
- {Opt_grpquota, "grpquota"},
- {Opt_ignore, "noquota"},
- {Opt_quota, "quota"},
- {Opt_usrquota, "usrquota"},
- {Opt_reservation, "reservation"},
- {Opt_noreservation, "noreservation"},
- {Opt_err, NULL}
+#define EXT2_SPEC_s_resuid (1 << 0)
+#define EXT2_SPEC_s_resgid (1 << 1)
+
+struct ext2_fs_context {
+ unsigned long vals_s_flags; /* Bits to set in s_flags */
+ unsigned long mask_s_flags; /* Bits changed in s_flags */
+ unsigned int vals_s_mount_opt;
+ unsigned int mask_s_mount_opt;
+ kuid_t s_resuid;
+ kgid_t s_resgid;
+ unsigned long s_sb_block;
+ unsigned int spec;
+
};
-static int parse_options(char *options, struct super_block *sb,
- struct ext2_mount_options *opts)
+static inline void ctx_set_mount_opt(struct ext2_fs_context *ctx,
+ unsigned long flag)
+{
+ ctx->mask_s_mount_opt |= flag;
+ ctx->vals_s_mount_opt |= flag;
+}
+
+static inline void ctx_clear_mount_opt(struct ext2_fs_context *ctx,
+ unsigned long flag)
+{
+ ctx->mask_s_mount_opt |= flag;
+ ctx->vals_s_mount_opt &= ~flag;
+}
+
+static inline unsigned long
+ctx_test_mount_opt(struct ext2_fs_context *ctx, unsigned long flag)
+{
+ return (ctx->vals_s_mount_opt & flag);
+}
+
+static inline bool
+ctx_parsed_mount_opt(struct ext2_fs_context *ctx, unsigned long flag)
+{
+ return (ctx->mask_s_mount_opt & flag);
+}
+
+static void ext2_free_fc(struct fs_context *fc)
{
- char *p;
- substring_t args[MAX_OPT_ARGS];
- int option;
- kuid_t uid;
- kgid_t gid;
-
- if (!options)
- return 1;
-
- while ((p = strsep (&options, ",")) != NULL) {
- int token;
- if (!*p)
- continue;
-
- token = match_token(p, tokens, args);
- switch (token) {
- case Opt_bsd_df:
- clear_opt (opts->s_mount_opt, MINIX_DF);
- break;
- case Opt_minix_df:
- set_opt (opts->s_mount_opt, MINIX_DF);
- break;
- case Opt_grpid:
- set_opt (opts->s_mount_opt, GRPID);
- break;
- case Opt_nogrpid:
- clear_opt (opts->s_mount_opt, GRPID);
- break;
- case Opt_resuid:
- if (match_int(&args[0], &option))
- return 0;
- uid = make_kuid(current_user_ns(), option);
- if (!uid_valid(uid)) {
- ext2_msg(sb, KERN_ERR, "Invalid uid value %d", option);
- return 0;
-
- }
- opts->s_resuid = uid;
- break;
- case Opt_resgid:
- if (match_int(&args[0], &option))
- return 0;
- gid = make_kgid(current_user_ns(), option);
- if (!gid_valid(gid)) {
- ext2_msg(sb, KERN_ERR, "Invalid gid value %d", option);
- return 0;
- }
- opts->s_resgid = gid;
- break;
- case Opt_sb:
- /* handled by get_sb_block() instead of here */
- /* *sb_block = match_int(&args[0]); */
- break;
- case Opt_err_panic:
- clear_opt (opts->s_mount_opt, ERRORS_CONT);
- clear_opt (opts->s_mount_opt, ERRORS_RO);
- set_opt (opts->s_mount_opt, ERRORS_PANIC);
- break;
- case Opt_err_ro:
- clear_opt (opts->s_mount_opt, ERRORS_CONT);
- clear_opt (opts->s_mount_opt, ERRORS_PANIC);
- set_opt (opts->s_mount_opt, ERRORS_RO);
- break;
- case Opt_err_cont:
- clear_opt (opts->s_mount_opt, ERRORS_RO);
- clear_opt (opts->s_mount_opt, ERRORS_PANIC);
- set_opt (opts->s_mount_opt, ERRORS_CONT);
- break;
- case Opt_nouid32:
- set_opt (opts->s_mount_opt, NO_UID32);
- break;
- case Opt_debug:
- set_opt (opts->s_mount_opt, DEBUG);
- break;
- case Opt_oldalloc:
- set_opt (opts->s_mount_opt, OLDALLOC);
- break;
- case Opt_orlov:
- clear_opt (opts->s_mount_opt, OLDALLOC);
- break;
- case Opt_nobh:
- ext2_msg(sb, KERN_INFO,
- "nobh option not supported");
- break;
+ kfree(fc->fs_private);
+}
+
+static int ext2_parse_param(struct fs_context *fc, struct fs_parameter *param)
+{
+ struct ext2_fs_context *ctx = fc->fs_private;
+ int opt;
+ struct fs_parse_result result;
+
+ opt = fs_parse(fc, ext2_param_spec, param, &result);
+ if (opt < 0)
+ return opt;
+
+ switch (opt) {
+ case Opt_bsd_df:
+ ctx_clear_mount_opt(ctx, EXT2_MOUNT_MINIX_DF);
+ break;
+ case Opt_minix_df:
+ ctx_set_mount_opt(ctx, EXT2_MOUNT_MINIX_DF);
+ break;
+ case Opt_grpid:
+ ctx_set_mount_opt(ctx, EXT2_MOUNT_GRPID);
+ break;
+ case Opt_nogrpid:
+ ctx_clear_mount_opt(ctx, EXT2_MOUNT_GRPID);
+ break;
+ case Opt_resuid:
+ ctx->s_resuid = result.uid;
+ ctx->spec |= EXT2_SPEC_s_resuid;
+ break;
+ case Opt_resgid:
+ ctx->s_resgid = result.gid;
+ ctx->spec |= EXT2_SPEC_s_resgid;
+ break;
+ case Opt_sb:
+ /* Note that this is silently ignored on remount */
+ ctx->s_sb_block = result.uint_32;
+ break;
+ case Opt_errors:
+ ctx_clear_mount_opt(ctx, EXT2_MOUNT_ERRORS_MASK);
+ ctx_set_mount_opt(ctx, result.uint_32);
+ break;
+ case Opt_nouid32:
+ ctx_set_mount_opt(ctx, EXT2_MOUNT_NO_UID32);
+ break;
+ case Opt_debug:
+ ctx_set_mount_opt(ctx, EXT2_MOUNT_DEBUG);
+ break;
+ case Opt_oldalloc:
+ ctx_set_mount_opt(ctx, EXT2_MOUNT_OLDALLOC);
+ break;
+ case Opt_orlov:
+ ctx_clear_mount_opt(ctx, EXT2_MOUNT_OLDALLOC);
+ break;
+ case Opt_nobh:
+ ext2_msg(NULL, KERN_INFO, "nobh option not supported\n");
+ break;
#ifdef CONFIG_EXT2_FS_XATTR
- case Opt_user_xattr:
- set_opt (opts->s_mount_opt, XATTR_USER);
- break;
- case Opt_nouser_xattr:
- clear_opt (opts->s_mount_opt, XATTR_USER);
- break;
+ case Opt_user_xattr:
+ if (!result.negated)
+ ctx_set_mount_opt(ctx, EXT2_MOUNT_XATTR_USER);
+ else
+ ctx_clear_mount_opt(ctx, EXT2_MOUNT_XATTR_USER);
+ break;
#else
- case Opt_user_xattr:
- case Opt_nouser_xattr:
- ext2_msg(sb, KERN_INFO, "(no)user_xattr options"
- "not supported");
- break;
+ case Opt_user_xattr:
+ ext2_msg(NULL, KERN_INFO, "(no)user_xattr options not supported");
+ break;
#endif
#ifdef CONFIG_EXT2_FS_POSIX_ACL
- case Opt_acl:
- set_opt(opts->s_mount_opt, POSIX_ACL);
- break;
- case Opt_noacl:
- clear_opt(opts->s_mount_opt, POSIX_ACL);
- break;
+ case Opt_acl:
+ if (!result.negated)
+ ctx_set_mount_opt(ctx, EXT2_MOUNT_POSIX_ACL);
+ else
+ ctx_clear_mount_opt(ctx, EXT2_MOUNT_POSIX_ACL);
+ break;
#else
- case Opt_acl:
- case Opt_noacl:
- ext2_msg(sb, KERN_INFO,
- "(no)acl options not supported");
- break;
+ case Opt_acl:
+ ext2_msg(NULL, KERN_INFO, "(no)acl options not supported");
+ break;
#endif
- case Opt_xip:
- ext2_msg(sb, KERN_INFO, "use dax instead of xip");
- set_opt(opts->s_mount_opt, XIP);
- fallthrough;
- case Opt_dax:
+ case Opt_xip:
+ ext2_msg(NULL, KERN_INFO, "use dax instead of xip");
+ ctx_set_mount_opt(ctx, EXT2_MOUNT_XIP);
+ fallthrough;
+ case Opt_dax:
#ifdef CONFIG_FS_DAX
- ext2_msg(sb, KERN_WARNING,
- "DAX enabled. Warning: EXPERIMENTAL, use at your own risk");
- set_opt(opts->s_mount_opt, DAX);
+ ext2_msg(NULL, KERN_WARNING,
+ "DAX enabled. Warning: EXPERIMENTAL, use at your own risk");
+ ctx_set_mount_opt(ctx, EXT2_MOUNT_DAX);
#else
- ext2_msg(sb, KERN_INFO, "dax option not supported");
+ ext2_msg(NULL, KERN_INFO, "dax option not supported");
#endif
- break;
+ break;
#if defined(CONFIG_QUOTA)
- case Opt_quota:
- case Opt_usrquota:
- set_opt(opts->s_mount_opt, USRQUOTA);
- break;
-
- case Opt_grpquota:
- set_opt(opts->s_mount_opt, GRPQUOTA);
- break;
+ case Opt_quota:
+ case Opt_usrquota:
+ ctx_set_mount_opt(ctx, EXT2_MOUNT_USRQUOTA);
+ break;
+
+ case Opt_grpquota:
+ ctx_set_mount_opt(ctx, EXT2_MOUNT_GRPQUOTA);
+ break;
#else
- case Opt_quota:
- case Opt_usrquota:
- case Opt_grpquota:
- ext2_msg(sb, KERN_INFO,
- "quota operations not supported");
- break;
+ case Opt_quota:
+ case Opt_usrquota:
+ case Opt_grpquota:
+ ext2_msg(NULL, KERN_INFO, "quota operations not supported");
+ break;
#endif
-
- case Opt_reservation:
- set_opt(opts->s_mount_opt, RESERVATION);
- ext2_msg(sb, KERN_INFO, "reservations ON");
- break;
- case Opt_noreservation:
- clear_opt(opts->s_mount_opt, RESERVATION);
- ext2_msg(sb, KERN_INFO, "reservations OFF");
- break;
- case Opt_ignore:
- break;
- default:
- return 0;
+ case Opt_reservation:
+ if (!result.negated) {
+ ctx_set_mount_opt(ctx, EXT2_MOUNT_RESERVATION);
+ ext2_msg(NULL, KERN_INFO, "reservations ON");
+ } else {
+ ctx_clear_mount_opt(ctx, EXT2_MOUNT_RESERVATION);
+ ext2_msg(NULL, KERN_INFO, "reservations OFF");
}
+ break;
+ case Opt_ignore:
+ break;
+ default:
+ return -EINVAL;
}
- return 1;
+ return 0;
}
static int ext2_setup_super (struct super_block * sb,
@@ -801,24 +790,83 @@ static unsigned long descriptor_loc(struct super_block *sb,
return ext2_group_first_block_no(sb, bg) + ext2_bg_has_super(sb, bg);
}
-static int ext2_fill_super(struct super_block *sb, void *data, int silent)
+/*
+ * Set all mount options either from defaults on disk, or from parsed
+ * options. Parsed/specified options override on-disk defaults.
+ */
+static void ext2_set_options(struct fs_context *fc, struct ext2_sb_info *sbi)
{
+ struct ext2_fs_context *ctx = fc->fs_private;
+ struct ext2_super_block *es = sbi->s_es;
+ unsigned long def_mount_opts = le32_to_cpu(es->s_default_mount_opts);
+
+ /* Copy parsed mount options to sbi */
+ sbi->s_mount_opt = ctx->vals_s_mount_opt;
+
+ /* Use in-superblock defaults only if not specified during parsing */
+ if (!ctx_parsed_mount_opt(ctx, EXT2_MOUNT_DEBUG) &&
+ def_mount_opts & EXT2_DEFM_DEBUG)
+ set_opt(sbi->s_mount_opt, DEBUG);
+
+ if (!ctx_parsed_mount_opt(ctx, EXT2_MOUNT_GRPID) &&
+ def_mount_opts & EXT2_DEFM_BSDGROUPS)
+ set_opt(sbi->s_mount_opt, GRPID);
+
+ if (!ctx_parsed_mount_opt(ctx, EXT2_MOUNT_NO_UID32) &&
+ def_mount_opts & EXT2_DEFM_UID16)
+ set_opt(sbi->s_mount_opt, NO_UID32);
+
+#ifdef CONFIG_EXT2_FS_XATTR
+ if (!ctx_parsed_mount_opt(ctx, EXT2_MOUNT_XATTR_USER) &&
+ def_mount_opts & EXT2_DEFM_XATTR_USER)
+ set_opt(sbi->s_mount_opt, XATTR_USER);
+#endif
+#ifdef CONFIG_EXT2_FS_POSIX_ACL
+ if (!ctx_parsed_mount_opt(ctx, EXT2_MOUNT_POSIX_ACL) &&
+ def_mount_opts & EXT2_DEFM_ACL)
+ set_opt(sbi->s_mount_opt, POSIX_ACL);
+#endif
+
+ if (!ctx_parsed_mount_opt(ctx, EXT2_MOUNT_ERRORS_MASK)) {
+ if (le16_to_cpu(sbi->s_es->s_errors) == EXT2_ERRORS_PANIC)
+ set_opt(sbi->s_mount_opt, ERRORS_PANIC);
+ else if (le16_to_cpu(sbi->s_es->s_errors) == EXT2_ERRORS_CONTINUE)
+ set_opt(sbi->s_mount_opt, ERRORS_CONT);
+ else
+ set_opt(sbi->s_mount_opt, ERRORS_RO);
+ }
+
+ if (ctx->spec & EXT2_SPEC_s_resuid)
+ sbi->s_resuid = ctx->s_resuid;
+ else
+ sbi->s_resuid = make_kuid(&init_user_ns,
+ le16_to_cpu(es->s_def_resuid));
+
+ if (ctx->spec & EXT2_SPEC_s_resgid)
+ sbi->s_resgid = ctx->s_resgid;
+ else
+ sbi->s_resgid = make_kgid(&init_user_ns,
+ le16_to_cpu(es->s_def_resgid));
+}
+
+static int ext2_fill_super(struct super_block *sb, struct fs_context *fc)
+{
+ struct ext2_fs_context *ctx = fc->fs_private;
+ int silent = fc->sb_flags & SB_SILENT;
struct buffer_head * bh;
struct ext2_sb_info * sbi;
struct ext2_super_block * es;
struct inode *root;
unsigned long block;
- unsigned long sb_block = get_sb_block(&data);
+ unsigned long sb_block = ctx->s_sb_block;
unsigned long logic_sb_block;
unsigned long offset = 0;
- unsigned long def_mount_opts;
long ret = -ENOMEM;
int blocksize = BLOCK_SIZE;
int db_count;
int i, j;
__le32 features;
int err;
- struct ext2_mount_options opts;
sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
if (!sbi)
@@ -877,42 +925,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
if (sb->s_magic != EXT2_SUPER_MAGIC)
goto cantfind_ext2;
- opts.s_mount_opt = 0;
- /* Set defaults before we parse the mount options */
- def_mount_opts = le32_to_cpu(es->s_default_mount_opts);
- if (def_mount_opts & EXT2_DEFM_DEBUG)
- set_opt(opts.s_mount_opt, DEBUG);
- if (def_mount_opts & EXT2_DEFM_BSDGROUPS)
- set_opt(opts.s_mount_opt, GRPID);
- if (def_mount_opts & EXT2_DEFM_UID16)
- set_opt(opts.s_mount_opt, NO_UID32);
-#ifdef CONFIG_EXT2_FS_XATTR
- if (def_mount_opts & EXT2_DEFM_XATTR_USER)
- set_opt(opts.s_mount_opt, XATTR_USER);
-#endif
-#ifdef CONFIG_EXT2_FS_POSIX_ACL
- if (def_mount_opts & EXT2_DEFM_ACL)
- set_opt(opts.s_mount_opt, POSIX_ACL);
-#endif
-
- if (le16_to_cpu(sbi->s_es->s_errors) == EXT2_ERRORS_PANIC)
- set_opt(opts.s_mount_opt, ERRORS_PANIC);
- else if (le16_to_cpu(sbi->s_es->s_errors) == EXT2_ERRORS_CONTINUE)
- set_opt(opts.s_mount_opt, ERRORS_CONT);
- else
- set_opt(opts.s_mount_opt, ERRORS_RO);
-
- opts.s_resuid = make_kuid(&init_user_ns, le16_to_cpu(es->s_def_resuid));
- opts.s_resgid = make_kgid(&init_user_ns, le16_to_cpu(es->s_def_resgid));
-
- set_opt(opts.s_mount_opt, RESERVATION);
-
- if (!parse_options((char *) data, sb, &opts))
- goto failed_mount;
-
- sbi->s_mount_opt = opts.s_mount_opt;
- sbi->s_resuid = opts.s_resuid;
- sbi->s_resgid = opts.s_resgid;
+ ext2_set_options(fc, sbi);
sb->s_flags = (sb->s_flags & ~SB_POSIXACL) |
(test_opt(sb, POSIX_ACL) ? SB_POSIXACL : 0);
@@ -1324,23 +1337,21 @@ static void ext2_write_super(struct super_block *sb)
ext2_sync_fs(sb, 1);
}
-static int ext2_remount (struct super_block * sb, int * flags, char * data)
+static int ext2_reconfigure(struct fs_context *fc)
{
+ struct ext2_fs_context *ctx = fc->fs_private;
+ struct super_block *sb = fc->root->d_sb;
struct ext2_sb_info * sbi = EXT2_SB(sb);
struct ext2_super_block * es;
struct ext2_mount_options new_opts;
+ int flags = fc->sb_flags;
int err;
sync_filesystem(sb);
- spin_lock(&sbi->s_lock);
- new_opts.s_mount_opt = sbi->s_mount_opt;
- new_opts.s_resuid = sbi->s_resuid;
- new_opts.s_resgid = sbi->s_resgid;
- spin_unlock(&sbi->s_lock);
-
- if (!parse_options(data, sb, &new_opts))
- return -EINVAL;
+ new_opts.s_mount_opt = ctx->vals_s_mount_opt;
+ new_opts.s_resuid = ctx->s_resuid;
+ new_opts.s_resgid = ctx->s_resgid;
spin_lock(&sbi->s_lock);
es = sbi->s_es;
@@ -1349,9 +1360,9 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data)
"dax flag with busy inodes while remounting");
new_opts.s_mount_opt ^= EXT2_MOUNT_DAX;
}
- if ((bool)(*flags & SB_RDONLY) == sb_rdonly(sb))
+ if ((bool)(flags & SB_RDONLY) == sb_rdonly(sb))
goto out_set;
- if (*flags & SB_RDONLY) {
+ if (flags & SB_RDONLY) {
if (le16_to_cpu(es->s_state) & EXT2_VALID_FS ||
!(sbi->s_mount_state & EXT2_VALID_FS))
goto out_set;
@@ -1470,10 +1481,9 @@ static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf)
return 0;
}
-static struct dentry *ext2_mount(struct file_system_type *fs_type,
- int flags, const char *dev_name, void *data)
+static int ext2_get_tree(struct fs_context *fc)
{
- return mount_bdev(fs_type, flags, dev_name, data, ext2_fill_super);
+ return get_tree_bdev(fc, ext2_fill_super);
}
#ifdef CONFIG_QUOTA
@@ -1624,12 +1634,49 @@ static int ext2_quota_off(struct super_block *sb, int type)
#endif
+static const struct fs_context_operations ext2_context_ops = {
+ .parse_param = ext2_parse_param,
+ .get_tree = ext2_get_tree,
+ .reconfigure = ext2_reconfigure,
+ .free = ext2_free_fc,
+};
+
+static int ext2_init_fs_context(struct fs_context *fc)
+{
+ struct ext2_fs_context *ctx;
+
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE) {
+ struct super_block *sb = fc->root->d_sb;
+ struct ext2_sb_info *sbi = EXT2_SB(sb);
+
+ spin_lock(&sbi->s_lock);
+ ctx->vals_s_mount_opt = sbi->s_mount_opt;
+ ctx->vals_s_flags = sb->s_flags;
+ ctx->s_resuid = sbi->s_resuid;
+ ctx->s_resgid = sbi->s_resgid;
+ spin_unlock(&sbi->s_lock);
+ } else {
+ ctx->s_sb_block = 1;
+ ctx_set_mount_opt(ctx, EXT2_MOUNT_RESERVATION);
+ }
+
+ fc->fs_private = ctx;
+ fc->ops = &ext2_context_ops;
+
+ return 0;
+}
+
static struct file_system_type ext2_fs_type = {
.owner = THIS_MODULE,
.name = "ext2",
- .mount = ext2_mount,
.kill_sb = kill_block_super,
.fs_flags = FS_REQUIRES_DEV,
+ .init_fs_context = ext2_init_fs_context,
+ .parameters = ext2_param_spec,
};
MODULE_ALIAS_FS("ext2");
--
2.48.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/2] ext2: create ext2_msg_fc for use during parsing
2025-02-23 19:57 [PATCH 0/2] ext2: convert to the new mount API Eric Sandeen
2025-02-23 19:57 ` [PATCH 1/2] " Eric Sandeen
@ 2025-02-23 19:57 ` Eric Sandeen
2025-02-24 16:01 ` Jan Kara
1 sibling, 1 reply; 7+ messages in thread
From: Eric Sandeen @ 2025-02-23 19:57 UTC (permalink / raw)
To: jack; +Cc: linux-ext4, Eric Sandeen
Rather than send a NULL sb to ext2_msg, which omits the s_id from
messages, create a new ext2_msg_fc which is able to provide this
information from the filesystem context *fc when parsing.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
---
fs/ext2/super.c | 48 +++++++++++++++++++++++++++++++++++-------------
1 file changed, 35 insertions(+), 13 deletions(-)
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index cb6253656eb2..2a4c007972b9 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -81,6 +81,31 @@ void ext2_error(struct super_block *sb, const char *function,
}
}
+static void ext2_msg_fc(struct fs_context *fc, const char *prefix,
+ const char *fmt, ...)
+{
+ struct va_format vaf;
+ va_list args;
+ const char *s_id;
+
+ if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE) {
+ s_id = fc->root->d_sb->s_id;
+ } else {
+ /* get last path component of source */
+ s_id = strrchr(fc->source, '/');
+ if (s_id)
+ s_id++;
+ }
+ va_start(args, fmt);
+
+ vaf.fmt = fmt;
+ vaf.va = &args;
+
+ printk("%sEXT2-fs (%s): %pV\n", prefix, s_id, &vaf);
+
+ va_end(args);
+}
+
void ext2_msg(struct super_block *sb, const char *prefix,
const char *fmt, ...)
{
@@ -92,10 +117,7 @@ void ext2_msg(struct super_block *sb, const char *prefix,
vaf.fmt = fmt;
vaf.va = &args;
- if (sb)
- printk("%sEXT2-fs (%s): %pV\n", prefix, sb->s_id, &vaf);
- else
- printk("%sEXT2-fs: %pV\n", prefix, &vaf);
+ printk("%sEXT2-fs (%s): %pV\n", prefix, sb->s_id, &vaf);
va_end(args);
}
@@ -544,7 +566,7 @@ static int ext2_parse_param(struct fs_context *fc, struct fs_parameter *param)
ctx_clear_mount_opt(ctx, EXT2_MOUNT_OLDALLOC);
break;
case Opt_nobh:
- ext2_msg(NULL, KERN_INFO, "nobh option not supported\n");
+ ext2_msg_fc(fc, KERN_INFO, "nobh option not supported\n");
break;
#ifdef CONFIG_EXT2_FS_XATTR
case Opt_user_xattr:
@@ -555,7 +577,7 @@ static int ext2_parse_param(struct fs_context *fc, struct fs_parameter *param)
break;
#else
case Opt_user_xattr:
- ext2_msg(NULL, KERN_INFO, "(no)user_xattr options not supported");
+ ext2_msg_fc(fc, KERN_INFO, "(no)user_xattr options not supported");
break;
#endif
#ifdef CONFIG_EXT2_FS_POSIX_ACL
@@ -567,20 +589,20 @@ static int ext2_parse_param(struct fs_context *fc, struct fs_parameter *param)
break;
#else
case Opt_acl:
- ext2_msg(NULL, KERN_INFO, "(no)acl options not supported");
+ ext2_msg_fc(fc, KERN_INFO, "(no)acl options not supported");
break;
#endif
case Opt_xip:
- ext2_msg(NULL, KERN_INFO, "use dax instead of xip");
+ ext2_msg_fc(fc, KERN_INFO, "use dax instead of xip");
ctx_set_mount_opt(ctx, EXT2_MOUNT_XIP);
fallthrough;
case Opt_dax:
#ifdef CONFIG_FS_DAX
- ext2_msg(NULL, KERN_WARNING,
+ ext2_msg_fc(fc, KERN_WARNING,
"DAX enabled. Warning: EXPERIMENTAL, use at your own risk");
ctx_set_mount_opt(ctx, EXT2_MOUNT_DAX);
#else
- ext2_msg(NULL, KERN_INFO, "dax option not supported");
+ ext2_msg_fc(fc, KERN_INFO, "dax option not supported");
#endif
break;
@@ -597,16 +619,16 @@ static int ext2_parse_param(struct fs_context *fc, struct fs_parameter *param)
case Opt_quota:
case Opt_usrquota:
case Opt_grpquota:
- ext2_msg(NULL, KERN_INFO, "quota operations not supported");
+ ext2_msg_fc(fc, KERN_INFO, "quota operations not supported");
break;
#endif
case Opt_reservation:
if (!result.negated) {
ctx_set_mount_opt(ctx, EXT2_MOUNT_RESERVATION);
- ext2_msg(NULL, KERN_INFO, "reservations ON");
+ ext2_msg_fc(fc, KERN_INFO, "reservations ON");
} else {
ctx_clear_mount_opt(ctx, EXT2_MOUNT_RESERVATION);
- ext2_msg(NULL, KERN_INFO, "reservations OFF");
+ ext2_msg_fc(fc, KERN_INFO, "reservations OFF");
}
break;
case Opt_ignore:
--
2.48.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] ext2: create ext2_msg_fc for use during parsing
2025-02-23 19:57 ` [PATCH 2/2] ext2: create ext2_msg_fc for use during parsing Eric Sandeen
@ 2025-02-24 16:01 ` Jan Kara
0 siblings, 0 replies; 7+ messages in thread
From: Jan Kara @ 2025-02-24 16:01 UTC (permalink / raw)
To: Eric Sandeen; +Cc: jack, linux-ext4
On Sun 23-02-25 13:57:41, Eric Sandeen wrote:
> Rather than send a NULL sb to ext2_msg, which omits the s_id from
> messages, create a new ext2_msg_fc which is able to provide this
> information from the filesystem context *fc when parsing.
>
> Signed-off-by: Eric Sandeen <sandeen@redhat.com>
...
> +static void ext2_msg_fc(struct fs_context *fc, const char *prefix,
> + const char *fmt, ...)
> +{
> + struct va_format vaf;
> + va_list args;
> + const char *s_id;
> +
> + if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE) {
> + s_id = fc->root->d_sb->s_id;
So the remount handling is definitely valuable...
> + } else {
> + /* get last path component of source */
> + s_id = strrchr(fc->source, '/');
> + if (s_id)
> + s_id++;
> + }
And this isn't too bad but I think it will crash if fc->source has no / in
it? I'll fix that up on commit.
Thanks for the patch!
Honza
> + va_start(args, fmt);
> +
> + vaf.fmt = fmt;
> + vaf.va = &args;
> +
> + printk("%sEXT2-fs (%s): %pV\n", prefix, s_id, &vaf);
> +
> + va_end(args);
> +}
> +
> void ext2_msg(struct super_block *sb, const char *prefix,
> const char *fmt, ...)
> {
> @@ -92,10 +117,7 @@ void ext2_msg(struct super_block *sb, const char *prefix,
> vaf.fmt = fmt;
> vaf.va = &args;
>
> - if (sb)
> - printk("%sEXT2-fs (%s): %pV\n", prefix, sb->s_id, &vaf);
> - else
> - printk("%sEXT2-fs: %pV\n", prefix, &vaf);
> + printk("%sEXT2-fs (%s): %pV\n", prefix, sb->s_id, &vaf);
>
> va_end(args);
> }
> @@ -544,7 +566,7 @@ static int ext2_parse_param(struct fs_context *fc, struct fs_parameter *param)
> ctx_clear_mount_opt(ctx, EXT2_MOUNT_OLDALLOC);
> break;
> case Opt_nobh:
> - ext2_msg(NULL, KERN_INFO, "nobh option not supported\n");
> + ext2_msg_fc(fc, KERN_INFO, "nobh option not supported\n");
> break;
> #ifdef CONFIG_EXT2_FS_XATTR
> case Opt_user_xattr:
> @@ -555,7 +577,7 @@ static int ext2_parse_param(struct fs_context *fc, struct fs_parameter *param)
> break;
> #else
> case Opt_user_xattr:
> - ext2_msg(NULL, KERN_INFO, "(no)user_xattr options not supported");
> + ext2_msg_fc(fc, KERN_INFO, "(no)user_xattr options not supported");
> break;
> #endif
> #ifdef CONFIG_EXT2_FS_POSIX_ACL
> @@ -567,20 +589,20 @@ static int ext2_parse_param(struct fs_context *fc, struct fs_parameter *param)
> break;
> #else
> case Opt_acl:
> - ext2_msg(NULL, KERN_INFO, "(no)acl options not supported");
> + ext2_msg_fc(fc, KERN_INFO, "(no)acl options not supported");
> break;
> #endif
> case Opt_xip:
> - ext2_msg(NULL, KERN_INFO, "use dax instead of xip");
> + ext2_msg_fc(fc, KERN_INFO, "use dax instead of xip");
> ctx_set_mount_opt(ctx, EXT2_MOUNT_XIP);
> fallthrough;
> case Opt_dax:
> #ifdef CONFIG_FS_DAX
> - ext2_msg(NULL, KERN_WARNING,
> + ext2_msg_fc(fc, KERN_WARNING,
> "DAX enabled. Warning: EXPERIMENTAL, use at your own risk");
> ctx_set_mount_opt(ctx, EXT2_MOUNT_DAX);
> #else
> - ext2_msg(NULL, KERN_INFO, "dax option not supported");
> + ext2_msg_fc(fc, KERN_INFO, "dax option not supported");
> #endif
> break;
>
> @@ -597,16 +619,16 @@ static int ext2_parse_param(struct fs_context *fc, struct fs_parameter *param)
> case Opt_quota:
> case Opt_usrquota:
> case Opt_grpquota:
> - ext2_msg(NULL, KERN_INFO, "quota operations not supported");
> + ext2_msg_fc(fc, KERN_INFO, "quota operations not supported");
> break;
> #endif
> case Opt_reservation:
> if (!result.negated) {
> ctx_set_mount_opt(ctx, EXT2_MOUNT_RESERVATION);
> - ext2_msg(NULL, KERN_INFO, "reservations ON");
> + ext2_msg_fc(fc, KERN_INFO, "reservations ON");
> } else {
> ctx_clear_mount_opt(ctx, EXT2_MOUNT_RESERVATION);
> - ext2_msg(NULL, KERN_INFO, "reservations OFF");
> + ext2_msg_fc(fc, KERN_INFO, "reservations OFF");
> }
> break;
> case Opt_ignore:
> --
> 2.48.0
>
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] ext2: convert to the new mount API
2025-02-23 19:57 ` [PATCH 1/2] " Eric Sandeen
@ 2025-02-24 16:02 ` Jan Kara
2025-02-26 16:42 ` Eric Sandeen
0 siblings, 1 reply; 7+ messages in thread
From: Jan Kara @ 2025-02-24 16:02 UTC (permalink / raw)
To: Eric Sandeen; +Cc: jack, linux-ext4
On Sun 23-02-25 13:57:40, Eric Sandeen wrote:
> Convert ext2 to the new mount API.
>
> Note that this makes the sb= option more accepting than it was before;
> previosly, sb= was only accepted if it was the first specified option.
> Now it can exist anywhere, and if respecified, the last specified value
> is used.
>
> Parse-time messages here are sent to ext2_msg with a NULL sb, and
> ext2_msg is adjusted to accept that, as ext4 does today as well.
>
> Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Looks good to me. Thanks!
Honza
> ---
> fs/ext2/ext2.h | 1 +
> fs/ext2/super.c | 571 ++++++++++++++++++++++++++----------------------
> 2 files changed, 310 insertions(+), 262 deletions(-)
>
> diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
> index f38bdd46e4f7..4025f875252a 100644
> --- a/fs/ext2/ext2.h
> +++ b/fs/ext2/ext2.h
> @@ -368,6 +368,7 @@ struct ext2_inode {
> #define EXT2_MOUNT_ERRORS_CONT 0x000010 /* Continue on errors */
> #define EXT2_MOUNT_ERRORS_RO 0x000020 /* Remount fs ro on errors */
> #define EXT2_MOUNT_ERRORS_PANIC 0x000040 /* Panic on errors */
> +#define EXT2_MOUNT_ERRORS_MASK 0x000070
> #define EXT2_MOUNT_MINIX_DF 0x000080 /* Mimics the Minix statfs */
> #define EXT2_MOUNT_NOBH 0x000100 /* No buffer_heads */
> #define EXT2_MOUNT_NO_UID32 0x000200 /* Disable 32-bit UIDs */
> diff --git a/fs/ext2/super.c b/fs/ext2/super.c
> index 37f7ce56adce..cb6253656eb2 100644
> --- a/fs/ext2/super.c
> +++ b/fs/ext2/super.c
> @@ -23,7 +23,8 @@
> #include <linux/slab.h>
> #include <linux/init.h>
> #include <linux/blkdev.h>
> -#include <linux/parser.h>
> +#include <linux/fs_context.h>
> +#include <linux/fs_parser.h>
> #include <linux/random.h>
> #include <linux/buffer_head.h>
> #include <linux/exportfs.h>
> @@ -40,7 +41,6 @@
> #include "acl.h"
>
> static void ext2_write_super(struct super_block *sb);
> -static int ext2_remount (struct super_block * sb, int * flags, char * data);
> static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf);
> static int ext2_sync_fs(struct super_block *sb, int wait);
> static int ext2_freeze(struct super_block *sb);
> @@ -92,7 +92,10 @@ void ext2_msg(struct super_block *sb, const char *prefix,
> vaf.fmt = fmt;
> vaf.va = &args;
>
> - printk("%sEXT2-fs (%s): %pV\n", prefix, sb->s_id, &vaf);
> + if (sb)
> + printk("%sEXT2-fs (%s): %pV\n", prefix, sb->s_id, &vaf);
> + else
> + printk("%sEXT2-fs: %pV\n", prefix, &vaf);
>
> va_end(args);
> }
> @@ -346,7 +349,6 @@ static const struct super_operations ext2_sops = {
> .freeze_fs = ext2_freeze,
> .unfreeze_fs = ext2_unfreeze,
> .statfs = ext2_statfs,
> - .remount_fs = ext2_remount,
> .show_options = ext2_show_options,
> #ifdef CONFIG_QUOTA
> .quota_read = ext2_quota_read,
> @@ -402,230 +404,217 @@ static const struct export_operations ext2_export_ops = {
> .get_parent = ext2_get_parent,
> };
>
> -static unsigned long get_sb_block(void **data)
> -{
> - unsigned long sb_block;
> - char *options = (char *) *data;
> -
> - if (!options || strncmp(options, "sb=", 3) != 0)
> - return 1; /* Default location */
> - options += 3;
> - sb_block = simple_strtoul(options, &options, 0);
> - if (*options && *options != ',') {
> - printk("EXT2-fs: Invalid sb specification: %s\n",
> - (char *) *data);
> - return 1;
> - }
> - if (*options == ',')
> - options++;
> - *data = (void *) options;
> - return sb_block;
> -}
> -
> enum {
> - Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid,
> - Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic,
> - Opt_err_ro, Opt_nouid32, Opt_debug,
> - Opt_oldalloc, Opt_orlov, Opt_nobh, Opt_user_xattr, Opt_nouser_xattr,
> - Opt_acl, Opt_noacl, Opt_xip, Opt_dax, Opt_ignore, Opt_err, Opt_quota,
> - Opt_usrquota, Opt_grpquota, Opt_reservation, Opt_noreservation
> + Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid, Opt_resgid, Opt_resuid,
> + Opt_sb, Opt_errors, Opt_nouid32, Opt_debug, Opt_oldalloc, Opt_orlov,
> + Opt_nobh, Opt_user_xattr, Opt_acl, Opt_xip, Opt_dax, Opt_ignore,
> + Opt_quota, Opt_usrquota, Opt_grpquota, Opt_reservation,
> +};
> +
> +static const struct constant_table ext2_param_errors[] = {
> + {"continue", EXT2_MOUNT_ERRORS_CONT},
> + {"panic", EXT2_MOUNT_ERRORS_PANIC},
> + {"remount-ro", EXT2_MOUNT_ERRORS_RO},
> + {}
> +};
> +
> +const struct fs_parameter_spec ext2_param_spec[] = {
> + fsparam_flag ("bsddf", Opt_bsd_df),
> + fsparam_flag ("minixdf", Opt_minix_df),
> + fsparam_flag ("grpid", Opt_grpid),
> + fsparam_flag ("bsdgroups", Opt_grpid),
> + fsparam_flag ("nogrpid", Opt_nogrpid),
> + fsparam_flag ("sysvgroups", Opt_nogrpid),
> + fsparam_gid ("resgid", Opt_resgid),
> + fsparam_uid ("resuid", Opt_resuid),
> + fsparam_u32 ("sb", Opt_sb),
> + fsparam_enum ("errors", Opt_errors, ext2_param_errors),
> + fsparam_flag ("nouid32", Opt_nouid32),
> + fsparam_flag ("debug", Opt_debug),
> + fsparam_flag ("oldalloc", Opt_oldalloc),
> + fsparam_flag ("orlov", Opt_orlov),
> + fsparam_flag ("nobh", Opt_nobh),
> + fsparam_flag_no ("user_xattr", Opt_user_xattr),
> + fsparam_flag_no ("acl", Opt_acl),
> + fsparam_flag ("xip", Opt_xip),
> + fsparam_flag ("dax", Opt_dax),
> + fsparam_flag ("grpquota", Opt_grpquota),
> + fsparam_flag ("noquota", Opt_ignore),
> + fsparam_flag ("quota", Opt_quota),
> + fsparam_flag ("usrquota", Opt_usrquota),
> + fsparam_flag_no ("reservation", Opt_reservation),
> + {}
> };
>
> -static const match_table_t tokens = {
> - {Opt_bsd_df, "bsddf"},
> - {Opt_minix_df, "minixdf"},
> - {Opt_grpid, "grpid"},
> - {Opt_grpid, "bsdgroups"},
> - {Opt_nogrpid, "nogrpid"},
> - {Opt_nogrpid, "sysvgroups"},
> - {Opt_resgid, "resgid=%u"},
> - {Opt_resuid, "resuid=%u"},
> - {Opt_sb, "sb=%u"},
> - {Opt_err_cont, "errors=continue"},
> - {Opt_err_panic, "errors=panic"},
> - {Opt_err_ro, "errors=remount-ro"},
> - {Opt_nouid32, "nouid32"},
> - {Opt_debug, "debug"},
> - {Opt_oldalloc, "oldalloc"},
> - {Opt_orlov, "orlov"},
> - {Opt_nobh, "nobh"},
> - {Opt_user_xattr, "user_xattr"},
> - {Opt_nouser_xattr, "nouser_xattr"},
> - {Opt_acl, "acl"},
> - {Opt_noacl, "noacl"},
> - {Opt_xip, "xip"},
> - {Opt_dax, "dax"},
> - {Opt_grpquota, "grpquota"},
> - {Opt_ignore, "noquota"},
> - {Opt_quota, "quota"},
> - {Opt_usrquota, "usrquota"},
> - {Opt_reservation, "reservation"},
> - {Opt_noreservation, "noreservation"},
> - {Opt_err, NULL}
> +#define EXT2_SPEC_s_resuid (1 << 0)
> +#define EXT2_SPEC_s_resgid (1 << 1)
> +
> +struct ext2_fs_context {
> + unsigned long vals_s_flags; /* Bits to set in s_flags */
> + unsigned long mask_s_flags; /* Bits changed in s_flags */
> + unsigned int vals_s_mount_opt;
> + unsigned int mask_s_mount_opt;
> + kuid_t s_resuid;
> + kgid_t s_resgid;
> + unsigned long s_sb_block;
> + unsigned int spec;
> +
> };
>
> -static int parse_options(char *options, struct super_block *sb,
> - struct ext2_mount_options *opts)
> +static inline void ctx_set_mount_opt(struct ext2_fs_context *ctx,
> + unsigned long flag)
> +{
> + ctx->mask_s_mount_opt |= flag;
> + ctx->vals_s_mount_opt |= flag;
> +}
> +
> +static inline void ctx_clear_mount_opt(struct ext2_fs_context *ctx,
> + unsigned long flag)
> +{
> + ctx->mask_s_mount_opt |= flag;
> + ctx->vals_s_mount_opt &= ~flag;
> +}
> +
> +static inline unsigned long
> +ctx_test_mount_opt(struct ext2_fs_context *ctx, unsigned long flag)
> +{
> + return (ctx->vals_s_mount_opt & flag);
> +}
> +
> +static inline bool
> +ctx_parsed_mount_opt(struct ext2_fs_context *ctx, unsigned long flag)
> +{
> + return (ctx->mask_s_mount_opt & flag);
> +}
> +
> +static void ext2_free_fc(struct fs_context *fc)
> {
> - char *p;
> - substring_t args[MAX_OPT_ARGS];
> - int option;
> - kuid_t uid;
> - kgid_t gid;
> -
> - if (!options)
> - return 1;
> -
> - while ((p = strsep (&options, ",")) != NULL) {
> - int token;
> - if (!*p)
> - continue;
> -
> - token = match_token(p, tokens, args);
> - switch (token) {
> - case Opt_bsd_df:
> - clear_opt (opts->s_mount_opt, MINIX_DF);
> - break;
> - case Opt_minix_df:
> - set_opt (opts->s_mount_opt, MINIX_DF);
> - break;
> - case Opt_grpid:
> - set_opt (opts->s_mount_opt, GRPID);
> - break;
> - case Opt_nogrpid:
> - clear_opt (opts->s_mount_opt, GRPID);
> - break;
> - case Opt_resuid:
> - if (match_int(&args[0], &option))
> - return 0;
> - uid = make_kuid(current_user_ns(), option);
> - if (!uid_valid(uid)) {
> - ext2_msg(sb, KERN_ERR, "Invalid uid value %d", option);
> - return 0;
> -
> - }
> - opts->s_resuid = uid;
> - break;
> - case Opt_resgid:
> - if (match_int(&args[0], &option))
> - return 0;
> - gid = make_kgid(current_user_ns(), option);
> - if (!gid_valid(gid)) {
> - ext2_msg(sb, KERN_ERR, "Invalid gid value %d", option);
> - return 0;
> - }
> - opts->s_resgid = gid;
> - break;
> - case Opt_sb:
> - /* handled by get_sb_block() instead of here */
> - /* *sb_block = match_int(&args[0]); */
> - break;
> - case Opt_err_panic:
> - clear_opt (opts->s_mount_opt, ERRORS_CONT);
> - clear_opt (opts->s_mount_opt, ERRORS_RO);
> - set_opt (opts->s_mount_opt, ERRORS_PANIC);
> - break;
> - case Opt_err_ro:
> - clear_opt (opts->s_mount_opt, ERRORS_CONT);
> - clear_opt (opts->s_mount_opt, ERRORS_PANIC);
> - set_opt (opts->s_mount_opt, ERRORS_RO);
> - break;
> - case Opt_err_cont:
> - clear_opt (opts->s_mount_opt, ERRORS_RO);
> - clear_opt (opts->s_mount_opt, ERRORS_PANIC);
> - set_opt (opts->s_mount_opt, ERRORS_CONT);
> - break;
> - case Opt_nouid32:
> - set_opt (opts->s_mount_opt, NO_UID32);
> - break;
> - case Opt_debug:
> - set_opt (opts->s_mount_opt, DEBUG);
> - break;
> - case Opt_oldalloc:
> - set_opt (opts->s_mount_opt, OLDALLOC);
> - break;
> - case Opt_orlov:
> - clear_opt (opts->s_mount_opt, OLDALLOC);
> - break;
> - case Opt_nobh:
> - ext2_msg(sb, KERN_INFO,
> - "nobh option not supported");
> - break;
> + kfree(fc->fs_private);
> +}
> +
> +static int ext2_parse_param(struct fs_context *fc, struct fs_parameter *param)
> +{
> + struct ext2_fs_context *ctx = fc->fs_private;
> + int opt;
> + struct fs_parse_result result;
> +
> + opt = fs_parse(fc, ext2_param_spec, param, &result);
> + if (opt < 0)
> + return opt;
> +
> + switch (opt) {
> + case Opt_bsd_df:
> + ctx_clear_mount_opt(ctx, EXT2_MOUNT_MINIX_DF);
> + break;
> + case Opt_minix_df:
> + ctx_set_mount_opt(ctx, EXT2_MOUNT_MINIX_DF);
> + break;
> + case Opt_grpid:
> + ctx_set_mount_opt(ctx, EXT2_MOUNT_GRPID);
> + break;
> + case Opt_nogrpid:
> + ctx_clear_mount_opt(ctx, EXT2_MOUNT_GRPID);
> + break;
> + case Opt_resuid:
> + ctx->s_resuid = result.uid;
> + ctx->spec |= EXT2_SPEC_s_resuid;
> + break;
> + case Opt_resgid:
> + ctx->s_resgid = result.gid;
> + ctx->spec |= EXT2_SPEC_s_resgid;
> + break;
> + case Opt_sb:
> + /* Note that this is silently ignored on remount */
> + ctx->s_sb_block = result.uint_32;
> + break;
> + case Opt_errors:
> + ctx_clear_mount_opt(ctx, EXT2_MOUNT_ERRORS_MASK);
> + ctx_set_mount_opt(ctx, result.uint_32);
> + break;
> + case Opt_nouid32:
> + ctx_set_mount_opt(ctx, EXT2_MOUNT_NO_UID32);
> + break;
> + case Opt_debug:
> + ctx_set_mount_opt(ctx, EXT2_MOUNT_DEBUG);
> + break;
> + case Opt_oldalloc:
> + ctx_set_mount_opt(ctx, EXT2_MOUNT_OLDALLOC);
> + break;
> + case Opt_orlov:
> + ctx_clear_mount_opt(ctx, EXT2_MOUNT_OLDALLOC);
> + break;
> + case Opt_nobh:
> + ext2_msg(NULL, KERN_INFO, "nobh option not supported\n");
> + break;
> #ifdef CONFIG_EXT2_FS_XATTR
> - case Opt_user_xattr:
> - set_opt (opts->s_mount_opt, XATTR_USER);
> - break;
> - case Opt_nouser_xattr:
> - clear_opt (opts->s_mount_opt, XATTR_USER);
> - break;
> + case Opt_user_xattr:
> + if (!result.negated)
> + ctx_set_mount_opt(ctx, EXT2_MOUNT_XATTR_USER);
> + else
> + ctx_clear_mount_opt(ctx, EXT2_MOUNT_XATTR_USER);
> + break;
> #else
> - case Opt_user_xattr:
> - case Opt_nouser_xattr:
> - ext2_msg(sb, KERN_INFO, "(no)user_xattr options"
> - "not supported");
> - break;
> + case Opt_user_xattr:
> + ext2_msg(NULL, KERN_INFO, "(no)user_xattr options not supported");
> + break;
> #endif
> #ifdef CONFIG_EXT2_FS_POSIX_ACL
> - case Opt_acl:
> - set_opt(opts->s_mount_opt, POSIX_ACL);
> - break;
> - case Opt_noacl:
> - clear_opt(opts->s_mount_opt, POSIX_ACL);
> - break;
> + case Opt_acl:
> + if (!result.negated)
> + ctx_set_mount_opt(ctx, EXT2_MOUNT_POSIX_ACL);
> + else
> + ctx_clear_mount_opt(ctx, EXT2_MOUNT_POSIX_ACL);
> + break;
> #else
> - case Opt_acl:
> - case Opt_noacl:
> - ext2_msg(sb, KERN_INFO,
> - "(no)acl options not supported");
> - break;
> + case Opt_acl:
> + ext2_msg(NULL, KERN_INFO, "(no)acl options not supported");
> + break;
> #endif
> - case Opt_xip:
> - ext2_msg(sb, KERN_INFO, "use dax instead of xip");
> - set_opt(opts->s_mount_opt, XIP);
> - fallthrough;
> - case Opt_dax:
> + case Opt_xip:
> + ext2_msg(NULL, KERN_INFO, "use dax instead of xip");
> + ctx_set_mount_opt(ctx, EXT2_MOUNT_XIP);
> + fallthrough;
> + case Opt_dax:
> #ifdef CONFIG_FS_DAX
> - ext2_msg(sb, KERN_WARNING,
> - "DAX enabled. Warning: EXPERIMENTAL, use at your own risk");
> - set_opt(opts->s_mount_opt, DAX);
> + ext2_msg(NULL, KERN_WARNING,
> + "DAX enabled. Warning: EXPERIMENTAL, use at your own risk");
> + ctx_set_mount_opt(ctx, EXT2_MOUNT_DAX);
> #else
> - ext2_msg(sb, KERN_INFO, "dax option not supported");
> + ext2_msg(NULL, KERN_INFO, "dax option not supported");
> #endif
> - break;
> + break;
>
> #if defined(CONFIG_QUOTA)
> - case Opt_quota:
> - case Opt_usrquota:
> - set_opt(opts->s_mount_opt, USRQUOTA);
> - break;
> -
> - case Opt_grpquota:
> - set_opt(opts->s_mount_opt, GRPQUOTA);
> - break;
> + case Opt_quota:
> + case Opt_usrquota:
> + ctx_set_mount_opt(ctx, EXT2_MOUNT_USRQUOTA);
> + break;
> +
> + case Opt_grpquota:
> + ctx_set_mount_opt(ctx, EXT2_MOUNT_GRPQUOTA);
> + break;
> #else
> - case Opt_quota:
> - case Opt_usrquota:
> - case Opt_grpquota:
> - ext2_msg(sb, KERN_INFO,
> - "quota operations not supported");
> - break;
> + case Opt_quota:
> + case Opt_usrquota:
> + case Opt_grpquota:
> + ext2_msg(NULL, KERN_INFO, "quota operations not supported");
> + break;
> #endif
> -
> - case Opt_reservation:
> - set_opt(opts->s_mount_opt, RESERVATION);
> - ext2_msg(sb, KERN_INFO, "reservations ON");
> - break;
> - case Opt_noreservation:
> - clear_opt(opts->s_mount_opt, RESERVATION);
> - ext2_msg(sb, KERN_INFO, "reservations OFF");
> - break;
> - case Opt_ignore:
> - break;
> - default:
> - return 0;
> + case Opt_reservation:
> + if (!result.negated) {
> + ctx_set_mount_opt(ctx, EXT2_MOUNT_RESERVATION);
> + ext2_msg(NULL, KERN_INFO, "reservations ON");
> + } else {
> + ctx_clear_mount_opt(ctx, EXT2_MOUNT_RESERVATION);
> + ext2_msg(NULL, KERN_INFO, "reservations OFF");
> }
> + break;
> + case Opt_ignore:
> + break;
> + default:
> + return -EINVAL;
> }
> - return 1;
> + return 0;
> }
>
> static int ext2_setup_super (struct super_block * sb,
> @@ -801,24 +790,83 @@ static unsigned long descriptor_loc(struct super_block *sb,
> return ext2_group_first_block_no(sb, bg) + ext2_bg_has_super(sb, bg);
> }
>
> -static int ext2_fill_super(struct super_block *sb, void *data, int silent)
> +/*
> + * Set all mount options either from defaults on disk, or from parsed
> + * options. Parsed/specified options override on-disk defaults.
> + */
> +static void ext2_set_options(struct fs_context *fc, struct ext2_sb_info *sbi)
> {
> + struct ext2_fs_context *ctx = fc->fs_private;
> + struct ext2_super_block *es = sbi->s_es;
> + unsigned long def_mount_opts = le32_to_cpu(es->s_default_mount_opts);
> +
> + /* Copy parsed mount options to sbi */
> + sbi->s_mount_opt = ctx->vals_s_mount_opt;
> +
> + /* Use in-superblock defaults only if not specified during parsing */
> + if (!ctx_parsed_mount_opt(ctx, EXT2_MOUNT_DEBUG) &&
> + def_mount_opts & EXT2_DEFM_DEBUG)
> + set_opt(sbi->s_mount_opt, DEBUG);
> +
> + if (!ctx_parsed_mount_opt(ctx, EXT2_MOUNT_GRPID) &&
> + def_mount_opts & EXT2_DEFM_BSDGROUPS)
> + set_opt(sbi->s_mount_opt, GRPID);
> +
> + if (!ctx_parsed_mount_opt(ctx, EXT2_MOUNT_NO_UID32) &&
> + def_mount_opts & EXT2_DEFM_UID16)
> + set_opt(sbi->s_mount_opt, NO_UID32);
> +
> +#ifdef CONFIG_EXT2_FS_XATTR
> + if (!ctx_parsed_mount_opt(ctx, EXT2_MOUNT_XATTR_USER) &&
> + def_mount_opts & EXT2_DEFM_XATTR_USER)
> + set_opt(sbi->s_mount_opt, XATTR_USER);
> +#endif
> +#ifdef CONFIG_EXT2_FS_POSIX_ACL
> + if (!ctx_parsed_mount_opt(ctx, EXT2_MOUNT_POSIX_ACL) &&
> + def_mount_opts & EXT2_DEFM_ACL)
> + set_opt(sbi->s_mount_opt, POSIX_ACL);
> +#endif
> +
> + if (!ctx_parsed_mount_opt(ctx, EXT2_MOUNT_ERRORS_MASK)) {
> + if (le16_to_cpu(sbi->s_es->s_errors) == EXT2_ERRORS_PANIC)
> + set_opt(sbi->s_mount_opt, ERRORS_PANIC);
> + else if (le16_to_cpu(sbi->s_es->s_errors) == EXT2_ERRORS_CONTINUE)
> + set_opt(sbi->s_mount_opt, ERRORS_CONT);
> + else
> + set_opt(sbi->s_mount_opt, ERRORS_RO);
> + }
> +
> + if (ctx->spec & EXT2_SPEC_s_resuid)
> + sbi->s_resuid = ctx->s_resuid;
> + else
> + sbi->s_resuid = make_kuid(&init_user_ns,
> + le16_to_cpu(es->s_def_resuid));
> +
> + if (ctx->spec & EXT2_SPEC_s_resgid)
> + sbi->s_resgid = ctx->s_resgid;
> + else
> + sbi->s_resgid = make_kgid(&init_user_ns,
> + le16_to_cpu(es->s_def_resgid));
> +}
> +
> +static int ext2_fill_super(struct super_block *sb, struct fs_context *fc)
> +{
> + struct ext2_fs_context *ctx = fc->fs_private;
> + int silent = fc->sb_flags & SB_SILENT;
> struct buffer_head * bh;
> struct ext2_sb_info * sbi;
> struct ext2_super_block * es;
> struct inode *root;
> unsigned long block;
> - unsigned long sb_block = get_sb_block(&data);
> + unsigned long sb_block = ctx->s_sb_block;
> unsigned long logic_sb_block;
> unsigned long offset = 0;
> - unsigned long def_mount_opts;
> long ret = -ENOMEM;
> int blocksize = BLOCK_SIZE;
> int db_count;
> int i, j;
> __le32 features;
> int err;
> - struct ext2_mount_options opts;
>
> sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
> if (!sbi)
> @@ -877,42 +925,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
> if (sb->s_magic != EXT2_SUPER_MAGIC)
> goto cantfind_ext2;
>
> - opts.s_mount_opt = 0;
> - /* Set defaults before we parse the mount options */
> - def_mount_opts = le32_to_cpu(es->s_default_mount_opts);
> - if (def_mount_opts & EXT2_DEFM_DEBUG)
> - set_opt(opts.s_mount_opt, DEBUG);
> - if (def_mount_opts & EXT2_DEFM_BSDGROUPS)
> - set_opt(opts.s_mount_opt, GRPID);
> - if (def_mount_opts & EXT2_DEFM_UID16)
> - set_opt(opts.s_mount_opt, NO_UID32);
> -#ifdef CONFIG_EXT2_FS_XATTR
> - if (def_mount_opts & EXT2_DEFM_XATTR_USER)
> - set_opt(opts.s_mount_opt, XATTR_USER);
> -#endif
> -#ifdef CONFIG_EXT2_FS_POSIX_ACL
> - if (def_mount_opts & EXT2_DEFM_ACL)
> - set_opt(opts.s_mount_opt, POSIX_ACL);
> -#endif
> -
> - if (le16_to_cpu(sbi->s_es->s_errors) == EXT2_ERRORS_PANIC)
> - set_opt(opts.s_mount_opt, ERRORS_PANIC);
> - else if (le16_to_cpu(sbi->s_es->s_errors) == EXT2_ERRORS_CONTINUE)
> - set_opt(opts.s_mount_opt, ERRORS_CONT);
> - else
> - set_opt(opts.s_mount_opt, ERRORS_RO);
> -
> - opts.s_resuid = make_kuid(&init_user_ns, le16_to_cpu(es->s_def_resuid));
> - opts.s_resgid = make_kgid(&init_user_ns, le16_to_cpu(es->s_def_resgid));
> -
> - set_opt(opts.s_mount_opt, RESERVATION);
> -
> - if (!parse_options((char *) data, sb, &opts))
> - goto failed_mount;
> -
> - sbi->s_mount_opt = opts.s_mount_opt;
> - sbi->s_resuid = opts.s_resuid;
> - sbi->s_resgid = opts.s_resgid;
> + ext2_set_options(fc, sbi);
>
> sb->s_flags = (sb->s_flags & ~SB_POSIXACL) |
> (test_opt(sb, POSIX_ACL) ? SB_POSIXACL : 0);
> @@ -1324,23 +1337,21 @@ static void ext2_write_super(struct super_block *sb)
> ext2_sync_fs(sb, 1);
> }
>
> -static int ext2_remount (struct super_block * sb, int * flags, char * data)
> +static int ext2_reconfigure(struct fs_context *fc)
> {
> + struct ext2_fs_context *ctx = fc->fs_private;
> + struct super_block *sb = fc->root->d_sb;
> struct ext2_sb_info * sbi = EXT2_SB(sb);
> struct ext2_super_block * es;
> struct ext2_mount_options new_opts;
> + int flags = fc->sb_flags;
> int err;
>
> sync_filesystem(sb);
>
> - spin_lock(&sbi->s_lock);
> - new_opts.s_mount_opt = sbi->s_mount_opt;
> - new_opts.s_resuid = sbi->s_resuid;
> - new_opts.s_resgid = sbi->s_resgid;
> - spin_unlock(&sbi->s_lock);
> -
> - if (!parse_options(data, sb, &new_opts))
> - return -EINVAL;
> + new_opts.s_mount_opt = ctx->vals_s_mount_opt;
> + new_opts.s_resuid = ctx->s_resuid;
> + new_opts.s_resgid = ctx->s_resgid;
>
> spin_lock(&sbi->s_lock);
> es = sbi->s_es;
> @@ -1349,9 +1360,9 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data)
> "dax flag with busy inodes while remounting");
> new_opts.s_mount_opt ^= EXT2_MOUNT_DAX;
> }
> - if ((bool)(*flags & SB_RDONLY) == sb_rdonly(sb))
> + if ((bool)(flags & SB_RDONLY) == sb_rdonly(sb))
> goto out_set;
> - if (*flags & SB_RDONLY) {
> + if (flags & SB_RDONLY) {
> if (le16_to_cpu(es->s_state) & EXT2_VALID_FS ||
> !(sbi->s_mount_state & EXT2_VALID_FS))
> goto out_set;
> @@ -1470,10 +1481,9 @@ static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf)
> return 0;
> }
>
> -static struct dentry *ext2_mount(struct file_system_type *fs_type,
> - int flags, const char *dev_name, void *data)
> +static int ext2_get_tree(struct fs_context *fc)
> {
> - return mount_bdev(fs_type, flags, dev_name, data, ext2_fill_super);
> + return get_tree_bdev(fc, ext2_fill_super);
> }
>
> #ifdef CONFIG_QUOTA
> @@ -1624,12 +1634,49 @@ static int ext2_quota_off(struct super_block *sb, int type)
>
> #endif
>
> +static const struct fs_context_operations ext2_context_ops = {
> + .parse_param = ext2_parse_param,
> + .get_tree = ext2_get_tree,
> + .reconfigure = ext2_reconfigure,
> + .free = ext2_free_fc,
> +};
> +
> +static int ext2_init_fs_context(struct fs_context *fc)
> +{
> + struct ext2_fs_context *ctx;
> +
> + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
> + if (!ctx)
> + return -ENOMEM;
> +
> + if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE) {
> + struct super_block *sb = fc->root->d_sb;
> + struct ext2_sb_info *sbi = EXT2_SB(sb);
> +
> + spin_lock(&sbi->s_lock);
> + ctx->vals_s_mount_opt = sbi->s_mount_opt;
> + ctx->vals_s_flags = sb->s_flags;
> + ctx->s_resuid = sbi->s_resuid;
> + ctx->s_resgid = sbi->s_resgid;
> + spin_unlock(&sbi->s_lock);
> + } else {
> + ctx->s_sb_block = 1;
> + ctx_set_mount_opt(ctx, EXT2_MOUNT_RESERVATION);
> + }
> +
> + fc->fs_private = ctx;
> + fc->ops = &ext2_context_ops;
> +
> + return 0;
> +}
> +
> static struct file_system_type ext2_fs_type = {
> .owner = THIS_MODULE,
> .name = "ext2",
> - .mount = ext2_mount,
> .kill_sb = kill_block_super,
> .fs_flags = FS_REQUIRES_DEV,
> + .init_fs_context = ext2_init_fs_context,
> + .parameters = ext2_param_spec,
> };
> MODULE_ALIAS_FS("ext2");
>
> --
> 2.48.0
>
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] ext2: convert to the new mount API
2025-02-24 16:02 ` Jan Kara
@ 2025-02-26 16:42 ` Eric Sandeen
2025-02-26 17:03 ` Jan Kara
0 siblings, 1 reply; 7+ messages in thread
From: Eric Sandeen @ 2025-02-26 16:42 UTC (permalink / raw)
To: Jan Kara, Eric Sandeen; +Cc: jack, linux-ext4
On 2/24/25 8:02 AM, Jan Kara wrote:
> On Sun 23-02-25 13:57:40, Eric Sandeen wrote:
>> Convert ext2 to the new mount API.
>>
>> Note that this makes the sb= option more accepting than it was before;
>> previosly, sb= was only accepted if it was the first specified option.
>> Now it can exist anywhere, and if respecified, the last specified value
>> is used.
>>
>> Parse-time messages here are sent to ext2_msg with a NULL sb, and
>> ext2_msg is adjusted to accept that, as ext4 does today as well.
>>
>> Signed-off-by: Eric Sandeen <sandeen@redhat.com>
>
> Looks good to me. Thanks!
Thanks Jan - You probably saw the minor nit from the kernel test robot,
"const struct fs_parameter_spec ext2_param_spec" should be static, too.
Sorry about that!
-Eric
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] ext2: convert to the new mount API
2025-02-26 16:42 ` Eric Sandeen
@ 2025-02-26 17:03 ` Jan Kara
0 siblings, 0 replies; 7+ messages in thread
From: Jan Kara @ 2025-02-26 17:03 UTC (permalink / raw)
To: Eric Sandeen; +Cc: Jan Kara, Eric Sandeen, jack, linux-ext4
On Wed 26-02-25 10:42:11, Eric Sandeen wrote:
> On 2/24/25 8:02 AM, Jan Kara wrote:
> > On Sun 23-02-25 13:57:40, Eric Sandeen wrote:
> >> Convert ext2 to the new mount API.
> >>
> >> Note that this makes the sb= option more accepting than it was before;
> >> previosly, sb= was only accepted if it was the first specified option.
> >> Now it can exist anywhere, and if respecified, the last specified value
> >> is used.
> >>
> >> Parse-time messages here are sent to ext2_msg with a NULL sb, and
> >> ext2_msg is adjusted to accept that, as ext4 does today as well.
> >>
> >> Signed-off-by: Eric Sandeen <sandeen@redhat.com>
> >
> > Looks good to me. Thanks!
>
> Thanks Jan - You probably saw the minor nit from the kernel test robot,
> "const struct fs_parameter_spec ext2_param_spec" should be static, too.
Yep, fixed now.
> Sorry about that!
No problem :).
Honza
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2025-02-26 17:03 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-02-23 19:57 [PATCH 0/2] ext2: convert to the new mount API Eric Sandeen
2025-02-23 19:57 ` [PATCH 1/2] " Eric Sandeen
2025-02-24 16:02 ` Jan Kara
2025-02-26 16:42 ` Eric Sandeen
2025-02-26 17:03 ` Jan Kara
2025-02-23 19:57 ` [PATCH 2/2] ext2: create ext2_msg_fc for use during parsing Eric Sandeen
2025-02-24 16:01 ` Jan Kara
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox