aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/overlayfs/readdir.c35
1 files changed, 14 insertions, 21 deletions
diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c
index 2a7ef4f8e2a6..7299e962f334 100644
--- a/fs/overlayfs/readdir.c
+++ b/fs/overlayfs/readdir.c
@@ -274,11 +274,11 @@ static int ovl_dir_mark_whiteouts(struct dentry *dir,
274 return 0; 274 return 0;
275} 275}
276 276
277static inline int ovl_dir_read_merged(struct path *upperpath, 277static int ovl_dir_read_merged(struct dentry *dentry, struct list_head *list)
278 struct path *lowerpath,
279 struct list_head *list)
280{ 278{
281 int err; 279 int err;
280 struct path lowerpath;
281 struct path upperpath;
282 struct ovl_readdir_data rdd = { 282 struct ovl_readdir_data rdd = {
283 .ctx.actor = ovl_fill_merge, 283 .ctx.actor = ovl_fill_merge,
284 .list = list, 284 .list = list,
@@ -286,25 +286,28 @@ static inline int ovl_dir_read_merged(struct path *upperpath,
286 .is_merge = false, 286 .is_merge = false,
287 }; 287 };
288 288
289 if (upperpath->dentry) { 289 ovl_path_lower(dentry, &lowerpath);
290 err = ovl_dir_read(upperpath, &rdd); 290 ovl_path_upper(dentry, &upperpath);
291
292 if (upperpath.dentry) {
293 err = ovl_dir_read(&upperpath, &rdd);
291 if (err) 294 if (err)
292 goto out; 295 goto out;
293 296
294 if (lowerpath->dentry) { 297 if (lowerpath.dentry) {
295 err = ovl_dir_mark_whiteouts(upperpath->dentry, &rdd); 298 err = ovl_dir_mark_whiteouts(upperpath.dentry, &rdd);
296 if (err) 299 if (err)
297 goto out; 300 goto out;
298 } 301 }
299 } 302 }
300 if (lowerpath->dentry) { 303 if (lowerpath.dentry) {
301 /* 304 /*
302 * Insert lowerpath entries before upperpath ones, this allows 305 * Insert lowerpath entries before upperpath ones, this allows
303 * offsets to be reasonably constant 306 * offsets to be reasonably constant
304 */ 307 */
305 list_add(&rdd.middle, rdd.list); 308 list_add(&rdd.middle, rdd.list);
306 rdd.is_merge = true; 309 rdd.is_merge = true;
307 err = ovl_dir_read(lowerpath, &rdd); 310 err = ovl_dir_read(&lowerpath, &rdd);
308 list_del(&rdd.middle); 311 list_del(&rdd.middle);
309 } 312 }
310out: 313out:
@@ -329,8 +332,6 @@ static void ovl_seek_cursor(struct ovl_dir_file *od, loff_t pos)
329static struct ovl_dir_cache *ovl_cache_get(struct dentry *dentry) 332static struct ovl_dir_cache *ovl_cache_get(struct dentry *dentry)
330{ 333{
331 int res; 334 int res;
332 struct path lowerpath;
333 struct path upperpath;
334 struct ovl_dir_cache *cache; 335 struct ovl_dir_cache *cache;
335 336
336 cache = ovl_dir_cache(dentry); 337 cache = ovl_dir_cache(dentry);
@@ -347,10 +348,7 @@ static struct ovl_dir_cache *ovl_cache_get(struct dentry *dentry)
347 cache->refcount = 1; 348 cache->refcount = 1;
348 INIT_LIST_HEAD(&cache->entries); 349 INIT_LIST_HEAD(&cache->entries);
349 350
350 ovl_path_lower(dentry, &lowerpath); 351 res = ovl_dir_read_merged(dentry, &cache->entries);
351 ovl_path_upper(dentry, &upperpath);
352
353 res = ovl_dir_read_merged(&upperpath, &lowerpath, &cache->entries);
354 if (res) { 352 if (res) {
355 ovl_cache_free(&cache->entries); 353 ovl_cache_free(&cache->entries);
356 kfree(cache); 354 kfree(cache);
@@ -538,14 +536,9 @@ const struct file_operations ovl_dir_operations = {
538int ovl_check_empty_dir(struct dentry *dentry, struct list_head *list) 536int ovl_check_empty_dir(struct dentry *dentry, struct list_head *list)
539{ 537{
540 int err; 538 int err;
541 struct path lowerpath;
542 struct path upperpath;
543 struct ovl_cache_entry *p; 539 struct ovl_cache_entry *p;
544 540
545 ovl_path_upper(dentry, &upperpath); 541 err = ovl_dir_read_merged(dentry, list);
546 ovl_path_lower(dentry, &lowerpath);
547
548 err = ovl_dir_read_merged(&upperpath, &lowerpath, list);
549 if (err) 542 if (err)
550 return err; 543 return err;
551 544