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

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

 



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.

> +
>         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.

Thanks,
Amir.
--
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