]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - fs/overlayfs/readdir.c
Merge tag 'uuid-for-4.13-2' of git://git.infradead.org/users/hch/uuid
[linux.git] / fs / overlayfs / readdir.c
index f241b4ee3d8a50b1c03ae4b1e1848b772fd26af1..3d424a51cabbf7f1739f154c4d8a7b5616262029 100644 (file)
@@ -667,3 +667,56 @@ void ovl_workdir_cleanup(struct inode *dir, struct vfsmount *mnt,
                ovl_cleanup(dir, dentry);
        }
 }
+
+int ovl_indexdir_cleanup(struct dentry *dentry, struct vfsmount *mnt,
+                        struct path *lowerstack, unsigned int numlower)
+{
+       int err;
+       struct inode *dir = dentry->d_inode;
+       struct path path = { .mnt = mnt, .dentry = dentry };
+       LIST_HEAD(list);
+       struct ovl_cache_entry *p;
+       struct ovl_readdir_data rdd = {
+               .ctx.actor = ovl_fill_merge,
+               .dentry = NULL,
+               .list = &list,
+               .root = RB_ROOT,
+               .is_lowest = false,
+       };
+
+       err = ovl_dir_read(&path, &rdd);
+       if (err)
+               goto out;
+
+       inode_lock_nested(dir, I_MUTEX_PARENT);
+       list_for_each_entry(p, &list, l_node) {
+               struct dentry *index;
+
+               if (p->name[0] == '.') {
+                       if (p->len == 1)
+                               continue;
+                       if (p->len == 2 && p->name[1] == '.')
+                               continue;
+               }
+               index = lookup_one_len(p->name, dentry, p->len);
+               if (IS_ERR(index)) {
+                       err = PTR_ERR(index);
+                       break;
+               }
+               err = ovl_verify_index(index, lowerstack, numlower);
+               if (err) {
+                       if (err == -EROFS)
+                               break;
+                       err = ovl_cleanup(dir, index);
+                       if (err)
+                               break;
+               }
+               dput(index);
+       }
+       inode_unlock(dir);
+out:
+       ovl_cache_free(&list);
+       if (err)
+               pr_err("overlayfs: failed index dir cleanup (%i)\n", err);
+       return err;
+}