Commit 3011645b authored by Amir Goldstein's avatar Amir Goldstein Committed by Miklos Szeredi
Browse files

ovl: cleanup non-empty directories in ovl_indexdir_cleanup()



Teach ovl_indexdir_cleanup() to remove temp directories containing
whiteouts to prepare for using index dir instead of work dir for removing
merge directories.

Signed-off-by: default avatarAmir Goldstein <amir73il@gmail.com>
Signed-off-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
parent b0def88d
Loading
Loading
Loading
Loading
+0 −11
Original line number Diff line number Diff line
@@ -484,12 +484,6 @@ struct dentry *ovl_index_upper(struct ovl_fs *ofs, struct dentry *index)
	return upper;
}

/* Is this a leftover from create/whiteout of directory index entry? */
static bool ovl_is_temp_index(struct dentry *index)
{
	return index->d_name.name[0] == '#';
}

/*
 * Verify that an index entry name matches the origin file handle stored in
 * OVL_XATTR_ORIGIN and that origin file handle can be decoded to lower path.
@@ -507,11 +501,6 @@ int ovl_verify_index(struct ovl_fs *ofs, struct dentry *index)
	if (!d_inode(index))
		return 0;

	/* Cleanup leftover from index create/cleanup attempt */
	err = -ESTALE;
	if (ovl_is_temp_index(index))
		goto fail;

	err = -EINVAL;
	if (index->d_name.len < sizeof(struct ovl_fb)*2)
		goto fail;
+2 −2
Original line number Diff line number Diff line
@@ -394,7 +394,7 @@ void ovl_cleanup_whiteouts(struct dentry *upper, struct list_head *list);
void ovl_cache_free(struct list_head *list);
void ovl_dir_cache_free(struct inode *inode);
int ovl_check_d_type_supported(struct path *realpath);
void ovl_workdir_cleanup(struct inode *dir, struct vfsmount *mnt,
int ovl_workdir_cleanup(struct inode *dir, struct vfsmount *mnt,
			struct dentry *dentry, int level);
int ovl_indexdir_cleanup(struct ovl_fs *ofs);

+12 −4
Original line number Diff line number Diff line
@@ -1071,14 +1071,13 @@ out:
	ovl_cache_free(&list);
}

void ovl_workdir_cleanup(struct inode *dir, struct vfsmount *mnt,
int ovl_workdir_cleanup(struct inode *dir, struct vfsmount *mnt,
			 struct dentry *dentry, int level)
{
	int err;

	if (!d_is_dir(dentry) || level > 1) {
		ovl_cleanup(dir, dentry);
		return;
		return ovl_cleanup(dir, dentry);
	}

	err = ovl_do_rmdir(dir, dentry);
@@ -1088,8 +1087,10 @@ void ovl_workdir_cleanup(struct inode *dir, struct vfsmount *mnt,
		inode_unlock(dir);
		ovl_workdir_cleanup_recurse(&path, level + 1);
		inode_lock_nested(dir, I_MUTEX_PARENT);
		ovl_cleanup(dir, dentry);
		err = ovl_cleanup(dir, dentry);
	}

	return err;
}

int ovl_indexdir_cleanup(struct ovl_fs *ofs)
@@ -1128,6 +1129,13 @@ int ovl_indexdir_cleanup(struct ovl_fs *ofs)
			index = NULL;
			break;
		}
		/* Cleanup leftover from index create/cleanup attempt */
		if (index->d_name.name[0] == '#') {
			err = ovl_workdir_cleanup(dir, path.mnt, index, 1);
			if (err)
				break;
			goto next;
		}
		err = ovl_verify_index(ofs, index);
		if (!err) {
			goto next;