Re: [PATCH v2] ovl: fix inconsistent d_ino for legacy merge dir

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

 



On 2018/1/4 3:56, Amir Goldstein Wrote:
> For a merge dir that was copied up before v4.12 or that was hand crafted
> offline (e.g. mkdir {upper/lower}/dir), upper dir does not contain the
> 'trusted.overlay.origin' xattr.  In that case, stat(2) on the merge dir
> returns the lower dir st_ino, but getdents(2) returns the upper dir d_ino.
> 
> After this change, on merge dir lookup, missing origin xattr on upper
> dir will be fixed and 'impure' xattr will be fixed on parent of the legacy
> merge dir.
> 
> Suggested-by: zhangyi (F) <yi.zhang@xxxxxxxxxx>
> Signed-off-by: Amir Goldstein <amir73il@xxxxxxxxx>
> ---
> 
> Zhangyi,
> 
> A slightly differnt patch. This time with ovl_want_write()
> and using different helpers.
> 
> Please re-review and test.
> 

Looks good to me.

Reviewed-by: zhangyi (F) <yi.zhang@xxxxxxxxxx>

> Thanks,
> Amir.
> 
>  fs/overlayfs/copy_up.c   |  4 ++--
>  fs/overlayfs/namei.c     | 33 +++++++++++++++++++++++++++++++++
>  fs/overlayfs/overlayfs.h |  2 ++
>  3 files changed, 37 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
> index eb3b8d39fb61..206ececd5ae7 100644
> --- a/fs/overlayfs/copy_up.c
> +++ b/fs/overlayfs/copy_up.c
> @@ -288,8 +288,8 @@ struct ovl_fh *ovl_encode_fh(struct dentry *lower, bool is_upper)
>  	return fh;
>  }
>  
> -static int ovl_set_origin(struct dentry *dentry, struct dentry *lower,
> -			  struct dentry *upper)
> +int ovl_set_origin(struct dentry *dentry, struct dentry *lower,
> +		   struct dentry *upper)
>  {
>  	const struct ovl_fh *fh = NULL;
>  	int err;
> diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c
> index 9cf15463754c..71db9a966d88 100644
> --- a/fs/overlayfs/namei.c
> +++ b/fs/overlayfs/namei.c
> @@ -584,6 +584,27 @@ static int ovl_find_layer(struct ovl_fs *ofs, struct ovl_path *path)
>  	return i;
>  }
>  
> +/* Fix missing 'origin' xattr */
> +static int ovl_fix_origin(struct dentry *dentry, struct dentry *lower,
> +			  struct dentry *upper)
> +{
> +	int err;
> +
> +	if (ovl_check_origin_xattr(upper))
> +		return 0;
> +
> +	err = ovl_want_write(dentry);
> +	if (err)
> +		return err;
> +
> +	err = ovl_set_origin(dentry, lower, upper);
> +	if (!err)
> +		err = ovl_set_impure(dentry->d_parent, upper->d_parent);
> +
> +	ovl_drop_write(dentry);
> +	return err;
> +}
> +
>  struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
>  			  unsigned int flags)
>  {
> @@ -674,6 +695,18 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
>  		if (!this)
>  			continue;
>  
> +		/*
> +		 * If no origin fh is stored in upper of a merge dir, store fh
> +		 * of lower dir and set upper parent "impure".
> +		 */
> +		if (upperdentry && !ctr && !ofs->noxattr) {
> +			err = ovl_fix_origin(dentry, this, upperdentry);
> +			if (err) {
> +				dput(this);
> +				goto out_put;
> +			}
> +		}
> +
>  		stack[ctr].dentry = this;
>  		stack[ctr].layer = lower.layer;
>  		ctr++;
> diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
> index b489099ccd49..d1cfa69c98b5 100644
> --- a/fs/overlayfs/overlayfs.h
> +++ b/fs/overlayfs/overlayfs.h
> @@ -322,3 +322,5 @@ int ovl_copy_up_flags(struct dentry *dentry, int flags);
>  int ovl_copy_xattr(struct dentry *old, struct dentry *new);
>  int ovl_set_attr(struct dentry *upper, struct kstat *stat);
>  struct ovl_fh *ovl_encode_fh(struct dentry *lower, bool is_upper);
> +int ovl_set_origin(struct dentry *dentry, struct dentry *lower,
> +		   struct dentry *upper);
> 

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