ovl: cleanup bad and stale index entries on mount
Bad index entries are entries whose name does not match the origin file handle stored in trusted.overlay.origin xattr. Bad index entries could be a result of a system power off in the middle of copy up. Stale index entries are entries whose origin file handle is stale. Stale index entries could be a result of copying layers or removing lower entries while the overlay is not mounted. The case of copying layers should be detected earlier by the verification of upper root dir origin and index dir origin. Both bad and stale index entries are detected and removed on mount. Signed-off-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
This commit is contained in:

committed by
Miklos Szeredi

parent
359f392ca5
commit
415543d5c6
@@ -667,3 +667,53 @@ 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;
|
||||
}
|
||||
if (ovl_verify_index(index, lowerstack, numlower)) {
|
||||
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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user