Re: [PATCH] ovl: keep lockdep silent when nest iterate_dir calling of lowerdir

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

 



On Fri, Jun 26, 2015 at 10:04 AM,  <xuw2015@xxxxxxxxx> wrote:
> From: George Wang <xuw2015@xxxxxxxxx>
>
> If we use the overlayfs mount point as the lowerdir of another overlayfs, the
> ->iterate will be called nestly. It's just like overlayfs2->iterate will call
> overlayfs1->iterate when we ls the overlayfs2 items. We turn off the lockdep
> to avoid the false positive warning in this situation, and trun on the lockdep
> when it finished.
>
> The following procedure can reproduce it:
>
> mkdir 1 1_lower 1_upper 1_work 2 2_upper 2_work
> mount -t overlay overlay 1 -o lowerdir=1_lower,upperdir=1_upper,workdir=1_work
> mount -t overlay overlay 2 -o lowerdir=1,upperdir=2_upper,workdir=2_work
> ls 2
>
> Reported-by: Konstantin Khlebnikov <koct9i@xxxxxxxxx>
> Signed-off-by: George Wang <xuw2015@xxxxxxxxx>

I don't like this solution. It looks like a piece of duct tape.
Stacking several layers of overlayfs is useless. I think it safer to
forbid that setup.

> ---
>  fs/overlayfs/readdir.c | 29 +++++++++++++++++++++++++++--
>  1 file changed, 27 insertions(+), 2 deletions(-)
>
> diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c
> index 70e9af5..3f7f99b 100644
> --- a/fs/overlayfs/readdir.c
> +++ b/fs/overlayfs/readdir.c
> @@ -236,6 +236,31 @@ static int ovl_check_whiteouts(struct dentry *dir, struct ovl_readdir_data *rdd)
>         return err;
>  }
>
> +/*
> + * If we use overlayfs as lower, the iterate_dir will be nest. This will
> + * trigger the lockdep deadlock warning, but actually, this is not deadlock.
> + * No one wants to see false positive warnings, so we use this wrapper
> + * function to keep silent in this situation.
> + */
> +static inline int iterate_dir_silent(struct file *dir, struct dir_context *ctx)
> +{
> +    extern const struct file_operations ovl_dir_operations;
> +    int err = 0;
> +    int off = 0;
> +
> +    if (dir->f_op == &ovl_dir_operations) {
> +        lockdep_off();
> +        off = 1;
> +    }
> +
> +    err = iterate_dir(dir, ctx);
> +
> +    if (off)
> +        lockdep_on();
> +
> +    return err;
> +}
> +
>  static inline int ovl_dir_read(struct path *realpath,
>                                struct ovl_readdir_data *rdd)
>  {
> @@ -251,7 +276,7 @@ static inline int ovl_dir_read(struct path *realpath,
>         do {
>                 rdd->count = 0;
>                 rdd->err = 0;
> -               err = iterate_dir(realfile, &rdd->ctx);
> +               err = iterate_dir_silent(realfile, &rdd->ctx);
>                 if (err >= 0)
>                         err = rdd->err;
>         } while (!err && rdd->count);
> @@ -370,7 +395,7 @@ static int ovl_iterate(struct file *file, struct dir_context *ctx)
>                 ovl_dir_reset(file);
>
>         if (od->is_real)
> -               return iterate_dir(od->realfile, ctx);
> +               return iterate_dir_silent(od->realfile, ctx);
>
>         if (!od->cache) {
>                 struct ovl_dir_cache *cache;
> --
> 1.8.3.1
>
--
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