Re: [PATCH v2 1/2] ovl: add option parsing support for remount

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



在 2018年4月4日,下午6:44,Amir Goldstein <amir73il@xxxxxxxxx> 写道:
> 
> On Wed, Apr 4, 2018 at 12:27 PM, Chengguang Xu <cgxu519@xxxxxxx> wrote:
>> Some overlayfs mount options cannot be changed via remount,
>> but remount operation does not return proper error even if
>> we specify different value to unchangeable options.
>> 
>> This patch add option parsing support for remount so we can
>> recogonize unchangeable options in remount.
>> 
>> Signed-off-by: Chengguang Xu <cgxu519@xxxxxxx>
>> ---
>> 
>> Changes since v1:
>> - Add remount option validation to parse_opt()
>> 
>> fs/overlayfs/super.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++---
>> 1 file changed, 127 insertions(+), 6 deletions(-)
>> 
>> diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
>> index 7c24619..4112720 100644
>> --- a/fs/overlayfs/super.c
>> +++ b/fs/overlayfs/super.c
>> @@ -425,6 +425,16 @@ static char *ovl_next_opt(char **s)
>> 
>> static int ovl_parse_redirect_mode(struct ovl_config *config, const char *mode)
>> {
>> +
>> +       if (!mode) {
>> +               config->redirect_mode = kstrdup(ovl_redirect_mode_def(),
>> +                                                       GFP_KERNEL);
>> +               if (!config->redirect_mode)
>> +                       return -ENOMEM;
>> +
>> +               mode = config->redirect_mode;
>> +       }
> 
> This makes @mode argument to function redundant.

Maybe moving default initialization before calling parse_opt() is better, 
what do you think?


> 
>> +
>>        if (strcmp(mode, "on") == 0) {
>>                config->redirect_dir = true;
>>                /*
>> @@ -446,13 +456,49 @@ static int ovl_parse_redirect_mode(struct ovl_config *config, const char *mode)
>>        return 0;
>> }
>> 
>> -static int ovl_parse_opt(char *opt, struct ovl_config *config)
>> +static char *ovl_token_to_string(int token)
>> {
>> -       char *p;
>> +       switch (token) {
>> +       case OPT_UPPERDIR: return "upperdir";
>> +       case OPT_LOWERDIR: return "lowerdir";
>> +       case OPT_WORKDIR: return "workdir";
>> +       case OPT_DEFAULT_PERMISSIONS: return "default_permissions";
>> +       case OPT_REDIRECT_DIR: return "redirect_dir";
>> +       case OPT_INDEX_ON:
>> +       case OPT_INDEX_OFF: return "index";
>> +       case OPT_NFS_EXPORT_ON:
>> +       case OPT_NFS_EXPORT_OFF: return "nfs_export";
>> +       default: return "???";
>> +       }
>> +}
> 
> You don't need this. The option name is available in args[0]
> variable when calling the parsing macros and I don't think
> you need to bother with stripping the =xxx part.
> 
>> 
>> -       config->redirect_mode = kstrdup(ovl_redirect_mode_def(), GFP_KERNEL);
>> -       if (!config->redirect_mode)
>> -               return -ENOMEM;
>> +static int ovl_valid_remount_string_option(int token, const char *new,
>> +                                               const char *old)
>> +{
>> +       if (!old || strcmp(new, old)) {
>> +               pr_err("overlayfs: option %s cannot be changed on remount.\n",
>> +                               ovl_token_to_string(token));
>> +               return -EINVAL;
>> +       }
>> +       return 0;
>> +}
>> +
>> +static int ovl_valid_remount_bool_option(int token, const bool new,
>> +                                               const bool old)
>> +{
>> +       if (new != old) {
>> +               pr_err("overlayfs: option %s cannot be changed on remount.\n",
>> +                               ovl_token_to_string(token));
>> +               return -EINVAL;
>> +       }
>> +       return 0;
>> +}
>> +
>> +static int ovl_parse_opt(char *opt, struct ovl_config *config,
>> +                                       struct ovl_config *old_config)
>> +{
>> +       char *p;
>> +       int err;
>> 
>>        while ((p = ovl_next_opt(&opt)) != NULL) {
>>                int token;
>> @@ -468,6 +514,14 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
>>                        config->upperdir = match_strdup(&args[0]);
>>                        if (!config->upperdir)
>>                                return -ENOMEM;
>> +                       if (old_config) {
>> +                               err = ovl_valid_remount_string_option(
>> +                                       token,
>> +                                       config->upperdir,
>> +                                       old_config->upperdir);
>> +                               if (err)
>> +                                       return err;
>> +                       }
> 
> Brevity: instead of adding 8 lines to each case, you can squeeze the entire
> handling of string option to a single macro, e.g.:
> 
>        err = (ovl_parse_string_option(upperdir, &args[0], config, oldconfig);
>        if (err)
>            return err;
> 
> Same for ovl_parse_bool_option.
> 
> Later, when you want to introduce an option that could be changed
> on remount or only changed from NULL, just add new macro flavors:
> 
> ovl_parse_remount_[string|bool]_option
> ovl_parse_test_and_remount_[string|bool]_option
> 
> Let me know if you are not clear on how.

OK, I’ll make the code looks more concise, but I still hope to put all related
checking logic inside remount and just keep parse_opt as simple as possible.
Because parse_opt also calls from mount and I think validating related options
in one place will be simpler.


Thanks,
Chengguang.



--
To unsubscribe from this list: send the line "unsubscribe linux-unionfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Filesystems Devel]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux