Skip to content

Commit

Permalink
ovl: don't remove non-empty opaque directory
Browse files Browse the repository at this point in the history
When removing an opaque directory we can't just call rmdir() to check for
emptiness, because the directory will need to be replaced with a whiteout.
The replacement is done with RENAME_EXCHANGE, which doesn't check
emptiness.

Solution is just to check emptiness by reading the directory.  In the
future we could add a new rename flag to check for emptiness even for
RENAME_EXCHANGE to optimize this case.

Reported-by: Vincent Batts <[email protected]>
Signed-off-by: Miklos Szeredi <[email protected]>
Tested-by: Jordi Pujol Palomer <[email protected]>
Fixes: 263b4a0 ("ovl: dont replace opaque dir")
Cc: <[email protected]> # v4.0+
  • Loading branch information
Miklos Szeredi committed May 14, 2015
1 parent 030bbdb commit d377c5e
Showing 1 changed file with 19 additions and 5 deletions.
24 changes: 19 additions & 5 deletions fs/overlayfs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -506,11 +506,25 @@ static int ovl_remove_and_whiteout(struct dentry *dentry, bool is_dir)
struct dentry *opaquedir = NULL;
int err;

if (is_dir && OVL_TYPE_MERGE_OR_LOWER(ovl_path_type(dentry))) {
opaquedir = ovl_check_empty_and_clear(dentry);
err = PTR_ERR(opaquedir);
if (IS_ERR(opaquedir))
goto out;
if (is_dir) {
if (OVL_TYPE_MERGE_OR_LOWER(ovl_path_type(dentry))) {
opaquedir = ovl_check_empty_and_clear(dentry);
err = PTR_ERR(opaquedir);
if (IS_ERR(opaquedir))
goto out;
} else {
LIST_HEAD(list);

/*
* When removing an empty opaque directory, then it
* makes no sense to replace it with an exact replica of
* itself. But emptiness still needs to be checked.
*/
err = ovl_check_empty_dir(dentry, &list);
ovl_cache_free(&list);
if (err)
goto out;
}
}

err = ovl_lock_rename_workdir(workdir, upperdir);
Expand Down

0 comments on commit d377c5e

Please sign in to comment.