Merge pull request #280 from giuseppe/rm-whiteout-symlink

main: mark directory not loaded on rename
This commit is contained in:
Daniel J Walsh 2021-03-05 14:22:40 -05:00 committed by GitHub
commit 1f1377d880
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 9 deletions

29
main.c
View File

@ -158,8 +158,6 @@ struct _uintptr_to_must_hold_fuse_ino_t_dummy_struct
};
#endif
static bool disable_ovl_whiteout;
static uid_t overflow_uid;
static gid_t overflow_gid;
@ -290,6 +288,12 @@ check_can_mknod (struct ovl_data *lo)
int ret;
char path[PATH_MAX];
if (getenv ("FUSE_OVERLAYFS_DISABLE_OVL_WHITEOUT"))
{
can_mknod = false;
return;
}
sprintf (path, "%lu", get_next_wd_counter ());
ret = mknodat (lo->workdir_fd, path, S_IFCHR|0700, makedev (0, 0));
@ -723,7 +727,7 @@ create_whiteout (struct ovl_data *lo, struct ovl_node *parent, const char *name,
return 0;
}
if (!disable_ovl_whiteout && !skip_mknod && can_mknod)
if (!skip_mknod && can_mknod)
{
char whiteout_path[PATH_MAX];
@ -4528,9 +4532,17 @@ ovl_rename_direct (fuse_req_t req, fuse_ino_t parent, const char *name,
/* Try to create the whiteout atomically, if it fails do the
rename+mknod separately. */
ret = direct_renameat2 (srcfd, name, destfd,
newname, flags|RENAME_WHITEOUT);
/* If the destination is a whiteout, just overwrite it. */
if (! can_mknod)
{
ret = -1;
errno = EPERM;
}
else
{
ret = direct_renameat2 (srcfd, name, destfd,
newname, flags|RENAME_WHITEOUT);
}
/* If the destination is a whiteout, just overwrite it. */
if (ret < 0 && errno == EEXIST)
ret = direct_renameat2 (srcfd, name, destfd, newname, flags & ~RENAME_NOREPLACE);
if (ret < 0)
@ -4543,6 +4555,8 @@ ovl_rename_direct (fuse_req_t req, fuse_ino_t parent, const char *name,
ret = create_whiteout (lo, pnode, name, false, true);
if (ret < 0)
goto error;
pnode->loaded = 0;
}
if (delete_whiteout (lo, destfd, NULL, newname) < 0)
@ -5468,9 +5482,6 @@ main (int argc, char *argv[])
struct ovl_layer *tmp_layer = NULL;
struct fuse_args args = FUSE_ARGS_INIT (argc, newargv);
if (getenv ("FUSE_OVERLAYFS_DISABLE_OVL_WHITEOUT"))
disable_ovl_whiteout = true;
memset (&opts, 0, sizeof (opts));
if (fuse_opt_parse (&args, &lo, ovl_opts, fuse_opt_proc) == -1)
error (EXIT_FAILURE, 0, "error parsing options");

View File

@ -211,3 +211,20 @@ touch merged/a merged/b
chmod 6 merged/a
mv merged/a merged/x
mv merged/b merged/a
# https://github.com/containers/fuse-overlayfs/issues/279
umount -l merged
rm -rf lower upper workdir merged
mkdir lower upper workdir merged
mkdir lower/test
touch lower/test/a.txt
fuse-overlayfs -o lowerdir=lower,upperdir=upper,workdir=workdir merged
(cd merged/test; touch a.txt; mv a.txt a2.txt; touch a3.txt; ln -s a3.txt a.txt)
if test -e upperdir/test/.wh.a.txt; then
echo "whiteout file still exists" >&2
exit 1
fi