diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/overlayfs/readdir.c | 43 | ||||
-rw-r--r-- | fs/overlayfs/super.c | 3 |
2 files changed, 24 insertions, 22 deletions
diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c index 481e44873b65..dfef6ca53dfe 100644 --- a/fs/overlayfs/readdir.c +++ b/fs/overlayfs/readdir.c | |||
@@ -261,35 +261,34 @@ static void ovl_dir_reset(struct file *file) | |||
261 | static int ovl_dir_read_merged(struct dentry *dentry, struct list_head *list) | 261 | static int ovl_dir_read_merged(struct dentry *dentry, struct list_head *list) |
262 | { | 262 | { |
263 | int err; | 263 | int err; |
264 | struct path lowerpath; | 264 | struct path realpath; |
265 | struct path upperpath; | ||
266 | struct ovl_readdir_data rdd = { | 265 | struct ovl_readdir_data rdd = { |
267 | .ctx.actor = ovl_fill_merge, | 266 | .ctx.actor = ovl_fill_merge, |
268 | .list = list, | 267 | .list = list, |
269 | .root = RB_ROOT, | 268 | .root = RB_ROOT, |
270 | .is_merge = false, | 269 | .is_merge = false, |
271 | }; | 270 | }; |
272 | 271 | int idx, next; | |
273 | ovl_path_lower(dentry, &lowerpath); | 272 | |
274 | ovl_path_upper(dentry, &upperpath); | 273 | for (idx = 0; idx != -1; idx = next) { |
275 | 274 | next = ovl_path_next(idx, dentry, &realpath); | |
276 | if (upperpath.dentry) { | 275 | |
277 | rdd.dir = upperpath.dentry; | 276 | if (next != -1) { |
278 | err = ovl_dir_read(&upperpath, &rdd); | 277 | rdd.dir = realpath.dentry; |
279 | if (err) | 278 | err = ovl_dir_read(&realpath, &rdd); |
280 | goto out; | 279 | if (err) |
281 | } | 280 | break; |
282 | if (lowerpath.dentry) { | 281 | } else { |
283 | /* | 282 | /* |
284 | * Insert lowerpath entries before upperpath ones, this allows | 283 | * Insert lowest layer entries before upper ones, this |
285 | * offsets to be reasonably constant | 284 | * allows offsets to be reasonably constant |
286 | */ | 285 | */ |
287 | list_add(&rdd.middle, rdd.list); | 286 | list_add(&rdd.middle, rdd.list); |
288 | rdd.is_merge = true; | 287 | rdd.is_merge = true; |
289 | err = ovl_dir_read(&lowerpath, &rdd); | 288 | err = ovl_dir_read(&realpath, &rdd); |
290 | list_del(&rdd.middle); | 289 | list_del(&rdd.middle); |
290 | } | ||
291 | } | 291 | } |
292 | out: | ||
293 | return err; | 292 | return err; |
294 | } | 293 | } |
295 | 294 | ||
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index 07e4c576e93e..c245043aa1b9 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c | |||
@@ -81,6 +81,9 @@ enum ovl_path_type ovl_path_type(struct dentry *dentry) | |||
81 | } else if (!oe->opaque) { | 81 | } else if (!oe->opaque) { |
82 | type |= __OVL_PATH_PURE; | 82 | type |= __OVL_PATH_PURE; |
83 | } | 83 | } |
84 | } else { | ||
85 | if (oe->numlower > 1) | ||
86 | type |= __OVL_PATH_MERGE; | ||
84 | } | 87 | } |
85 | return type; | 88 | return type; |
86 | } | 89 | } |