ovl: mark upper dir with type origin entries "impure"

When moving a merge dir or non-dir with copy up origin into a non-merge
upper dir (a.k.a pure upper dir), we are marking the target parent dir
"impure". ovl_iterate() iterates pure upper dirs directly, because there is
no need to filter out whiteouts and merge dir content with lower dir. But
for the case of an "impure" upper dir, ovl_iterate() will not be able to
iterate the real upper dir directly, because it will need to lookup the
origin inode and use it to fill d_ino.

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
This commit is contained in:
Amir Goldstein
2017-05-11 16:42:26 +03:00
committed by Miklos Szeredi
orang tua 3d27573ce3
melakukan ee1d6d37b6
5 mengubah file dengan 79 tambahan dan 2 penghapusan

Melihat File

@@ -167,7 +167,7 @@ invalid:
goto out;
}
static bool ovl_is_opaquedir(struct dentry *dentry)
static bool ovl_check_dir_xattr(struct dentry *dentry, const char *name)
{
int res;
char val;
@@ -175,13 +175,23 @@ static bool ovl_is_opaquedir(struct dentry *dentry)
if (!d_is_dir(dentry))
return false;
res = vfs_getxattr(dentry, OVL_XATTR_OPAQUE, &val, 1);
res = vfs_getxattr(dentry, name, &val, 1);
if (res == 1 && val == 'y')
return true;
return false;
}
static bool ovl_is_opaquedir(struct dentry *dentry)
{
return ovl_check_dir_xattr(dentry, OVL_XATTR_OPAQUE);
}
static bool ovl_is_impuredir(struct dentry *dentry)
{
return ovl_check_dir_xattr(dentry, OVL_XATTR_IMPURE);
}
static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d,
const char *name, unsigned int namelen,
size_t prelen, const char *post,
@@ -351,6 +361,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
unsigned int ctr = 0;
struct inode *inode = NULL;
bool upperopaque = false;
bool upperimpure = false;
char *upperredirect = NULL;
struct dentry *this;
unsigned int i;
@@ -395,6 +406,8 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
poe = roe;
}
upperopaque = d.opaque;
if (upperdentry && d.is_dir)
upperimpure = ovl_is_impuredir(upperdentry);
}
if (!d.stop && poe->numlower) {
@@ -463,6 +476,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
revert_creds(old_cred);
oe->opaque = upperopaque;
oe->impure = upperimpure;
oe->redirect = upperredirect;
oe->__upperdentry = upperdentry;
memcpy(oe->lowerstack, stack, sizeof(struct path) * ctr);