aboutsummaryrefslogtreecommitdiffstats
path: root/fs/overlayfs/export.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/overlayfs/export.c')
-rw-r--r--fs/overlayfs/export.c41
1 files changed, 21 insertions, 20 deletions
diff --git a/fs/overlayfs/export.c b/fs/overlayfs/export.c
index defd4e231ad2..35680b6e175b 100644
--- a/fs/overlayfs/export.c
+++ b/fs/overlayfs/export.c
@@ -80,7 +80,7 @@ static int ovl_connectable_layer(struct dentry *dentry)
/* We can get overlay root from root of any layer */
if (dentry == dentry->d_sb->s_root)
- return oe->numlower;
+ return ovl_numlower(oe);
/*
* If it's an unindexed merge dir, then it's not connectable with any
@@ -91,7 +91,7 @@ static int ovl_connectable_layer(struct dentry *dentry)
return 0;
/* We can get upper/overlay path from indexed/lower dentry */
- return oe->lowerstack[0].layer->idx;
+ return ovl_lowerstack(oe)->layer->idx;
}
/*
@@ -105,6 +105,7 @@ static int ovl_connectable_layer(struct dentry *dentry)
static int ovl_connect_layer(struct dentry *dentry)
{
struct dentry *next, *parent = NULL;
+ struct ovl_entry *oe = OVL_E(dentry);
int origin_layer;
int err = 0;
@@ -112,7 +113,7 @@ static int ovl_connect_layer(struct dentry *dentry)
WARN_ON(!ovl_dentry_lower(dentry)))
return -EIO;
- origin_layer = OVL_E(dentry)->lowerstack[0].layer->idx;
+ origin_layer = ovl_lowerstack(oe)->layer->idx;
if (ovl_dentry_test_flag(OVL_E_CONNECTED, dentry))
return origin_layer;
@@ -285,21 +286,29 @@ static struct dentry *ovl_obtain_alias(struct super_block *sb,
struct dentry *lower = lowerpath ? lowerpath->dentry : NULL;
struct dentry *upper = upper_alias ?: index;
struct dentry *dentry;
- struct inode *inode;
+ struct inode *inode = NULL;
struct ovl_entry *oe;
struct ovl_inode_params oip = {
- .lowerpath = lowerpath,
.index = index,
- .numlower = !!lower
};
/* We get overlay directory dentries with ovl_lookup_real() */
if (d_is_dir(upper ?: lower))
return ERR_PTR(-EIO);
+ oe = ovl_alloc_entry(!!lower);
+ if (!oe)
+ return ERR_PTR(-ENOMEM);
+
oip.upperdentry = dget(upper);
+ if (lower) {
+ ovl_lowerstack(oe)->dentry = dget(lower);
+ ovl_lowerstack(oe)->layer = lowerpath->layer;
+ }
+ oip.oe = oe;
inode = ovl_get_inode(sb, &oip);
if (IS_ERR(inode)) {
+ ovl_free_entry(oe);
dput(upper);
return ERR_CAST(inode);
}
@@ -314,20 +323,11 @@ static struct dentry *ovl_obtain_alias(struct super_block *sb,
dentry = d_alloc_anon(inode->i_sb);
if (unlikely(!dentry))
goto nomem;
- oe = ovl_alloc_entry(lower ? 1 : 0);
- if (!oe)
- goto nomem;
- if (lower) {
- oe->lowerstack->dentry = dget(lower);
- oe->lowerstack->layer = lowerpath->layer;
- }
- dentry->d_fsdata = oe;
if (upper_alias)
ovl_dentry_set_upper_alias(dentry);
- ovl_dentry_update_reval(dentry, upper,
- DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE);
+ ovl_dentry_init_reval(dentry, upper, OVL_I_E(inode));
return d_instantiate_anon(dentry, inode);
@@ -342,15 +342,16 @@ out_iput:
/* Get the upper or lower dentry in stack whose on layer @idx */
static struct dentry *ovl_dentry_real_at(struct dentry *dentry, int idx)
{
- struct ovl_entry *oe = dentry->d_fsdata;
+ struct ovl_entry *oe = OVL_E(dentry);
+ struct ovl_path *lowerstack = ovl_lowerstack(oe);
int i;
if (!idx)
return ovl_dentry_upper(dentry);
- for (i = 0; i < oe->numlower; i++) {
- if (oe->lowerstack[i].layer->idx == idx)
- return oe->lowerstack[i].dentry;
+ for (i = 0; i < ovl_numlower(oe); i++) {
+ if (lowerstack[i].layer->idx == idx)
+ return lowerstack[i].dentry;
}
return NULL;