Hongbo, Could you please post v5?
Thanks, On 07/07, Hongbo Li wrote: > > > On 2025/7/4 11:27, Chao Yu wrote: > > On 6/2/25 17:02, Hongbo Li wrote: > > > In handle_mount_opt, we use fs_parameter to parse each option. > > > However we're still using the old API to get the options string. > > > Using fsparams parse_options allows us to remove many of the Opt_ > > > enums, so remove them. > > > > > > The checkpoint disable cap (or percent) involves rather complex > > > parsing; we retain the old match_table mechanism for this, which > > > handles it well. > > > > > > There are some changes about parsing options: > > > 1. For `active_logs`, `inline_xattr_size` and `fault_injection`, > > > we use s32 type according the internal structure to record the > > > option's value. > > > > > > Signed-off-by: Hongbo Li <lihongb...@huawei.com> > > > [sandeen: forward port, minor fixes and updates] > > > Signed-off-by: Eric Sandeen <sand...@redhat.com> > > > [hongbo: minor cleanup] > > > Signed-off-by: Hongbo Li <lihongb...@huawei.com> > > > --- > > > fs/f2fs/super.c | 1068 ++++++++++++++++++----------------------------- > > > 1 file changed, 413 insertions(+), 655 deletions(-) > > > > > > diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c > > > index 996633b8379e..dff2419ba905 100644 > > > --- a/fs/f2fs/super.c > > > +++ b/fs/f2fs/super.c > > > @@ -27,6 +27,7 @@ > > > #include <linux/part_stat.h> > > > #include <linux/zstd.h> > > > #include <linux/lz4.h> > > > +#include <linux/ctype.h> > > > #include <linux/fs_parser.h> > > > #include "f2fs.h" > > > @@ -126,29 +127,20 @@ enum { > > > Opt_disable_roll_forward, > > > Opt_norecovery, > > > Opt_discard, > > > - Opt_nodiscard, > > > Opt_noheap, > > > Opt_heap, > > > Opt_user_xattr, > > > - Opt_nouser_xattr, > > > Opt_acl, > > > - Opt_noacl, > > > Opt_active_logs, > > > Opt_disable_ext_identify, > > > Opt_inline_xattr, > > > - Opt_noinline_xattr, > > > Opt_inline_xattr_size, > > > Opt_inline_data, > > > Opt_inline_dentry, > > > - Opt_noinline_dentry, > > > Opt_flush_merge, > > > - Opt_noflush_merge, > > > Opt_barrier, > > > - Opt_nobarrier, > > > Opt_fastboot, > > > Opt_extent_cache, > > > - Opt_noextent_cache, > > > - Opt_noinline_data, > > > Opt_data_flush, > > > Opt_reserve_root, > > > Opt_resgid, > > > @@ -157,21 +149,13 @@ enum { > > > Opt_fault_injection, > > > Opt_fault_type, > > > Opt_lazytime, > > > - Opt_nolazytime, > > > Opt_quota, > > > - Opt_noquota, > > > Opt_usrquota, > > > Opt_grpquota, > > > Opt_prjquota, > > > Opt_usrjquota, > > > Opt_grpjquota, > > > Opt_prjjquota, > > > - Opt_offusrjquota, > > > - Opt_offgrpjquota, > > > - Opt_offprjjquota, > > > - Opt_jqfmt_vfsold, > > > - Opt_jqfmt_vfsv0, > > > - Opt_jqfmt_vfsv1, > > > Opt_alloc, > > > Opt_fsync, > > > Opt_test_dummy_encryption, > > > @@ -181,17 +165,15 @@ enum { > > > Opt_checkpoint_disable_cap_perc, > > > Opt_checkpoint_enable, > > > Opt_checkpoint_merge, > > > - Opt_nocheckpoint_merge, > > > Opt_compress_algorithm, > > > Opt_compress_log_size, > > > - Opt_compress_extension, > > > Opt_nocompress_extension, > > > + Opt_compress_extension, > > > Opt_compress_chksum, > > > Opt_compress_mode, > > > Opt_compress_cache, > > > Opt_atgc, > > > Opt_gc_merge, > > > - Opt_nogc_merge, > > > Opt_discard_unit, > > > Opt_memory_mode, > > > Opt_age_extent_cache, > > > @@ -321,83 +303,12 @@ static const struct fs_parameter_spec > > > f2fs_param_specs[] = { > > > {} > > > }; > > > -static match_table_t f2fs_tokens = { > > > - {Opt_gc_background, "background_gc=%s"}, > > > - {Opt_disable_roll_forward, "disable_roll_forward"}, > > > - {Opt_norecovery, "norecovery"}, > > > - {Opt_discard, "discard"}, > > > - {Opt_nodiscard, "nodiscard"}, > > > - {Opt_noheap, "no_heap"}, > > > - {Opt_heap, "heap"}, > > > - {Opt_user_xattr, "user_xattr"}, > > > - {Opt_nouser_xattr, "nouser_xattr"}, > > > - {Opt_acl, "acl"}, > > > - {Opt_noacl, "noacl"}, > > > - {Opt_active_logs, "active_logs=%u"}, > > > - {Opt_disable_ext_identify, "disable_ext_identify"}, > > > - {Opt_inline_xattr, "inline_xattr"}, > > > - {Opt_noinline_xattr, "noinline_xattr"}, > > > - {Opt_inline_xattr_size, "inline_xattr_size=%u"}, > > > - {Opt_inline_data, "inline_data"}, > > > - {Opt_inline_dentry, "inline_dentry"}, > > > - {Opt_noinline_dentry, "noinline_dentry"}, > > > - {Opt_flush_merge, "flush_merge"}, > > > - {Opt_noflush_merge, "noflush_merge"}, > > > - {Opt_barrier, "barrier"}, > > > - {Opt_nobarrier, "nobarrier"}, > > > - {Opt_fastboot, "fastboot"}, > > > - {Opt_extent_cache, "extent_cache"}, > > > - {Opt_noextent_cache, "noextent_cache"}, > > > - {Opt_noinline_data, "noinline_data"}, > > > - {Opt_data_flush, "data_flush"}, > > > - {Opt_reserve_root, "reserve_root=%u"}, > > > - {Opt_resgid, "resgid=%u"}, > > > - {Opt_resuid, "resuid=%u"}, > > > - {Opt_mode, "mode=%s"}, > > > - {Opt_fault_injection, "fault_injection=%u"}, > > > - {Opt_fault_type, "fault_type=%u"}, > > > - {Opt_lazytime, "lazytime"}, > > > - {Opt_nolazytime, "nolazytime"}, > > > - {Opt_quota, "quota"}, > > > - {Opt_noquota, "noquota"}, > > > - {Opt_usrquota, "usrquota"}, > > > - {Opt_grpquota, "grpquota"}, > > > - {Opt_prjquota, "prjquota"}, > > > - {Opt_usrjquota, "usrjquota=%s"}, > > > - {Opt_grpjquota, "grpjquota=%s"}, > > > - {Opt_prjjquota, "prjjquota=%s"}, > > > - {Opt_offusrjquota, "usrjquota="}, > > > - {Opt_offgrpjquota, "grpjquota="}, > > > - {Opt_offprjjquota, "prjjquota="}, > > > - {Opt_jqfmt_vfsold, "jqfmt=vfsold"}, > > > - {Opt_jqfmt_vfsv0, "jqfmt=vfsv0"}, > > > - {Opt_jqfmt_vfsv1, "jqfmt=vfsv1"}, > > > - {Opt_alloc, "alloc_mode=%s"}, > > > - {Opt_fsync, "fsync_mode=%s"}, > > > - {Opt_test_dummy_encryption, "test_dummy_encryption=%s"}, > > > - {Opt_test_dummy_encryption, "test_dummy_encryption"}, > > > - {Opt_inlinecrypt, "inlinecrypt"}, > > > - {Opt_checkpoint_disable, "checkpoint=disable"}, > > > - {Opt_checkpoint_disable_cap, "checkpoint=disable:%u"}, > > > - {Opt_checkpoint_disable_cap_perc, "checkpoint=disable:%u%%"}, > > > - {Opt_checkpoint_enable, "checkpoint=enable"}, > > > - {Opt_checkpoint_merge, "checkpoint_merge"}, > > > - {Opt_nocheckpoint_merge, "nocheckpoint_merge"}, > > > - {Opt_compress_algorithm, "compress_algorithm=%s"}, > > > - {Opt_compress_log_size, "compress_log_size=%u"}, > > > - {Opt_compress_extension, "compress_extension=%s"}, > > > - {Opt_nocompress_extension, "nocompress_extension=%s"}, > > > - {Opt_compress_chksum, "compress_chksum"}, > > > - {Opt_compress_mode, "compress_mode=%s"}, > > > - {Opt_compress_cache, "compress_cache"}, > > > - {Opt_atgc, "atgc"}, > > > - {Opt_gc_merge, "gc_merge"}, > > > - {Opt_nogc_merge, "nogc_merge"}, > > > - {Opt_discard_unit, "discard_unit=%s"}, > > > - {Opt_memory_mode, "memory=%s"}, > > > - {Opt_age_extent_cache, "age_extent_cache"}, > > > - {Opt_errors, "errors=%s"}, > > > - {Opt_nat_bits, "nat_bits"}, > > > +/* Resort to a match_table for this interestingly formatted option */ > > > +static match_table_t f2fs_checkpoint_tokens = { > > > + {Opt_checkpoint_disable, "disable"}, > > > + {Opt_checkpoint_disable_cap, "disable:%u"}, > > > + {Opt_checkpoint_disable_cap_perc, "disable:%u%%"}, > > > + {Opt_checkpoint_enable, "enable"}, > > > {Opt_err, NULL}, > > > }; > > > @@ -513,7 +424,7 @@ static void init_once(void *foo) > > > static const char * const quotatypes[] = INITQFNAMES; > > > #define QTYPE2NAME(t) (quotatypes[t]) > > > static int f2fs_set_qf_name(struct f2fs_sb_info *sbi, int qtype, > > > - substring_t *args) > > > + struct fs_parameter *param) > > > { > > > struct super_block *sb = sbi->sb; > > > char *qname; > > > @@ -528,7 +439,7 @@ static int f2fs_set_qf_name(struct f2fs_sb_info *sbi, > > > int qtype, > > > return 0; > > > } > > > - qname = match_strdup(args); > > > + qname = kmemdup_nul(param->string, param->size, GFP_KERNEL); > > > if (!qname) { > > > f2fs_err(sbi, "Not enough memory for storing quotafile > > > name"); > > > return -ENOMEM; > > > @@ -613,14 +524,9 @@ static int f2fs_check_quota_options(struct > > > f2fs_sb_info *sbi) > > > #endif > > > static int f2fs_set_test_dummy_encryption(struct f2fs_sb_info *sbi, > > > - const char *opt, > > > - const substring_t *arg, > > > + const struct fs_parameter *param, > > > bool is_remount) > > > { > > > - struct fs_parameter param = { > > > - .type = fs_value_is_string, > > > - .string = arg->from ? arg->from : "", > > > - }; > > > struct fscrypt_dummy_policy *policy = > > > &F2FS_OPTION(sbi).dummy_enc_policy; > > > int err; > > > @@ -646,17 +552,17 @@ static int f2fs_set_test_dummy_encryption(struct > > > f2fs_sb_info *sbi, > > > return -EINVAL; > > > } > > > - err = fscrypt_parse_test_dummy_encryption(¶m, policy); > > > + err = fscrypt_parse_test_dummy_encryption(param, policy); > > > if (err) { > > > if (err == -EEXIST) > > > f2fs_warn(sbi, > > > "Can't change test_dummy_encryption > > > on remount"); > > > else if (err == -EINVAL) > > > f2fs_warn(sbi, "Value of option \"%s\" is > > > unrecognized", > > > - opt); > > > + param->key); > > > else > > > f2fs_warn(sbi, "Error processing option \"%s\" > > > [%d]", > > > - opt, err); > > > + param->key, err); > > > return -EINVAL; > > > } > > > f2fs_warn(sbi, "Test dummy encryption mode enabled"); > > > @@ -799,372 +705,269 @@ static int f2fs_set_zstd_level(struct > > > f2fs_sb_info *sbi, const char *str) > > > #endif > > > #endif > > > -static int parse_options(struct f2fs_sb_info *sbi, char *options, bool > > > is_remount) > > > +static int handle_mount_opt(struct fs_context *fc, struct fs_parameter > > > *param) > > > { > > > - substring_t args[MAX_OPT_ARGS]; > > > + struct f2fs_sb_info *sbi = fc->s_fs_info; > > > #ifdef CONFIG_F2FS_FS_COMPRESSION > > > unsigned char (*ext)[F2FS_EXTENSION_LEN]; > > > unsigned char (*noext)[F2FS_EXTENSION_LEN]; > > > int ext_cnt, noext_cnt; > > > + char *name; > > > #endif > > > - char *p, *name; > > > - int arg = 0; > > > - kuid_t uid; > > > - kgid_t gid; > > > - int ret; > > > + substring_t args[MAX_OPT_ARGS]; > > > + struct fs_parse_result result; > > > + bool is_remount; > > > + int token, ret, arg; > > > - if (!options) > > > - return 0; > > > + token = fs_parse(fc, f2fs_param_specs, param, &result); > > > + if (token < 0) > > > + return token; > > > - while ((p = strsep(&options, ",")) != NULL) { > > > - int token; > > > + is_remount = fc->purpose == FS_CONTEXT_FOR_RECONFIGURE; > > > - if (!*p) > > > - continue; > > > - /* > > > - * Initialize args struct so we know whether arg was > > > - * found; some options take optional arguments. > > > - */ > > > - args[0].to = args[0].from = NULL; > > > - token = match_token(p, f2fs_tokens, args); > > > - > > > - switch (token) { > > > - case Opt_gc_background: > > > - name = match_strdup(&args[0]); > > > - > > > - if (!name) > > > - return -ENOMEM; > > > - if (!strcmp(name, "on")) { > > > - F2FS_OPTION(sbi).bggc_mode = BGGC_MODE_ON; > > > - } else if (!strcmp(name, "off")) { > > > - if (f2fs_sb_has_blkzoned(sbi)) { > > > - f2fs_warn(sbi, "zoned devices need > > > bggc"); > > > - kfree(name); > > > - return -EINVAL; > > > - } > > > > Missed to check this condition in f2fs_check_opt_consistency()? > > > > Thanks for pointing this. Yeah, we should add this in > f2fs_check_opt_consistency like this: > > diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c > index 0a070dadbb42..86938dd5491e 100644 > --- a/fs/f2fs/super.c > +++ b/fs/f2fs/super.c > @@ -1458,6 +1458,10 @@ static int f2fs_check_opt_consistency(struct > fs_context *fc, > * devices, but mandatory for host-managed zoned block devices. > */ > if (f2fs_sb_has_blkzoned(sbi)) { > + if (F2FS_CTX_OPTION(ctx).bggc_mode == BGGC_MODE_OFF) { > + f2fs_warn(sbi, "zoned devices need bggc"); > + return -EINVAL; > + } > #ifdef CONFIG_BLK_DEV_ZONED > if ((ctx->spec_mask & F2FS_SPEC_discard_unit) && > F2FS_CTX_INFO(ctx).discard_unit != DISCARD_UNIT_SECTION) { > > Thanks, > Hongbo > > > Thanks, > > > > > - F2FS_OPTION(sbi).bggc_mode = BGGC_MODE_OFF; > > > - } else if (!strcmp(name, "sync")) { > > > - F2FS_OPTION(sbi).bggc_mode = BGGC_MODE_SYNC; > > > - } else { > > > - kfree(name); > > > + switch (token) { > > > + case Opt_gc_background: > > > + F2FS_OPTION(sbi).bggc_mode = result.uint_32; > > > + break; > > > + case Opt_disable_roll_forward: > > > + set_opt(sbi, DISABLE_ROLL_FORWARD); > > > + break; > > > + case Opt_norecovery: > > > + /* requires ro mount, checked in f2fs_validate_options */ > > > + set_opt(sbi, NORECOVERY); > > > + break; > > > + case Opt_discard: > > > + if (result.negated) { > > > + if (f2fs_hw_should_discard(sbi)) { > > > + f2fs_warn(sbi, "discard is required for zoned > > > block devices"); > > > return -EINVAL; > > > } > > > - kfree(name); > > > - break; > > > - case Opt_disable_roll_forward: > > > - set_opt(sbi, DISABLE_ROLL_FORWARD); > > > - break; > > > - case Opt_norecovery: > > > - /* requires ro mount, checked in f2fs_default_check */ > > > - set_opt(sbi, NORECOVERY); > > > - break; > > > - case Opt_discard: > > > + clear_opt(sbi, DISCARD); > > > + } else { > > > if (!f2fs_hw_support_discard(sbi)) { > > > f2fs_warn(sbi, "device does not support > > > discard"); > > > break; > > > } > > > set_opt(sbi, DISCARD); > > > - break; > > > - case Opt_nodiscard: > > > - if (f2fs_hw_should_discard(sbi)) { > > > - f2fs_warn(sbi, "discard is required for zoned > > > block devices"); > > > - return -EINVAL; > > > - } > > > - clear_opt(sbi, DISCARD); > > > - break; > > > - case Opt_noheap: > > > - case Opt_heap: > > > - f2fs_warn(sbi, "heap/no_heap options were deprecated"); > > > - break; > > > + } > > > + break; > > > + case Opt_noheap: > > > + case Opt_heap: > > > + f2fs_warn(sbi, "heap/no_heap options were deprecated"); > > > + break; > > > #ifdef CONFIG_F2FS_FS_XATTR > > > - case Opt_user_xattr: > > > - set_opt(sbi, XATTR_USER); > > > - break; > > > - case Opt_nouser_xattr: > > > + case Opt_user_xattr: > > > + if (result.negated) > > > clear_opt(sbi, XATTR_USER); > > > - break; > > > - case Opt_inline_xattr: > > > - set_opt(sbi, INLINE_XATTR); > > > - break; > > > - case Opt_noinline_xattr: > > > + else > > > + set_opt(sbi, XATTR_USER); > > > + break; > > > + case Opt_inline_xattr: > > > + if (result.negated) > > > clear_opt(sbi, INLINE_XATTR); > > > - break; > > > - case Opt_inline_xattr_size: > > > - if (args->from && match_int(args, &arg)) > > > - return -EINVAL; > > > - set_opt(sbi, INLINE_XATTR_SIZE); > > > - F2FS_OPTION(sbi).inline_xattr_size = arg; > > > - break; > > > + else > > > + set_opt(sbi, INLINE_XATTR); > > > + break; > > > + case Opt_inline_xattr_size: > > > + set_opt(sbi, INLINE_XATTR_SIZE); > > > + F2FS_OPTION(sbi).inline_xattr_size = result.int_32; > > > + break; > > > #else > > > - case Opt_user_xattr: > > > - case Opt_nouser_xattr: > > > - case Opt_inline_xattr: > > > - case Opt_noinline_xattr: > > > - case Opt_inline_xattr_size: > > > - f2fs_info(sbi, "xattr options not supported"); > > > - break; > > > + case Opt_user_xattr: > > > + case Opt_inline_xattr: > > > + case Opt_inline_xattr_size: > > > + f2fs_info(sbi, "%s options not supported", param->key); > > > + break; > > > #endif > > > #ifdef CONFIG_F2FS_FS_POSIX_ACL > > > - case Opt_acl: > > > - set_opt(sbi, POSIX_ACL); > > > - break; > > > - case Opt_noacl: > > > + case Opt_acl: > > > + if (result.negated) > > > clear_opt(sbi, POSIX_ACL); > > > - break; > > > + else > > > + set_opt(sbi, POSIX_ACL); > > > + break; > > > #else > > > - case Opt_acl: > > > - case Opt_noacl: > > > - f2fs_info(sbi, "acl options not supported"); > > > - break; > > > + case Opt_acl: > > > + f2fs_info(sbi, "%s options not supported", param->key); > > > + break; > > > #endif > > > - case Opt_active_logs: > > > - if (args->from && match_int(args, &arg)) > > > - return -EINVAL; > > > - if (arg != 2 && arg != 4 && > > > - arg != NR_CURSEG_PERSIST_TYPE) > > > - return -EINVAL; > > > - F2FS_OPTION(sbi).active_logs = arg; > > > - break; > > > - case Opt_disable_ext_identify: > > > - set_opt(sbi, DISABLE_EXT_IDENTIFY); > > > - break; > > > - case Opt_inline_data: > > > + case Opt_active_logs: > > > + if (result.int_32 != 2 && result.int_32 != 4 && > > > + result.int_32 != NR_CURSEG_PERSIST_TYPE) > > > + return -EINVAL; > > > + F2FS_OPTION(sbi).active_logs = result.int_32; > > > + break; > > > + case Opt_disable_ext_identify: > > > + set_opt(sbi, DISABLE_EXT_IDENTIFY); > > > + break; > > > + case Opt_inline_data: > > > + if (result.negated) > > > + clear_opt(sbi, INLINE_DATA); > > > + else > > > set_opt(sbi, INLINE_DATA); > > > - break; > > > - case Opt_inline_dentry: > > > - set_opt(sbi, INLINE_DENTRY); > > > - break; > > > - case Opt_noinline_dentry: > > > + break; > > > + case Opt_inline_dentry: > > > + if (result.negated) > > > clear_opt(sbi, INLINE_DENTRY); > > > - break; > > > - case Opt_flush_merge: > > > - set_opt(sbi, FLUSH_MERGE); > > > - break; > > > - case Opt_noflush_merge: > > > + else > > > + set_opt(sbi, INLINE_DENTRY); > > > + break; > > > + case Opt_flush_merge: > > > + if (result.negated) > > > clear_opt(sbi, FLUSH_MERGE); > > > - break; > > > - case Opt_nobarrier: > > > + else > > > + set_opt(sbi, FLUSH_MERGE); > > > + break; > > > + case Opt_barrier: > > > + if (result.negated) > > > set_opt(sbi, NOBARRIER); > > > - break; > > > - case Opt_barrier: > > > + else > > > clear_opt(sbi, NOBARRIER); > > > - break; > > > - case Opt_fastboot: > > > - set_opt(sbi, FASTBOOT); > > > - break; > > > - case Opt_extent_cache: > > > - set_opt(sbi, READ_EXTENT_CACHE); > > > - break; > > > - case Opt_noextent_cache: > > > + break; > > > + case Opt_fastboot: > > > + set_opt(sbi, FASTBOOT); > > > + break; > > > + case Opt_extent_cache: > > > + if (result.negated) { > > > if (f2fs_sb_has_device_alias(sbi)) { > > > f2fs_err(sbi, "device aliasing requires > > > extent cache"); > > > return -EINVAL; > > > } > > > clear_opt(sbi, READ_EXTENT_CACHE); > > > - break; > > > - case Opt_noinline_data: > > > - clear_opt(sbi, INLINE_DATA); > > > - break; > > > - case Opt_data_flush: > > > - set_opt(sbi, DATA_FLUSH); > > > - break; > > > - case Opt_reserve_root: > > > - if (args->from && match_int(args, &arg)) > > > - return -EINVAL; > > > - if (test_opt(sbi, RESERVE_ROOT)) { > > > - f2fs_info(sbi, "Preserve previous > > > reserve_root=%u", > > > - > > > F2FS_OPTION(sbi).root_reserved_blocks); > > > - } else { > > > - F2FS_OPTION(sbi).root_reserved_blocks = arg; > > > - set_opt(sbi, RESERVE_ROOT); > > > - } > > > - break; > > > - case Opt_resuid: > > > - if (args->from && match_int(args, &arg)) > > > - return -EINVAL; > > > - uid = make_kuid(current_user_ns(), arg); > > > - if (!uid_valid(uid)) { > > > - f2fs_err(sbi, "Invalid uid value %d", arg); > > > - return -EINVAL; > > > - } > > > - F2FS_OPTION(sbi).s_resuid = uid; > > > - break; > > > - case Opt_resgid: > > > - if (args->from && match_int(args, &arg)) > > > - return -EINVAL; > > > - gid = make_kgid(current_user_ns(), arg); > > > - if (!gid_valid(gid)) { > > > - f2fs_err(sbi, "Invalid gid value %d", arg); > > > - return -EINVAL; > > > - } > > > - F2FS_OPTION(sbi).s_resgid = gid; > > > - break; > > > - case Opt_mode: > > > - name = match_strdup(&args[0]); > > > - > > > - if (!name) > > > - return -ENOMEM; > > > - if (!strcmp(name, "adaptive")) { > > > - F2FS_OPTION(sbi).fs_mode = FS_MODE_ADAPTIVE; > > > - } else if (!strcmp(name, "lfs")) { > > > - F2FS_OPTION(sbi).fs_mode = FS_MODE_LFS; > > > - } else if (!strcmp(name, "fragment:segment")) { > > > - F2FS_OPTION(sbi).fs_mode = FS_MODE_FRAGMENT_SEG; > > > - } else if (!strcmp(name, "fragment:block")) { > > > - F2FS_OPTION(sbi).fs_mode = FS_MODE_FRAGMENT_BLK; > > > - } else { > > > - kfree(name); > > > - return -EINVAL; > > > - } > > > - kfree(name); > > > - break; > > > + } else > > > + set_opt(sbi, READ_EXTENT_CACHE); > > > + break; > > > + case Opt_data_flush: > > > + set_opt(sbi, DATA_FLUSH); > > > + break; > > > + case Opt_reserve_root: > > > + if (test_opt(sbi, RESERVE_ROOT)) { > > > + f2fs_info(sbi, "Preserve previous reserve_root=%u", > > > + F2FS_OPTION(sbi).root_reserved_blocks); > > > + } else { > > > + F2FS_OPTION(sbi).root_reserved_blocks = result.int_32; > > > + set_opt(sbi, RESERVE_ROOT); > > > + } > > > + break; > > > + case Opt_resuid: > > > + F2FS_OPTION(sbi).s_resuid = result.uid; > > > + break; > > > + case Opt_resgid: > > > + F2FS_OPTION(sbi).s_resgid = result.gid; > > > + break; > > > + case Opt_mode: > > > + F2FS_OPTION(sbi).fs_mode = result.uint_32; > > > + break; > > > #ifdef CONFIG_F2FS_FAULT_INJECTION > > > - case Opt_fault_injection: > > > - if (args->from && match_int(args, &arg)) > > > - return -EINVAL; > > > - if (f2fs_build_fault_attr(sbi, arg, 0, FAULT_RATE)) > > > - return -EINVAL; > > > - set_opt(sbi, FAULT_INJECTION); > > > - break; > > > + case Opt_fault_injection: > > > + if (f2fs_build_fault_attr(sbi, result.int_32, 0, FAULT_RATE)) > > > + return -EINVAL; > > > + set_opt(sbi, FAULT_INJECTION); > > > + break; > > > - case Opt_fault_type: > > > - if (args->from && match_int(args, &arg)) > > > - return -EINVAL; > > > - if (f2fs_build_fault_attr(sbi, 0, arg, FAULT_TYPE)) > > > - return -EINVAL; > > > - set_opt(sbi, FAULT_INJECTION); > > > - break; > > > + case Opt_fault_type: > > > + if (f2fs_build_fault_attr(sbi, 0, result.int_32, FAULT_TYPE)) > > > + return -EINVAL; > > > + set_opt(sbi, FAULT_INJECTION); > > > + break; > > > #else > > > - case Opt_fault_injection: > > > - case Opt_fault_type: > > > - f2fs_info(sbi, "fault injection options not supported"); > > > - break; > > > + case Opt_fault_injection: > > > + case Opt_fault_type: > > > + f2fs_info(sbi, "%s options not supported", param->key); > > > + break; > > > #endif > > > - case Opt_lazytime: > > > - set_opt(sbi, LAZYTIME); > > > - break; > > > - case Opt_nolazytime: > > > + case Opt_lazytime: > > > + if (result.negated) > > > clear_opt(sbi, LAZYTIME); > > > - break; > > > + else > > > + set_opt(sbi, LAZYTIME); > > > + break; > > > #ifdef CONFIG_QUOTA > > > - case Opt_quota: > > > - case Opt_usrquota: > > > - set_opt(sbi, USRQUOTA); > > > - break; > > > - case Opt_grpquota: > > > - set_opt(sbi, GRPQUOTA); > > > - break; > > > - case Opt_prjquota: > > > - set_opt(sbi, PRJQUOTA); > > > - break; > > > - case Opt_usrjquota: > > > - ret = f2fs_set_qf_name(sbi, USRQUOTA, &args[0]); > > > - if (ret) > > > - return ret; > > > - break; > > > - case Opt_grpjquota: > > > - ret = f2fs_set_qf_name(sbi, GRPQUOTA, &args[0]); > > > - if (ret) > > > - return ret; > > > - break; > > > - case Opt_prjjquota: > > > - ret = f2fs_set_qf_name(sbi, PRJQUOTA, &args[0]); > > > - if (ret) > > > - return ret; > > > - break; > > > - case Opt_offusrjquota: > > > - ret = f2fs_clear_qf_name(sbi, USRQUOTA); > > > - if (ret) > > > - return ret; > > > - break; > > > - case Opt_offgrpjquota: > > > - ret = f2fs_clear_qf_name(sbi, GRPQUOTA); > > > - if (ret) > > > - return ret; > > > - break; > > > - case Opt_offprjjquota: > > > - ret = f2fs_clear_qf_name(sbi, PRJQUOTA); > > > - if (ret) > > > - return ret; > > > - break; > > > - case Opt_jqfmt_vfsold: > > > - F2FS_OPTION(sbi).s_jquota_fmt = QFMT_VFS_OLD; > > > - break; > > > - case Opt_jqfmt_vfsv0: > > > - F2FS_OPTION(sbi).s_jquota_fmt = QFMT_VFS_V0; > > > - break; > > > - case Opt_jqfmt_vfsv1: > > > - F2FS_OPTION(sbi).s_jquota_fmt = QFMT_VFS_V1; > > > - break; > > > - case Opt_noquota: > > > + case Opt_quota: > > > + if (result.negated) { > > > clear_opt(sbi, QUOTA); > > > clear_opt(sbi, USRQUOTA); > > > clear_opt(sbi, GRPQUOTA); > > > clear_opt(sbi, PRJQUOTA); > > > - break; > > > + } else > > > + set_opt(sbi, USRQUOTA); > > > + break; > > > + case Opt_usrquota: > > > + set_opt(sbi, USRQUOTA); > > > + break; > > > + case Opt_grpquota: > > > + set_opt(sbi, GRPQUOTA); > > > + break; > > > + case Opt_prjquota: > > > + set_opt(sbi, PRJQUOTA); > > > + break; > > > + case Opt_usrjquota: > > > + if (!*param->string) > > > + ret = f2fs_clear_qf_name(sbi, USRQUOTA); > > > + else > > > + ret = f2fs_set_qf_name(sbi, USRQUOTA, param); > > > + if (ret) > > > + return ret; > > > + break; > > > + case Opt_grpjquota: > > > + if (!*param->string) > > > + ret = f2fs_clear_qf_name(sbi, GRPQUOTA); > > > + else > > > + ret = f2fs_set_qf_name(sbi, GRPQUOTA, param); > > > + if (ret) > > > + return ret; > > > + break; > > > + case Opt_prjjquota: > > > + if (!*param->string) > > > + ret = f2fs_clear_qf_name(sbi, PRJQUOTA); > > > + else > > > + ret = f2fs_set_qf_name(sbi, PRJQUOTA, param); > > > + if (ret) > > > + return ret; > > > + break; > > > + case Opt_jqfmt: > > > + F2FS_OPTION(sbi).s_jquota_fmt = result.uint_32; > > > + break; > > > #else > > > - case Opt_quota: > > > - case Opt_usrquota: > > > - case Opt_grpquota: > > > - case Opt_prjquota: > > > - case Opt_usrjquota: > > > - case Opt_grpjquota: > > > - case Opt_prjjquota: > > > - case Opt_offusrjquota: > > > - case Opt_offgrpjquota: > > > - case Opt_offprjjquota: > > > - case Opt_jqfmt_vfsold: > > > - case Opt_jqfmt_vfsv0: > > > - case Opt_jqfmt_vfsv1: > > > - case Opt_noquota: > > > - f2fs_info(sbi, "quota operations not supported"); > > > - break; > > > + case Opt_quota: > > > + case Opt_usrquota: > > > + case Opt_grpquota: > > > + case Opt_prjquota: > > > + case Opt_usrjquota: > > > + case Opt_grpjquota: > > > + case Opt_prjjquota: > > > + f2fs_info(sbi, "quota operations not supported"); > > > + break; > > > #endif > > > - case Opt_alloc: > > > - name = match_strdup(&args[0]); > > > - if (!name) > > > - return -ENOMEM; > > > - > > > - if (!strcmp(name, "default")) { > > > - F2FS_OPTION(sbi).alloc_mode = > > > ALLOC_MODE_DEFAULT; > > > - } else if (!strcmp(name, "reuse")) { > > > - F2FS_OPTION(sbi).alloc_mode = ALLOC_MODE_REUSE; > > > - } else { > > > - kfree(name); > > > - return -EINVAL; > > > - } > > > - kfree(name); > > > - break; > > > - case Opt_fsync: > > > - name = match_strdup(&args[0]); > > > - if (!name) > > > - return -ENOMEM; > > > - if (!strcmp(name, "posix")) { > > > - F2FS_OPTION(sbi).fsync_mode = FSYNC_MODE_POSIX; > > > - } else if (!strcmp(name, "strict")) { > > > - F2FS_OPTION(sbi).fsync_mode = FSYNC_MODE_STRICT; > > > - } else if (!strcmp(name, "nobarrier")) { > > > - F2FS_OPTION(sbi).fsync_mode = > > > - FSYNC_MODE_NOBARRIER; > > > - } else { > > > - kfree(name); > > > - return -EINVAL; > > > - } > > > - kfree(name); > > > - break; > > > - case Opt_test_dummy_encryption: > > > - ret = f2fs_set_test_dummy_encryption(sbi, p, &args[0], > > > - is_remount); > > > - if (ret) > > > - return ret; > > > - break; > > > - case Opt_inlinecrypt: > > > + case Opt_alloc: > > > + F2FS_OPTION(sbi).alloc_mode = result.uint_32; > > > + break; > > > + case Opt_fsync: > > > + F2FS_OPTION(sbi).fsync_mode = result.uint_32; > > > + break; > > > + case Opt_test_dummy_encryption: > > > + ret = f2fs_set_test_dummy_encryption(sbi, param, is_remount); > > > + if (ret) > > > + return ret; > > > + break; > > > + case Opt_inlinecrypt: > > > #ifdef CONFIG_FS_ENCRYPTION_INLINE_CRYPT > > > - set_opt(sbi, INLINECRYPT); > > > + set_opt(sbi, INLINECRYPT); > > > #else > > > - f2fs_info(sbi, "inline encryption not supported"); > > > + f2fs_info(sbi, "inline encryption not supported"); > > > #endif > > > - break; > > > + break; > > > + case Opt_checkpoint: > > > + /* > > > + * Initialize args struct so we know whether arg was > > > + * found; some options take optional arguments. > > > + */ > > > + args[0].from = args[0].to = NULL; > > > + arg = 0; > > > + > > > + /* revert to match_table for checkpoint= options */ > > > + token = match_token(param->string, f2fs_checkpoint_tokens, > > > args); > > > + switch (token) { > > > case Opt_checkpoint_disable_cap_perc: > > > if (args->from && match_int(args, &arg)) > > > return -EINVAL; > > > @@ -1185,270 +988,225 @@ static int parse_options(struct f2fs_sb_info > > > *sbi, char *options, bool is_remoun > > > case Opt_checkpoint_enable: > > > clear_opt(sbi, DISABLE_CHECKPOINT); > > > break; > > > - case Opt_checkpoint_merge: > > > - set_opt(sbi, MERGE_CHECKPOINT); > > > - break; > > > - case Opt_nocheckpoint_merge: > > > + default: > > > + return -EINVAL; > > > + } > > > + break; > > > + case Opt_checkpoint_merge: > > > + if (result.negated) > > > clear_opt(sbi, MERGE_CHECKPOINT); > > > - break; > > > + else > > > + set_opt(sbi, MERGE_CHECKPOINT); > > > + break; > > > #ifdef CONFIG_F2FS_FS_COMPRESSION > > > - case Opt_compress_algorithm: > > > - if (!f2fs_sb_has_compression(sbi)) { > > > - f2fs_info(sbi, "Image doesn't support > > > compression"); > > > - break; > > > - } > > > - name = match_strdup(&args[0]); > > > - if (!name) > > > - return -ENOMEM; > > > - if (!strcmp(name, "lzo")) { > > > + case Opt_compress_algorithm: > > > + if (!f2fs_sb_has_compression(sbi)) { > > > + f2fs_info(sbi, "Image doesn't support compression"); > > > + break; > > > + } > > > + name = param->string; > > > + if (!strcmp(name, "lzo")) { > > > #ifdef CONFIG_F2FS_FS_LZO > > > - F2FS_OPTION(sbi).compress_level = 0; > > > - F2FS_OPTION(sbi).compress_algorithm = > > > - COMPRESS_LZO; > > > + F2FS_OPTION(sbi).compress_level = 0; > > > + F2FS_OPTION(sbi).compress_algorithm = COMPRESS_LZO; > > > #else > > > - f2fs_info(sbi, "kernel doesn't support lzo > > > compression"); > > > + f2fs_info(sbi, "kernel doesn't support lzo > > > compression"); > > > #endif > > > - } else if (!strncmp(name, "lz4", 3)) { > > > + } else if (!strncmp(name, "lz4", 3)) { > > > #ifdef CONFIG_F2FS_FS_LZ4 > > > - ret = f2fs_set_lz4hc_level(sbi, name); > > > - if (ret) { > > > - kfree(name); > > > - return -EINVAL; > > > - } > > > - F2FS_OPTION(sbi).compress_algorithm = > > > - COMPRESS_LZ4; > > > + ret = f2fs_set_lz4hc_level(sbi, name); > > > + if (ret) > > > + return -EINVAL; > > > + F2FS_OPTION(sbi).compress_algorithm = COMPRESS_LZ4; > > > #else > > > - f2fs_info(sbi, "kernel doesn't support lz4 > > > compression"); > > > + f2fs_info(sbi, "kernel doesn't support lz4 > > > compression"); > > > #endif > > > - } else if (!strncmp(name, "zstd", 4)) { > > > + } else if (!strncmp(name, "zstd", 4)) { > > > #ifdef CONFIG_F2FS_FS_ZSTD > > > - ret = f2fs_set_zstd_level(sbi, name); > > > - if (ret) { > > > - kfree(name); > > > - return -EINVAL; > > > - } > > > - F2FS_OPTION(sbi).compress_algorithm = > > > - COMPRESS_ZSTD; > > > + ret = f2fs_set_zstd_level(sbi, name); > > > + if (ret) > > > + return -EINVAL; > > > + F2FS_OPTION(sbi).compress_algorithm = COMPRESS_ZSTD; > > > #else > > > - f2fs_info(sbi, "kernel doesn't support zstd > > > compression"); > > > + f2fs_info(sbi, "kernel doesn't support zstd > > > compression"); > > > #endif > > > - } else if (!strcmp(name, "lzo-rle")) { > > > + } else if (!strcmp(name, "lzo-rle")) { > > > #ifdef CONFIG_F2FS_FS_LZORLE > > > - F2FS_OPTION(sbi).compress_level = 0; > > > - F2FS_OPTION(sbi).compress_algorithm = > > > - COMPRESS_LZORLE; > > > + F2FS_OPTION(sbi).compress_level = 0; > > > + F2FS_OPTION(sbi).compress_algorithm = COMPRESS_LZORLE; > > > #else > > > - f2fs_info(sbi, "kernel doesn't support lzorle > > > compression"); > > > + f2fs_info(sbi, "kernel doesn't support lzorle > > > compression"); > > > #endif > > > - } else { > > > - kfree(name); > > > - return -EINVAL; > > > - } > > > - kfree(name); > > > + } else > > > + return -EINVAL; > > > + break; > > > + case Opt_compress_log_size: > > > + if (!f2fs_sb_has_compression(sbi)) { > > > + f2fs_info(sbi, "Image doesn't support compression"); > > > break; > > > - case Opt_compress_log_size: > > > - if (!f2fs_sb_has_compression(sbi)) { > > > - f2fs_info(sbi, "Image doesn't support > > > compression"); > > > - break; > > > - } > > > - if (args->from && match_int(args, &arg)) > > > - return -EINVAL; > > > - if (arg < MIN_COMPRESS_LOG_SIZE || > > > - arg > MAX_COMPRESS_LOG_SIZE) { > > > - f2fs_err(sbi, > > > - "Compress cluster log size is out of > > > range"); > > > - return -EINVAL; > > > - } > > > - F2FS_OPTION(sbi).compress_log_size = arg; > > > + } > > > + if (result.uint_32 < MIN_COMPRESS_LOG_SIZE || > > > + result.uint_32 > MAX_COMPRESS_LOG_SIZE) { > > > + f2fs_err(sbi, > > > + "Compress cluster log size is out of range"); > > > + return -EINVAL; > > > + } > > > + F2FS_OPTION(sbi).compress_log_size = result.uint_32; > > > + break; > > > + case Opt_compress_extension: > > > + if (!f2fs_sb_has_compression(sbi)) { > > > + f2fs_info(sbi, "Image doesn't support compression"); > > > break; > > > - case Opt_compress_extension: > > > - if (!f2fs_sb_has_compression(sbi)) { > > > - f2fs_info(sbi, "Image doesn't support > > > compression"); > > > - break; > > > - } > > > - name = match_strdup(&args[0]); > > > - if (!name) > > > - return -ENOMEM; > > > - > > > - ext = F2FS_OPTION(sbi).extensions; > > > - ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt; > > > - > > > - if (strlen(name) >= F2FS_EXTENSION_LEN || > > > - ext_cnt >= COMPRESS_EXT_NUM) { > > > - f2fs_err(sbi, > > > - "invalid extension length/number"); > > > - kfree(name); > > > - return -EINVAL; > > > - } > > > + } > > > + name = param->string; > > > + ext = F2FS_OPTION(sbi).extensions; > > > + ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt; > > > - if (is_compress_extension_exist(sbi, name, true)) { > > > - kfree(name); > > > - break; > > > - } > > > + if (strlen(name) >= F2FS_EXTENSION_LEN || > > > + ext_cnt >= COMPRESS_EXT_NUM) { > > > + f2fs_err(sbi, "invalid extension length/number"); > > > + return -EINVAL; > > > + } > > > - ret = strscpy(ext[ext_cnt], name); > > > - if (ret < 0) { > > > - kfree(name); > > > - return ret; > > > - } > > > - F2FS_OPTION(sbi).compress_ext_cnt++; > > > - kfree(name); > > > + if (is_compress_extension_exist(sbi, name, true)) > > > break; > > > - case Opt_nocompress_extension: > > > - if (!f2fs_sb_has_compression(sbi)) { > > > - f2fs_info(sbi, "Image doesn't support > > > compression"); > > > - break; > > > - } > > > - name = match_strdup(&args[0]); > > > - if (!name) > > > - return -ENOMEM; > > > - > > > - noext = F2FS_OPTION(sbi).noextensions; > > > - noext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt; > > > - if (strlen(name) >= F2FS_EXTENSION_LEN || > > > - noext_cnt >= COMPRESS_EXT_NUM) { > > > - f2fs_err(sbi, > > > - "invalid extension length/number"); > > > - kfree(name); > > > - return -EINVAL; > > > - } > > > + ret = strscpy(ext[ext_cnt], name, F2FS_EXTENSION_LEN); > > > + if (ret < 0) > > > + return ret; > > > + F2FS_OPTION(sbi).compress_ext_cnt++; > > > + break; > > > + case Opt_nocompress_extension: > > > + if (!f2fs_sb_has_compression(sbi)) { > > > + f2fs_info(sbi, "Image doesn't support compression"); > > > + break; > > > + } > > > + name = param->string; > > > + noext = F2FS_OPTION(sbi).noextensions; > > > + noext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt; > > > - if (is_compress_extension_exist(sbi, name, false)) { > > > - kfree(name); > > > - break; > > > - } > > > + if (strlen(name) >= F2FS_EXTENSION_LEN || > > > + noext_cnt >= COMPRESS_EXT_NUM) { > > > + f2fs_err(sbi, "invalid extension length/number"); > > > + return -EINVAL; > > > + } > > > - ret = strscpy(noext[noext_cnt], name); > > > - if (ret < 0) { > > > - kfree(name); > > > - return ret; > > > - } > > > - F2FS_OPTION(sbi).nocompress_ext_cnt++; > > > - kfree(name); > > > + if (is_compress_extension_exist(sbi, name, false)) > > > break; > > > - case Opt_compress_chksum: > > > - if (!f2fs_sb_has_compression(sbi)) { > > > - f2fs_info(sbi, "Image doesn't support > > > compression"); > > > - break; > > > - } > > > - F2FS_OPTION(sbi).compress_chksum = true; > > > + > > > + ret = strscpy(noext[noext_cnt], name, F2FS_EXTENSION_LEN); > > > + if (ret < 0) > > > + return ret; > > > + F2FS_OPTION(sbi).nocompress_ext_cnt++; > > > + break; > > > + case Opt_compress_chksum: > > > + if (!f2fs_sb_has_compression(sbi)) { > > > + f2fs_info(sbi, "Image doesn't support compression"); > > > break; > > > - case Opt_compress_mode: > > > - if (!f2fs_sb_has_compression(sbi)) { > > > - f2fs_info(sbi, "Image doesn't support > > > compression"); > > > - break; > > > - } > > > - name = match_strdup(&args[0]); > > > - if (!name) > > > - return -ENOMEM; > > > - if (!strcmp(name, "fs")) { > > > - F2FS_OPTION(sbi).compress_mode = COMPR_MODE_FS; > > > - } else if (!strcmp(name, "user")) { > > > - F2FS_OPTION(sbi).compress_mode = > > > COMPR_MODE_USER; > > > - } else { > > > - kfree(name); > > > - return -EINVAL; > > > - } > > > - kfree(name); > > > + } > > > + F2FS_OPTION(sbi).compress_chksum = true; > > > + break; > > > + case Opt_compress_mode: > > > + if (!f2fs_sb_has_compression(sbi)) { > > > + f2fs_info(sbi, "Image doesn't support compression"); > > > break; > > > - case Opt_compress_cache: > > > - if (!f2fs_sb_has_compression(sbi)) { > > > - f2fs_info(sbi, "Image doesn't support > > > compression"); > > > - break; > > > - } > > > - set_opt(sbi, COMPRESS_CACHE); > > > + } > > > + F2FS_OPTION(sbi).compress_mode = result.uint_32; > > > + break; > > > + case Opt_compress_cache: > > > + if (!f2fs_sb_has_compression(sbi)) { > > > + f2fs_info(sbi, "Image doesn't support compression"); > > > break; > > > + } > > > + set_opt(sbi, COMPRESS_CACHE); > > > + break; > > > #else > > > - case Opt_compress_algorithm: > > > - case Opt_compress_log_size: > > > - case Opt_compress_extension: > > > - case Opt_nocompress_extension: > > > - case Opt_compress_chksum: > > > - case Opt_compress_mode: > > > - case Opt_compress_cache: > > > - f2fs_info(sbi, "compression options not supported"); > > > - break; > > > + case Opt_compress_algorithm: > > > + case Opt_compress_log_size: > > > + case Opt_compress_extension: > > > + case Opt_nocompress_extension: > > > + case Opt_compress_chksum: > > > + case Opt_compress_mode: > > > + case Opt_compress_cache: > > > + f2fs_info(sbi, "compression options not supported"); > > > + break; > > > #endif > > > - case Opt_atgc: > > > - set_opt(sbi, ATGC); > > > - break; > > > - case Opt_gc_merge: > > > - set_opt(sbi, GC_MERGE); > > > - break; > > > - case Opt_nogc_merge: > > > + case Opt_atgc: > > > + set_opt(sbi, ATGC); > > > + break; > > > + case Opt_gc_merge: > > > + if (result.negated) > > > clear_opt(sbi, GC_MERGE); > > > - break; > > > - case Opt_discard_unit: > > > - name = match_strdup(&args[0]); > > > - if (!name) > > > - return -ENOMEM; > > > - if (!strcmp(name, "block")) { > > > - F2FS_OPTION(sbi).discard_unit = > > > - DISCARD_UNIT_BLOCK; > > > - } else if (!strcmp(name, "segment")) { > > > - F2FS_OPTION(sbi).discard_unit = > > > - DISCARD_UNIT_SEGMENT; > > > - } else if (!strcmp(name, "section")) { > > > - F2FS_OPTION(sbi).discard_unit = > > > - DISCARD_UNIT_SECTION; > > > - } else { > > > - kfree(name); > > > - return -EINVAL; > > > - } > > > - kfree(name); > > > - break; > > > - case Opt_memory_mode: > > > - name = match_strdup(&args[0]); > > > - if (!name) > > > - return -ENOMEM; > > > - if (!strcmp(name, "normal")) { > > > - F2FS_OPTION(sbi).memory_mode = > > > - MEMORY_MODE_NORMAL; > > > - } else if (!strcmp(name, "low")) { > > > - F2FS_OPTION(sbi).memory_mode = > > > - MEMORY_MODE_LOW; > > > - } else { > > > - kfree(name); > > > - return -EINVAL; > > > - } > > > - kfree(name); > > > - break; > > > - case Opt_age_extent_cache: > > > - set_opt(sbi, AGE_EXTENT_CACHE); > > > - break; > > > - case Opt_errors: > > > - name = match_strdup(&args[0]); > > > - if (!name) > > > - return -ENOMEM; > > > - if (!strcmp(name, "remount-ro")) { > > > - F2FS_OPTION(sbi).errors = > > > - MOUNT_ERRORS_READONLY; > > > - } else if (!strcmp(name, "continue")) { > > > - F2FS_OPTION(sbi).errors = > > > - MOUNT_ERRORS_CONTINUE; > > > - } else if (!strcmp(name, "panic")) { > > > - F2FS_OPTION(sbi).errors = > > > - MOUNT_ERRORS_PANIC; > > > - } else { > > > - kfree(name); > > > - return -EINVAL; > > > + else > > > + set_opt(sbi, GC_MERGE); > > > + break; > > > + case Opt_discard_unit: > > > + F2FS_OPTION(sbi).discard_unit = result.uint_32; > > > + break; > > > + case Opt_memory_mode: > > > + F2FS_OPTION(sbi).memory_mode = result.uint_32; > > > + break; > > > + case Opt_age_extent_cache: > > > + set_opt(sbi, AGE_EXTENT_CACHE); > > > + break; > > > + case Opt_errors: > > > + F2FS_OPTION(sbi).errors = result.uint_32; > > > + break; > > > + case Opt_nat_bits: > > > + set_opt(sbi, NAT_BITS); > > > + break; > > > + } > > > + return 0; > > > +} > > > + > > > +static int parse_options(struct f2fs_sb_info *sbi, char *options, bool > > > is_remount) > > > +{ > > > + struct fs_parameter param; > > > + struct fs_context fc; > > > + char *key; > > > + int ret; > > > + > > > + if (!options) > > > + return 0; > > > + > > > + memset(&fc, 0, sizeof(fc)); > > > + fc.s_fs_info = sbi; > > > + if (is_remount) > > > + fc.purpose = FS_CONTEXT_FOR_RECONFIGURE; > > > + > > > + while ((key = strsep(&options, ",")) != NULL) { > > > + if (*key) { > > > + size_t v_len = 0; > > > + char *value = strchr(key, '='); > > > + > > > + param.type = fs_value_is_flag; > > > + param.string = NULL; > > > + > > > + if (value) { > > > + if (value == key) > > > + continue; > > > + > > > + *value++ = 0; > > > + v_len = strlen(value); > > > + param.string = kmemdup_nul(value, v_len, > > > GFP_KERNEL); > > > + if (!param.string) > > > + return -ENOMEM; > > > + param.type = fs_value_is_string; > > > } > > > - kfree(name); > > > - break; > > > - case Opt_nat_bits: > > > - set_opt(sbi, NAT_BITS); > > > - break; > > > - default: > > > - f2fs_err(sbi, "Unrecognized mount option \"%s\" or > > > missing value", > > > - p); > > > - return -EINVAL; > > > + > > > + param.key = key; > > > + param.size = v_len; > > > + > > > + ret = handle_mount_opt(&fc, ¶m); > > > + kfree(param.string); > > > + if (ret < 0) > > > + return ret; > > > } > > > } > > > return 0; > > > } > > > -static int f2fs_default_check(struct f2fs_sb_info *sbi) > > > +static int f2fs_validate_options(struct f2fs_sb_info *sbi) > > > { > > > #ifdef CONFIG_QUOTA > > > if (f2fs_check_quota_options(sbi)) > > > @@ -2527,7 +2285,7 @@ static int f2fs_remount(struct super_block *sb, int > > > *flags, char *data) > > > } > > > #endif > > > - err = f2fs_default_check(sbi); > > > + err = f2fs_validate_options(sbi); > > > if (err) > > > goto restore_opts; > > > @@ -4725,7 +4483,7 @@ static int f2fs_fill_super(struct super_block *sb, > > > void *data, int silent) > > > if (err) > > > goto free_options; > > > - err = f2fs_default_check(sbi); > > > + err = f2fs_validate_options(sbi); > > > if (err) > > > goto free_options; > > _______________________________________________ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel