From 9adc80c31ba0f23acdec4484cef7338c89c84e5d Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Fri, 21 Jun 2019 09:29:30 +0200 Subject: [PATCH] Revert "main: add helper function to get fd to the upper layer" This reverts commit b4ef7a8fff0a76ac05dccb59edbbb49971b76420. Closes: https://github.com/containers/fuse-overlayfs/issues/86 Signed-off-by: Giuseppe Scrivano --- main.c | 66 ++++++++++++++++++---------------------- tests/fedora-installs.sh | 20 +++++++++--- 2 files changed, 46 insertions(+), 40 deletions(-) diff --git a/main.c b/main.c index 4f36694..a97e556 100644 --- a/main.c +++ b/main.c @@ -404,12 +404,6 @@ node_dirfd (struct ovl_node *n) return n->layer->fd; } -static int -upper_layer_fd (struct ovl_data *lo) -{ - return lo->layers->fd; -} - static bool has_prefix (const char *str, const char *pref) { @@ -527,7 +521,7 @@ create_whiteout (struct ovl_data *lo, struct ovl_node *parent, const char *name, ret = asprintf (&whiteout_path, "%s/%s", parent->path, name); if (ret < 0) return ret; - ret = mknodat (upper_layer_fd (lo), whiteout_path, S_IFCHR|0700, makedev (0, 0)); + ret = mknodat (get_upper_layer (lo)->fd, whiteout_path, S_IFCHR|0700, makedev (0, 0)); if (ret == 0) return 0; @@ -541,7 +535,7 @@ create_whiteout (struct ovl_data *lo, struct ovl_node *parent, const char *name, ret = asprintf (&whiteout_wh_path, "%s/.wh.%s", parent->path, name); if (ret < 0) return ret; - fd = TEMP_FAILURE_RETRY (openat (upper_layer_fd (lo), whiteout_wh_path, O_CREAT|O_WRONLY|O_NONBLOCK, 0700)); + fd = TEMP_FAILURE_RETRY (openat (get_upper_layer (lo)->fd, whiteout_wh_path, O_CREAT|O_WRONLY|O_NONBLOCK, 0700)); if (fd < 0 && errno != EEXIST) return -1; @@ -573,12 +567,12 @@ delete_whiteout (struct ovl_data *lo, int dirfd, struct ovl_node *parent, const if (ret < 0) return ret; - if (TEMP_FAILURE_RETRY (fstatat (upper_layer_fd (lo), whiteout_path, &st, AT_SYMLINK_NOFOLLOW)) == 0 + if (TEMP_FAILURE_RETRY (fstatat (get_upper_layer (lo)->fd, whiteout_path, &st, AT_SYMLINK_NOFOLLOW)) == 0 && (st.st_mode & S_IFMT) == S_IFCHR && major (st.st_rdev) == 0 && minor (st.st_rdev) == 0) { - if (unlinkat (upper_layer_fd (lo), whiteout_path, 0) < 0) + if (unlinkat (get_upper_layer (lo)->fd, whiteout_path, 0) < 0) return -1; } } @@ -606,7 +600,7 @@ delete_whiteout (struct ovl_data *lo, int dirfd, struct ovl_node *parent, const if (ret < 0) return ret; - if (unlinkat (upper_layer_fd (lo), whiteout_path, 0) < 0 && errno != ENOENT) + if (unlinkat (get_upper_layer (lo)->fd, whiteout_path, 0) < 0 && errno != ENOENT) return -1; } @@ -632,7 +626,7 @@ hide_node (struct ovl_data *lo, struct ovl_node *node, bool unlink_src) if (unlink_src) { /* If the atomic rename+mknod failed, then fallback into doing it in two steps. */ - if (syscall (SYS_renameat2, upper_layer_fd (lo), node->path, lo->workdir_fd, + if (syscall (SYS_renameat2, node_dirfd (node), node->path, lo->workdir_fd, newpath, RENAME_WHITEOUT) < 0) { if (node->parent) @@ -643,7 +637,7 @@ hide_node (struct ovl_data *lo, struct ovl_node *node, bool unlink_src) if (create_whiteout (lo, node->parent, node->name, true, false) < 0) return -1; } - if (renameat (upper_layer_fd (lo), node->path, lo->workdir_fd, newpath) < 0) + if (renameat (node_dirfd (node), node->path, lo->workdir_fd, newpath) < 0) { if (node->parent) { @@ -653,7 +647,7 @@ hide_node (struct ovl_data *lo, struct ovl_node *node, bool unlink_src) /* If the rename failed, then try to delete the whiteout file we created earlier. */ if (ret == 0) - unlinkat (upper_layer_fd (lo), whpath, 0); + unlinkat (get_upper_layer (lo)->fd, whpath, 0); } return -1; } @@ -1977,7 +1971,7 @@ create_node_directory (struct ovl_data *lo, struct ovl_node *src) times[0] = st.st_atim; times[1] = st.st_mtim; - ret = create_directory (lo, upper_layer_fd (lo), src->path, times, src->parent, sfd, st.st_uid, st.st_gid, st.st_mode); + ret = create_directory (lo, get_upper_layer (lo)->fd, src->path, times, src->parent, sfd, st.st_uid, st.st_gid, st.st_mode); if (ret == 0) { src->layer = get_upper_layer (lo); @@ -2077,7 +2071,7 @@ copyup (struct ovl_data *lo, struct ovl_node *node) p = new; } p[ret] = '\0'; - ret = symlinkat (p, upper_layer_fd (lo), node->path); + ret = symlinkat (p, get_upper_layer (lo)->fd, node->path); if (ret < 0) goto exit; goto success; @@ -2151,7 +2145,7 @@ copyup (struct ovl_data *lo, struct ovl_node *node) goto exit; /* Finally, move the file to its destination. */ - ret = renameat (lo->workdir_fd, wd_tmp_file_name, upper_layer_fd (lo), node->path); + ret = renameat (lo->workdir_fd, wd_tmp_file_name, get_upper_layer (lo)->fd, node->path); if (ret < 0) goto exit; @@ -2162,7 +2156,7 @@ copyup (struct ovl_data *lo, struct ovl_node *node) ret = asprintf (&whpath, "%s/.wh.%s", node->parent->path, node->name); if (ret < 0) goto exit; - if (unlinkat (upper_layer_fd (lo), whpath, 0) < 0 && errno != ENOENT) + if (unlinkat (get_upper_layer (lo)->fd, whpath, 0) < 0 && errno != ENOENT) goto exit; } @@ -2260,7 +2254,7 @@ empty_dir (struct ovl_data *lo, struct ovl_node *node) cleanup_close int cleanup_fd = -1; struct dirent *dent; - cleanup_fd = TEMP_FAILURE_RETRY (openat (upper_layer_fd (lo), node->path, O_DIRECTORY)); + cleanup_fd = TEMP_FAILURE_RETRY (openat (get_upper_layer (lo)->fd, node->path, O_DIRECTORY)); if (cleanup_fd < 0) return -1; @@ -2440,7 +2434,7 @@ ovl_setxattr (fuse_req_t req, fuse_ino_t ino, const char *name, return; } - fd = TEMP_FAILURE_RETRY (openat (upper_layer_fd (lo), node->path, O_NONBLOCK)); + fd = TEMP_FAILURE_RETRY (openat (node_dirfd (node), node->path, O_NONBLOCK)); if (fd < 0) { fuse_reply_err (req, errno); @@ -2480,7 +2474,7 @@ ovl_removexattr (fuse_req_t req, fuse_ino_t ino, const char *name) return; } - fd = TEMP_FAILURE_RETRY (openat (upper_layer_fd (lo), node->path, O_NONBLOCK)); + fd = TEMP_FAILURE_RETRY (openat (node_dirfd (node), node->path, O_NONBLOCK)); if (fd < 0) { fuse_reply_err (req, errno); @@ -2568,13 +2562,13 @@ ovl_do_open (fuse_req_t req, fuse_ino_t parent, const char *name, int flags, mod unlinkat (lo->workdir_fd, wd_tmp_file_name, 0); return ret; } - if (unlinkat (upper_layer_fd (lo), path, 0) < 0 && errno != ENOENT) + if (unlinkat (get_upper_layer (lo)->fd, path, 0) < 0 && errno != ENOENT) return -1; if (delete_whiteout (lo, -1, p, name) < 0) return -1; - if (renameat (lo->workdir_fd, wd_tmp_file_name, upper_layer_fd (lo), path) < 0) + if (renameat (lo->workdir_fd, wd_tmp_file_name, get_upper_layer (lo)->fd, path) < 0) { unlinkat (lo->workdir_fd, wd_tmp_file_name, 0); return -1; @@ -2608,7 +2602,7 @@ ovl_do_open (fuse_req_t req, fuse_ino_t parent, const char *name, int flags, mod if (n == NULL) return -1; - return TEMP_FAILURE_RETRY (openat (upper_layer_fd (lo), n->path, flags, mode)); + return TEMP_FAILURE_RETRY (openat (node_dirfd (n), n->path, flags, mode)); } } @@ -2786,7 +2780,7 @@ ovl_setattr (fuse_req_t req, fuse_ino_t ino, struct stat *attr, int to_set, stru return; } - dirfd = upper_layer_fd (lo); + dirfd = node_dirfd (node); if (TEMP_FAILURE_RETRY (fstatat (dirfd, node->path, &old_st, AT_SYMLINK_NOFOLLOW)) < 0) { @@ -2944,20 +2938,20 @@ ovl_link (fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent, const char *newn return; } - if (linkat (upper_layer_fd (lo), node->path, lo->workdir_fd, wd_tmp_file_name, 0) < 0) + if (linkat (node_dirfd (newparentnode), node->path, lo->workdir_fd, wd_tmp_file_name, 0) < 0) { fuse_reply_err (req, errno); return; } - if (renameat (lo->workdir_fd, wd_tmp_file_name, upper_layer_fd (lo), path) < 0) + if (renameat (lo->workdir_fd, wd_tmp_file_name, node_dirfd (newparentnode), path) < 0) { fuse_reply_err (req, errno); return; } else { - cleanup_close int dfd = TEMP_FAILURE_RETRY (openat (upper_layer_fd (lo), path, O_WRONLY|O_NONBLOCK)); + cleanup_close int dfd = TEMP_FAILURE_RETRY (openat (node_dirfd (newparentnode), path, O_WRONLY|O_NONBLOCK)); if (dfd >= 0) { bool set = false; @@ -3078,7 +3072,7 @@ ovl_symlink (fuse_req_t req, const char *link, fuse_ino_t parent, const char *na return; } - ret = renameat (lo->workdir_fd, wd_tmp_file_name, upper_layer_fd (lo), path); + ret = renameat (lo->workdir_fd, wd_tmp_file_name, get_upper_layer (lo)->fd, path); if (ret < 0) { fuse_reply_err (req, errno); @@ -3160,7 +3154,7 @@ ovl_rename_exchange (fuse_req_t req, fuse_ino_t parent, const char *name, if (pnode == NULL) goto error; - ret = TEMP_FAILURE_RETRY (openat (upper_layer_fd (lo), pnode->path, O_DIRECTORY)); + ret = TEMP_FAILURE_RETRY (openat (node_dirfd (pnode), pnode->path, O_DIRECTORY)); if (ret < 0) goto error; srcfd = ret; @@ -3169,7 +3163,7 @@ ovl_rename_exchange (fuse_req_t req, fuse_ino_t parent, const char *name, if (destpnode == NULL) goto error; - ret = TEMP_FAILURE_RETRY (openat (upper_layer_fd (lo), destpnode->path, O_DIRECTORY)); + ret = TEMP_FAILURE_RETRY (openat (node_dirfd (destpnode), destpnode->path, O_DIRECTORY)); if (ret < 0) goto error; destfd = ret; @@ -3292,7 +3286,7 @@ ovl_rename_direct (fuse_req_t req, fuse_ino_t parent, const char *name, if (pnode == NULL) goto error; - ret = TEMP_FAILURE_RETRY (openat (upper_layer_fd (lo), pnode->path, O_DIRECTORY)); + ret = TEMP_FAILURE_RETRY (openat (node_dirfd (pnode), pnode->path, O_DIRECTORY)); if (ret < 0) goto error; srcfd = ret; @@ -3301,7 +3295,7 @@ ovl_rename_direct (fuse_req_t req, fuse_ino_t parent, const char *name, if (destpnode == NULL) goto error; - ret = TEMP_FAILURE_RETRY (openat (upper_layer_fd (lo), destpnode->path, O_DIRECTORY)); + ret = TEMP_FAILURE_RETRY (openat (node_dirfd (destpnode), destpnode->path, O_DIRECTORY)); if (ret < 0) goto error; destfd = ret; @@ -3466,7 +3460,7 @@ ovl_statfs (fuse_req_t req, fuse_ino_t ino) if (ovl_debug (req)) fprintf (stderr, "ovl_statfs(ino=%" PRIu64 "s)\n", ino); - ret = fstatvfs (upper_layer_fd (lo), &sfs); + ret = fstatvfs (get_upper_layer (lo)->fd, &sfs); if (ret < 0) { fuse_reply_err (req, errno); @@ -3624,7 +3618,7 @@ ovl_mknod (fuse_req_t req, fuse_ino_t parent, const char *name, mode_t mode, dev return; } - ret = renameat (lo->workdir_fd, wd_tmp_file_name, upper_layer_fd (lo), path); + ret = renameat (lo->workdir_fd, wd_tmp_file_name, get_upper_layer (lo)->fd, path); if (ret < 0) { fuse_reply_err (req, errno); @@ -3710,7 +3704,7 @@ ovl_mkdir (fuse_req_t req, fuse_ino_t parent, const char *name, mode_t mode) return; } - ret = create_directory (lo, upper_layer_fd (lo), path, NULL, pnode, -1, + ret = create_directory (lo, get_upper_layer (lo)->fd, path, NULL, pnode, -1, get_uid (lo, ctx->uid), get_gid (lo, ctx->gid), mode & ~ctx->umask); if (ret < 0) { diff --git a/tests/fedora-installs.sh b/tests/fedora-installs.sh index 50dd9ca..51464ae 100755 --- a/tests/fedora-installs.sh +++ b/tests/fedora-installs.sh @@ -6,7 +6,7 @@ mkdir lower upper workdir merged fuse-overlayfs -o lowerdir=lower,upperdir=upper,workdir=workdir,suid,dev merged -docker run --rm -ti -v merged:/merged fedora dnf --installroot /merged --releasever 30 install -y glibc-common gedit +docker run --rm -ti -v $(pwd)/merged:/merged fedora dnf --installroot /merged --releasever 30 install -y glibc-common gedit umount merged @@ -18,11 +18,23 @@ mkdir upper workdir fuse-overlayfs -o lowerdir=lower,upperdir=upper,workdir=workdir,suid,dev merged # Install some big packages -docker run --rm -ti -v merged:/merged fedora dnf --installroot /merged --releasever 30 install -y emacs texlive +docker run --rm -ti -v $(pwd)/merged:/merged fedora dnf --installroot /merged --releasever 30 install -y emacs texlive -docker run --rm -ti -v merged:/merged fedora sh -c 'rm /merged/usr/share/glib-2.0/schemas/gschemas.compiled; glib-compile-schemas /merged/usr/share/glib-2.0/schemas/' +docker run --rm -ti -v $(pwd)/merged:/merged fedora sh -c 'rm /merged/usr/share/glib-2.0/schemas/gschemas.compiled; glib-compile-schemas /merged/usr/share/glib-2.0/schemas/' umount merged fuse-overlayfs -o lowerdir=lower,upperdir=upper,workdir=workdir,suid,dev merged -docker run --rm -ti -v merged:/merged fedora sh -c 'rm -rf /merged/usr/share/glib-2.0/' +docker run --rm -ti -v $(pwd)/merged:/merged fedora sh -c 'rm -rf /merged/usr/share/glib-2.0/' + + +umount merged +rm -rf workdir lower upper +mkdir upper workdir lower + +fuse-overlayfs -o lowerdir=lower,upperdir=upper,workdir=workdir,suid,dev merged + +# https://github.com/containers/fuse-overlayfs/issues/86 +docker run --rm -ti -v $(pwd)/merged:/merged centos:6 yum --installroot /merged -y --releasever 6 install https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm + +umount merged