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:
committed by
Miklos Szeredi
parent
a5a927a7c8
commit
9678e63030
@@ -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++;
|
||||
|
||||
Reference in New Issue
Block a user