Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9d7459d8 authored by Miklos Szeredi's avatar Miklos Szeredi
Browse files

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: default avatarMiklos Szeredi <mszeredi@suse.cz>
parent 5ef88da5
Loading
Loading
Loading
Loading
+21 −22
Original line number Diff line number Diff line
@@ -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)
{
	int err;
	struct path lowerpath;
	struct path upperpath;
	struct path realpath;
	struct ovl_readdir_data rdd = {
		.ctx.actor = ovl_fill_merge,
		.list = list,
		.root = RB_ROOT,
		.is_merge = false,
	};
	int idx, next;

	ovl_path_lower(dentry, &lowerpath);
	ovl_path_upper(dentry, &upperpath);
	for (idx = 0; idx != -1; idx = next) {
		next = ovl_path_next(idx, dentry, &realpath);

	if (upperpath.dentry) {
		rdd.dir = upperpath.dentry;
		err = ovl_dir_read(&upperpath, &rdd);
		if (next != -1) {
			rdd.dir = realpath.dentry;
			err = ovl_dir_read(&realpath, &rdd);
			if (err)
			goto out;
	}
	if (lowerpath.dentry) {
				break;
		} else {
			/*
		 * Insert lowerpath entries before upperpath ones, this allows
		 * offsets to be reasonably constant
			 * 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(&lowerpath, &rdd);
			err = ovl_dir_read(&realpath, &rdd);
			list_del(&rdd.middle);
		}
out:
	}
	return err;
}

+3 −0
Original line number Diff line number Diff line
@@ -81,6 +81,9 @@ enum ovl_path_type ovl_path_type(struct dentry *dentry)
		} else if (!oe->opaque) {
			type |= __OVL_PATH_PURE;
		}
	} else {
		if (oe->numlower > 1)
			type |= __OVL_PATH_MERGE;
	}
	return type;
}