Merge pull request #25 from giuseppe/fix-wh-variant

fuse-overlayfs: fix a couple of issues with the .wh. variant and enable tests
This commit is contained in:
Giuseppe Scrivano 2018-11-07 14:02:46 +01:00 committed by GitHub
commit 3d48bf9a82
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 59 additions and 16 deletions

View File

@ -27,3 +27,4 @@ script:
- make -j $(nproc)
- sudo make -j install; sudo cp fuse-overlayfs /sbin
- (cd /unionmount-testsuite; sudo ./run --ov --fuse=fuse-overlayfs --xdev)
- (cd /unionmount-testsuite; FUSE_OVERLAYFS_DISABLE_OVL_WHITEOUT=1 sudo -E ./run --ov --fuse=fuse-overlayfs --xdev)

74
main.c
View File

@ -83,6 +83,8 @@ struct _uintptr_to_must_hold_fuse_ino_t_dummy_struct
};
#endif
static bool disable_ovl_whiteout;
struct ovl_layer
{
struct ovl_layer *next;
@ -374,7 +376,7 @@ create_whiteout (struct ovl_data *lo, struct ovl_node *parent, const char *name,
int fd = -1;
static bool can_mknod = true;
if (!skip_mknod && can_mknod)
if (!disable_ovl_whiteout && !skip_mknod && can_mknod)
{
int ret;
@ -881,7 +883,7 @@ load_dir (struct ovl_data *lo, struct ovl_node *n, struct ovl_layer *layer, char
{
DIR *dp;
struct dirent *dent;
struct stat st;
struct stat st, tmp_st;
struct ovl_layer *it, *upper_layer = get_upper_layer (lo);
if (!n)
@ -906,6 +908,7 @@ load_dir (struct ovl_data *lo, struct ovl_node *n, struct ovl_layer *layer, char
for (;;)
{
int ret;
struct ovl_node key;
const char *wh;
struct ovl_node *child = NULL;
@ -954,12 +957,18 @@ load_dir (struct ovl_data *lo, struct ovl_node *n, struct ovl_layer *layer, char
}
}
sprintf (node_path, ".wh.%s", dent->d_name);
ret = TEMP_FAILURE_RETRY (fstatat (fd, node_path, &tmp_st, AT_SYMLINK_NOFOLLOW));
if (ret < 0 && errno != ENOENT)
{
closedir (dp);
return NULL;
}
sprintf (node_path, "%s/%s", n->path, dent->d_name);
wh = get_whiteout_name (dent->d_name, &st);
if (wh)
if (ret == 0)
{
child = make_whiteout_node (node_path, wh);
child = make_whiteout_node (node_path, dent->d_name);
if (child == NULL)
{
errno = ENOMEM;
@ -969,14 +978,28 @@ load_dir (struct ovl_data *lo, struct ovl_node *n, struct ovl_layer *layer, char
}
else
{
bool dirp = st.st_mode & S_IFDIR;
child = make_ovl_node (node_path, it, dent->d_name, 0, dirp, n);
if (child == NULL)
wh = get_whiteout_name (dent->d_name, &st);
if (wh)
{
errno = ENOMEM;
closedir (dp);
return NULL;
child = make_whiteout_node (node_path, wh);
if (child == NULL)
{
errno = ENOMEM;
closedir (dp);
return NULL;
}
}
else
{
bool dirp = st.st_mode & S_IFDIR;
child = make_ovl_node (node_path, it, dent->d_name, 0, dirp, n);
if (child == NULL)
{
errno = ENOMEM;
closedir (dp);
return NULL;
}
}
}
@ -1106,7 +1129,7 @@ do_lookup_file (struct ovl_data *lo, fuse_ino_t parent, const char *name)
char path[PATH_MAX];
char whpath[PATH_MAX];
struct ovl_layer *it;
struct stat st;
struct stat st, tmp_st;
struct ovl_layer *upper_layer = get_upper_layer (lo);
for (it = lo->layers; it; it = it->next)
@ -1120,7 +1143,23 @@ do_lookup_file (struct ovl_data *lo, fuse_ino_t parent, const char *name)
int saved_errno = errno;
if (errno == ENOENT)
continue;
{
sprintf (whpath, "%s/.wh.%s", pnode->path, name);
ret = TEMP_FAILURE_RETRY (fstatat (it->fd, whpath, &tmp_st, AT_SYMLINK_NOFOLLOW));
if (ret < 0 && errno != ENOENT)
return NULL;
if (ret == 0)
{
node = make_whiteout_node (path, name);
if (node == NULL)
{
errno = ENOMEM;
return NULL;
}
goto insert_node;
}
continue;
}
if (node)
node_free (node);
@ -1148,7 +1187,7 @@ do_lookup_file (struct ovl_data *lo, fuse_ino_t parent, const char *name)
}
sprintf (whpath, "%s/.wh.%s", pnode->path, name);
ret = TEMP_FAILURE_RETRY (fstatat (it->fd, whpath, &st, AT_SYMLINK_NOFOLLOW));
ret = TEMP_FAILURE_RETRY (fstatat (it->fd, whpath, &tmp_st, AT_SYMLINK_NOFOLLOW));
if (ret < 0 && errno != ENOENT)
return NULL;
if (ret == 0)
@ -1178,7 +1217,7 @@ do_lookup_file (struct ovl_data *lo, fuse_ino_t parent, const char *name)
if (ret > 0)
node->last_layer = it;
}
insert_node:
if (insert_node (pnode, node, false) == NULL)
{
node_free (node);
@ -3541,6 +3580,9 @@ main (int argc, char *argv[])
int ret = -1;
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");