mirror of
https://github.com/containers/fuse-overlayfs.git
synced 2025-09-13 01:09:41 -04:00
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:
commit
3d48bf9a82
@ -27,3 +27,4 @@ script:
|
|||||||
- make -j $(nproc)
|
- make -j $(nproc)
|
||||||
- sudo make -j install; sudo cp fuse-overlayfs /sbin
|
- sudo make -j install; sudo cp fuse-overlayfs /sbin
|
||||||
- (cd /unionmount-testsuite; sudo ./run --ov --fuse=fuse-overlayfs --xdev)
|
- (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
74
main.c
@ -83,6 +83,8 @@ struct _uintptr_to_must_hold_fuse_ino_t_dummy_struct
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static bool disable_ovl_whiteout;
|
||||||
|
|
||||||
struct ovl_layer
|
struct ovl_layer
|
||||||
{
|
{
|
||||||
struct ovl_layer *next;
|
struct ovl_layer *next;
|
||||||
@ -374,7 +376,7 @@ create_whiteout (struct ovl_data *lo, struct ovl_node *parent, const char *name,
|
|||||||
int fd = -1;
|
int fd = -1;
|
||||||
static bool can_mknod = true;
|
static bool can_mknod = true;
|
||||||
|
|
||||||
if (!skip_mknod && can_mknod)
|
if (!disable_ovl_whiteout && !skip_mknod && can_mknod)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -881,7 +883,7 @@ load_dir (struct ovl_data *lo, struct ovl_node *n, struct ovl_layer *layer, char
|
|||||||
{
|
{
|
||||||
DIR *dp;
|
DIR *dp;
|
||||||
struct dirent *dent;
|
struct dirent *dent;
|
||||||
struct stat st;
|
struct stat st, tmp_st;
|
||||||
struct ovl_layer *it, *upper_layer = get_upper_layer (lo);
|
struct ovl_layer *it, *upper_layer = get_upper_layer (lo);
|
||||||
|
|
||||||
if (!n)
|
if (!n)
|
||||||
@ -906,6 +908,7 @@ load_dir (struct ovl_data *lo, struct ovl_node *n, struct ovl_layer *layer, char
|
|||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
struct ovl_node key;
|
struct ovl_node key;
|
||||||
const char *wh;
|
const char *wh;
|
||||||
struct ovl_node *child = NULL;
|
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);
|
sprintf (node_path, "%s/%s", n->path, dent->d_name);
|
||||||
|
|
||||||
wh = get_whiteout_name (dent->d_name, &st);
|
if (ret == 0)
|
||||||
if (wh)
|
|
||||||
{
|
{
|
||||||
child = make_whiteout_node (node_path, wh);
|
child = make_whiteout_node (node_path, dent->d_name);
|
||||||
if (child == NULL)
|
if (child == NULL)
|
||||||
{
|
{
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
@ -969,14 +978,28 @@ load_dir (struct ovl_data *lo, struct ovl_node *n, struct ovl_layer *layer, char
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool dirp = st.st_mode & S_IFDIR;
|
wh = get_whiteout_name (dent->d_name, &st);
|
||||||
|
if (wh)
|
||||||
child = make_ovl_node (node_path, it, dent->d_name, 0, dirp, n);
|
|
||||||
if (child == NULL)
|
|
||||||
{
|
{
|
||||||
errno = ENOMEM;
|
child = make_whiteout_node (node_path, wh);
|
||||||
closedir (dp);
|
if (child == NULL)
|
||||||
return 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 path[PATH_MAX];
|
||||||
char whpath[PATH_MAX];
|
char whpath[PATH_MAX];
|
||||||
struct ovl_layer *it;
|
struct ovl_layer *it;
|
||||||
struct stat st;
|
struct stat st, tmp_st;
|
||||||
struct ovl_layer *upper_layer = get_upper_layer (lo);
|
struct ovl_layer *upper_layer = get_upper_layer (lo);
|
||||||
|
|
||||||
for (it = lo->layers; it; it = it->next)
|
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;
|
int saved_errno = errno;
|
||||||
|
|
||||||
if (errno == ENOENT)
|
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)
|
if (node)
|
||||||
node_free (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);
|
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)
|
if (ret < 0 && errno != ENOENT)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
@ -1178,7 +1217,7 @@ do_lookup_file (struct ovl_data *lo, fuse_ino_t parent, const char *name)
|
|||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
node->last_layer = it;
|
node->last_layer = it;
|
||||||
}
|
}
|
||||||
|
insert_node:
|
||||||
if (insert_node (pnode, node, false) == NULL)
|
if (insert_node (pnode, node, false) == NULL)
|
||||||
{
|
{
|
||||||
node_free (node);
|
node_free (node);
|
||||||
@ -3541,6 +3580,9 @@ main (int argc, char *argv[])
|
|||||||
int ret = -1;
|
int ret = -1;
|
||||||
struct fuse_args args = FUSE_ARGS_INIT (argc, newargv);
|
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));
|
memset (&opts, 0, sizeof (opts));
|
||||||
if (fuse_opt_parse (&args, &lo, ovl_opts, fuse_opt_proc) == -1)
|
if (fuse_opt_parse (&args, &lo, ovl_opts, fuse_opt_proc) == -1)
|
||||||
error (EXIT_FAILURE, 0, "error parsing options");
|
error (EXIT_FAILURE, 0, "error parsing options");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user