forked from luck/tmp_suning_uos_patched
ovl: fix inconsistent d_ino for legacy merge dir
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@huawei.com> Reviewed-by: zhangyi (F) <yi.zhang@huawei.com> Signed-off-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
This commit is contained in:
parent
a5a927a7c8
commit
9678e63030
|
@ -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;
|
||||
|
|
|
@ -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++;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue
Block a user