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;
+}