Re: [PATCH v2] ovl: check for incomapt features in work dir

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

 



On Sun, Aug 30, 2020 at 10:28 PM Amir Goldstein <amir73il@xxxxxxxxx> wrote:
>
> An incompatible feature is marked by a non-empty directory nested
> 2 levels deep under "work" dir, e.g.:
> workdir/work/incompat/volatile.
>
> This commit checks for marked incompat features, warns about them
> and fails to mount the overlay, for example:
>   overlayfs: overlay with incompat feature 'volatile' cannot be mounted
>
> Very old kernels (i.e. v3.18) will fail to remove a non-empty "work"
> dir and fail the mount.  Newer kernels will fail to remove a "work"
> dir with entries nested 3 levels and fall back to read-only mount.
>
> User mounting with old kernel will see a warning like these in dmesg:
>   overlayfs: cleanup of 'incompat/...' failed (-39)
>   overlayfs: cleanup of 'work/incompat' failed (-39)
>   overlayfs: cleanup of 'ovl-work/work' failed (-39)
>   overlayfs: failed to create directory /vdf/ovl-work/work (errno: 17);
>              mounting read-only
>
> These warnings should give the hint to the user that:
> 1. mount failure is caused by backward incompatible features
> 2. mount failure can be resolved by manually removing the "work" directory
>
> There is nothing preventing users on old kernels from manually removing
> workdir entirely or mounting overlay with a new workdir, so this is in
> no way a full proof backward compatibility enforcement, but only a best
> effort.
>
> Signed-off-by: Amir Goldstein <amir73il@xxxxxxxxx>
> ---
>
> Vivek,
>
> Re-posting with minor cleanups.
> Also pushed to branch ovl-incompat.
>
> Thanks,
> Amir.
>
> Changes since v1:
> - Move check for "incompat" name to ovl_workdir_cleanup_recurse()
>
>
>  fs/overlayfs/readdir.c | 30 +++++++++++++++++++++++++-----
>  fs/overlayfs/super.c   | 25 ++++++++++++++++++-------
>  2 files changed, 43 insertions(+), 12 deletions(-)
>
> diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c
> index 6918b98faeb6..683c6f27ab77 100644
> --- a/fs/overlayfs/readdir.c
> +++ b/fs/overlayfs/readdir.c
> @@ -1051,7 +1051,9 @@ int ovl_check_d_type_supported(struct path *realpath)
>         return rdd.d_type_supported;
>  }
>
> -static void ovl_workdir_cleanup_recurse(struct path *path, int level)
> +#define OVL_INCOMPATDIR_NAME "incompat"
> +
> +static int ovl_workdir_cleanup_recurse(struct path *path, int level)
>  {
>         int err;
>         struct inode *dir = path->dentry->d_inode;
> @@ -1065,6 +1067,15 @@ static void ovl_workdir_cleanup_recurse(struct path *path, int level)
>                 .root = &root,
>                 .is_lowest = false,
>         };
> +       bool incompat = false;
> +
> +       /*
> +        * The "work/incompat" directory is treated specially - if it is not
> +        * empty, instead of printing a generic error and mounting read-only,
> +        * we will error about incompat features and fail the mount.
> +        */
> +       if (level == 2 && !strcmp(path->dentry->d_name.name, OVL_INCOMPATDIR_NAME))
> +               incompat = true;

Should the test be specific to "work/incompat"?  AFAICS this will
trigger under "index" as well...

>
>         err = ovl_dir_read(path, &rdd);
>         if (err)
> @@ -1079,21 +1090,29 @@ static void ovl_workdir_cleanup_recurse(struct path *path, int level)
>                                 continue;
>                         if (p->len == 2 && p->name[1] == '.')
>                                 continue;
> +               } else if (incompat) {
> +                       pr_warn("overlay with incompat feature '%.*s' cannot be mounted\n",
> +                               p->len, p->name);
> +                       err = -EEXIST;

EEXIST feels counterintuitive.  I'd rather opt for EINVAL.

Thanks,
Miklos



[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