From 3b7a5a79afee1699af71254bde52b79212c26cf6 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Fri, 6 Jul 2018 11:28:18 +0200 Subject: [PATCH] containerfs: copyup uses a temporary file in the workingdir Signed-off-by: Giuseppe Scrivano --- main.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/main.c b/main.c index 7a8d30d..053ce36 100644 --- a/main.c +++ b/main.c @@ -148,6 +148,13 @@ lo_data (fuse_req_t req) return (struct lo_data *) fuse_req_userdata (req); } +static unsigned long +get_next_wd_counter () +{ + static unsigned long counter = 1; + return counter++; +} + static struct lo_mapping * read_mappings (const char *str) { @@ -280,9 +287,8 @@ hide_node (struct lo_data *lo, struct lo_node *node, bool unlink_src) { char dest[PATH_MAX]; char *newpath; - static unsigned long counter = 1; - asprintf (&newpath, "%lu", counter++); + asprintf (&newpath, "%lu", get_next_wd_counter ()); if (newpath == NULL) { unlink (dest); @@ -1242,7 +1248,7 @@ copyup (struct lo_data *lo, struct lo_node *node) char *buf = NULL; struct timespec times[2]; ssize_t xattr_len; - + char wd_tmp_file_name[32]; if (node->parent) { @@ -1251,6 +1257,8 @@ copyup (struct lo_data *lo, struct lo_node *node) return ret; } + sprintf (wd_tmp_file_name, "%lu", get_next_wd_counter ()); + if (fstatat (node_dirfd (node), node->path, &st, AT_SYMLINK_NOFOLLOW) < 0) goto exit; @@ -1287,7 +1295,7 @@ copyup (struct lo_data *lo, struct lo_node *node) if (sfd < 0) goto exit; - dfd = openat (get_upper_layer (lo)->fd, node->path, O_CREAT|O_WRONLY, st.st_mode); + dfd = openat (lo->workdir_fd, wd_tmp_file_name, O_CREAT|O_WRONLY, st.st_mode); if (dfd < 0) goto exit; @@ -1346,6 +1354,10 @@ copyup (struct lo_data *lo, struct lo_node *node) } } + /* Finally, move the file to its destination. */ + ret = renameat (lo->workdir_fd, wd_tmp_file_name, get_upper_layer (lo)->fd, node->path); + if (ret < 0) + goto exit; success: ret = 0; @@ -1360,7 +1372,7 @@ copyup (struct lo_data *lo, struct lo_node *node) if (dfd >= 0) close (dfd); if (ret < 0) - unlinkat (get_upper_layer (lo)->fd, node->path, 0); + unlinkat (lo->workdir_fd, wd_tmp_file_name, 0); errno = saved_errno; return ret;