mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-18 22:14:16 +00:00
ovl: multi-layer readdir
If multiple lower layers exist, merge them as well in readdir according to the same rules as merging upper with lower. I.e. take whiteouts and opaque directories into account on all but the lowers layer. Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
This commit is contained in:
parent
5ef88da56a
commit
9d7459d834
2 changed files with 22 additions and 20 deletions
|
@ -261,35 +261,34 @@ static void ovl_dir_reset(struct file *file)
|
||||||
static int ovl_dir_read_merged(struct dentry *dentry, struct list_head *list)
|
static int ovl_dir_read_merged(struct dentry *dentry, struct list_head *list)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
struct path lowerpath;
|
struct path realpath;
|
||||||
struct path upperpath;
|
|
||||||
struct ovl_readdir_data rdd = {
|
struct ovl_readdir_data rdd = {
|
||||||
.ctx.actor = ovl_fill_merge,
|
.ctx.actor = ovl_fill_merge,
|
||||||
.list = list,
|
.list = list,
|
||||||
.root = RB_ROOT,
|
.root = RB_ROOT,
|
||||||
.is_merge = false,
|
.is_merge = false,
|
||||||
};
|
};
|
||||||
|
int idx, next;
|
||||||
|
|
||||||
ovl_path_lower(dentry, &lowerpath);
|
for (idx = 0; idx != -1; idx = next) {
|
||||||
ovl_path_upper(dentry, &upperpath);
|
next = ovl_path_next(idx, dentry, &realpath);
|
||||||
|
|
||||||
if (upperpath.dentry) {
|
if (next != -1) {
|
||||||
rdd.dir = upperpath.dentry;
|
rdd.dir = realpath.dentry;
|
||||||
err = ovl_dir_read(&upperpath, &rdd);
|
err = ovl_dir_read(&realpath, &rdd);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
break;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Insert lowest layer entries before upper ones, this
|
||||||
|
* allows offsets to be reasonably constant
|
||||||
|
*/
|
||||||
|
list_add(&rdd.middle, rdd.list);
|
||||||
|
rdd.is_merge = true;
|
||||||
|
err = ovl_dir_read(&realpath, &rdd);
|
||||||
|
list_del(&rdd.middle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (lowerpath.dentry) {
|
|
||||||
/*
|
|
||||||
* Insert lowerpath entries before upperpath ones, this allows
|
|
||||||
* offsets to be reasonably constant
|
|
||||||
*/
|
|
||||||
list_add(&rdd.middle, rdd.list);
|
|
||||||
rdd.is_merge = true;
|
|
||||||
err = ovl_dir_read(&lowerpath, &rdd);
|
|
||||||
list_del(&rdd.middle);
|
|
||||||
}
|
|
||||||
out:
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,6 +81,9 @@ enum ovl_path_type ovl_path_type(struct dentry *dentry)
|
||||||
} else if (!oe->opaque) {
|
} else if (!oe->opaque) {
|
||||||
type |= __OVL_PATH_PURE;
|
type |= __OVL_PATH_PURE;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (oe->numlower > 1)
|
||||||
|
type |= __OVL_PATH_MERGE;
|
||||||
}
|
}
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue