|
@@ -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 upperpath;
|
|
|
|
|
|
+ struct path realpath;
|
|
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,
|
|
};
|
|
};
|
|
-
|
|
|
|
- ovl_path_lower(dentry, &lowerpath);
|
|
|
|
- ovl_path_upper(dentry, &upperpath);
|
|
|
|
-
|
|
|
|
- if (upperpath.dentry) {
|
|
|
|
- rdd.dir = upperpath.dentry;
|
|
|
|
- err = ovl_dir_read(&upperpath, &rdd);
|
|
|
|
- if (err)
|
|
|
|
- goto out;
|
|
|
|
- }
|
|
|
|
- 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);
|
|
|
|
|
|
+ int idx, next;
|
|
|
|
+
|
|
|
|
+ for (idx = 0; idx != -1; idx = next) {
|
|
|
|
+ next = ovl_path_next(idx, dentry, &realpath);
|
|
|
|
+
|
|
|
|
+ if (next != -1) {
|
|
|
|
+ rdd.dir = realpath.dentry;
|
|
|
|
+ err = ovl_dir_read(&realpath, &rdd);
|
|
|
|
+ if (err)
|
|
|
|
+ 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);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
-out:
|
|
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|
|
|
|
|