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 978ecd2
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 16 deletions.
51 changes: 35 additions & 16 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1152,7 +1152,7 @@ make_ovl_node (struct ovl_data *lo, const char *path, struct ovl_layer *layer, c
return NULL;

ret->parent = parent;
ret->layer = layer;
ret->last_layer = ret->layer = layer;
ret->tmp_ino = ino;
ret->tmp_dev = dev;
ret->hidden_dirfd = -1;
Expand Down 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,6 +1366,7 @@ 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);

if (!n)
Expand All @@ -1360,10 +1379,13 @@ load_dir (struct ovl_data *lo, struct ovl_node *n, struct ovl_layer *layer, char
}
}

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

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

dp = it->ds->opendir (it, path);
if (dp == NULL)
continue;
Expand Down Expand Up @@ -1397,7 +1419,6 @@ load_dir (struct ovl_data *lo, struct ovl_node *n, struct ovl_layer *layer, char
child = hash_lookup (n->children, &key);
if (child)
{
child->last_layer = it;
if (!child->whiteout || it != upper_layer)
continue;
else
Expand Down Expand Up @@ -1481,16 +1502,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 +1703,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 +1795,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 978ecd2

Please sign in to comment.