Skip to content

Commit

Permalink
main: correctly mark the last_layer with a deleted directory
Browse files Browse the repository at this point in the history
Closes: #136

Signed-off-by: Giuseppe Scrivano <[email protected]>
  • Loading branch information
giuseppe committed Oct 31, 2019
1 parent 715a95c commit 161914c
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 15 deletions.
66 changes: 51 additions & 15 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1187,11 +1187,17 @@ make_ovl_node (struct ovl_data *lo, const char *path, struct ovl_layer *layer, c
struct stat st;
struct ovl_layer *it;
cleanup_free char *npath = NULL;
char whiteout_path[PATH_MAX];

npath = strdup (ret->path);
if (npath == NULL)
return NULL;

if (parent)
strconcat3 (whiteout_path, PATH_MAX, parent->path, "/.wh.", name);
else
strconcat3 (whiteout_path, PATH_MAX, "/.wh.", name, NULL);

for (it = layer; it; it = it->next)
{
ssize_t s;
Expand All @@ -1200,6 +1206,18 @@ make_ovl_node (struct ovl_data *lo, const char *path, struct ovl_layer *layer, c
cleanup_free char *origin = NULL;
cleanup_close int fd = -1;

if (dir_p)
{
int r;

r = it->ds->file_exists (it, whiteout_path);
if (r < 0 && errno != ENOENT)
return NULL;

if (r == 0)
break;
}

if (! fast_ino_check)
fd = it->ds->openat (it, npath, O_RDONLY|O_NONBLOCK|O_NOFOLLOW, 0755);

Expand Down Expand Up @@ -1348,7 +1366,9 @@ static struct ovl_node *
load_dir (struct ovl_data *lo, struct ovl_node *n, struct ovl_layer *layer, char *path, char *name)
{
struct dirent *dent;
bool stop_lookup = false;
struct ovl_layer *it, *upper_layer = get_upper_layer (lo);
char parent_whiteout_path[PATH_MAX];

if (!n)
{
Expand All @@ -1360,17 +1380,35 @@ load_dir (struct ovl_data *lo, struct ovl_node *n, struct ovl_layer *layer, char
}
}

for (it = lo->layers; it; it = it->next)
if (n->parent)
strconcat3 (parent_whiteout_path, PATH_MAX, n->parent->path, "/.wh.", name);
else
strconcat3 (parent_whiteout_path, PATH_MAX, ".wh.", name, NULL);

for (it = lo->layers; it && !stop_lookup; it = it->next)
{
int ret;
DIR *dp = NULL;

if (n->last_layer == it)
stop_lookup = true;

ret = it->ds->file_exists (it, parent_whiteout_path);
if (ret < 0 && errno != ENOENT)
{
it->ds->closedir (dp);
return NULL;
}

if (ret == 0)
break;

dp = it->ds->opendir (it, path);
if (dp == NULL)
continue;

for (;;)
{
int ret;
struct ovl_node key;
struct ovl_node *child = NULL;
char node_path[PATH_MAX];
Expand Down Expand Up @@ -1481,16 +1519,13 @@ load_dir (struct ovl_data *lo, struct ovl_node *n, struct ovl_layer *layer, char
}
}

if (insert_node (n, child, false) == NULL)
{
errno = ENOMEM;
it->ds->closedir (dp);
return NULL;
}
if (insert_node (n, child, false) == NULL)
{
errno = ENOMEM;
it->ds->closedir (dp);
return NULL;
}
}

if (n->last_layer == it)
break;
}

if (get_timeout (lo) > 0)
Expand Down Expand Up @@ -1685,14 +1720,18 @@ do_lookup_file (struct ovl_data *lo, fuse_ino_t parent, const char *name)
int ret;
struct ovl_layer *it;
struct stat st;
bool stop_lookup = false;
struct ovl_layer *upper_layer = get_upper_layer (lo);

for (it = lo->layers; it; it = it->next)
for (it = lo->layers; it && !stop_lookup; it = it->next)
{
char path[PATH_MAX];
char whpath[PATH_MAX];
const char *wh_name;

if (pnode && pnode->last_layer == it)
stop_lookup = true;

strconcat3 (path, PATH_MAX, pnode->path, "/", name);

ret = it->ds->statat (it, path, &st, AT_SYMLINK_NOFOLLOW, STATX_TYPE|STATX_MODE|STATX_INO);
Expand Down Expand Up @@ -1773,9 +1812,6 @@ do_lookup_file (struct ovl_data *lo, fuse_ino_t parent, const char *name)
errno = ENOMEM;
return NULL;
}

if (pnode && pnode->last_layer == it)
break;
}
}

Expand Down
15 changes: 15 additions & 0 deletions tests/fedora-installs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,18 @@ touch merged/usr 2>&1 | grep Read-only
mkdir merged/abcd12345 2>&1 | grep Read-only
ln merged/file-lower-layer merged/file-lower-layer-link 2>&1 | grep Read-only
ln -s merged/file-lower-layer merged/a-symlink 2>&1 | grep Read-only

umount merged

# https://github.com/containers/fuse-overlayfs/issues/136
rm -rf lower1 lower2 lower3 lower upper workdir merged
mkdir lower1 lower2 lower3 upper workdir merged

mkdir -p lower1/dir1/dir2
touch lower1/dir1/dir2/foo
touch lower2/.wh.dir1
mkdir -p lower3/dir1/dir2

fuse-overlayfs -o lowerdir=lower3:lower2:lower1,upperdir=upper,workdir=workdir merged

test \! -e merged/dir1/dir2/foo

0 comments on commit 161914c

Please sign in to comment.