diff options
-rw-r--r-- | fs/overlayfs/readdir.c | 35 |
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 | ||
277 | static inline int ovl_dir_read_merged(struct path *upperpath, | 277 | static 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 | } |
310 | out: | 313 | out: |
@@ -329,8 +332,6 @@ static void ovl_seek_cursor(struct ovl_dir_file *od, loff_t pos) | |||
329 | static struct ovl_dir_cache *ovl_cache_get(struct dentry *dentry) | 332 | static 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 = { | |||
538 | int ovl_check_empty_dir(struct dentry *dentry, struct list_head *list) | 536 | int 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 | ||