mirror of
https://github.com/containers/fuse-overlayfs.git
synced 2025-09-10 07:44:54 -04:00
fuse-overlayfs: split ovl_rename in two functions
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
This commit is contained in:
parent
234a1baaf9
commit
b3f454183f
184
main.c
184
main.c
@ -2560,7 +2560,7 @@ ovl_flock (fuse_req_t req, fuse_ino_t ino,
|
||||
}
|
||||
|
||||
static void
|
||||
ovl_rename (fuse_req_t req, fuse_ino_t parent, const char *name,
|
||||
ovl_rename_exchange (fuse_req_t req, fuse_ino_t parent, const char *name,
|
||||
fuse_ino_t newparent, const char *newname,
|
||||
unsigned int flags)
|
||||
{
|
||||
@ -2570,10 +2570,8 @@ ovl_rename (fuse_req_t req, fuse_ino_t parent, const char *name,
|
||||
int saved_errno;
|
||||
int srcfd = -1;
|
||||
int destfd = -1;
|
||||
struct ovl_node key, *rm = NULL;
|
||||
|
||||
if (ovl_debug (req))
|
||||
fprintf (stderr, "ovl_rename(ino=%" PRIu64 "s, name=%s , ino=%" PRIu64 "s, name=%s)\n", parent, name, newparent, newname);
|
||||
struct ovl_node *rm1, *rm2;
|
||||
char *tmp;
|
||||
|
||||
node = do_lookup_file (lo, parent, name);
|
||||
if (node == NULL)
|
||||
@ -2626,8 +2624,6 @@ ovl_rename (fuse_req_t req, fuse_ino_t parent, const char *name,
|
||||
if (node == NULL)
|
||||
goto error;
|
||||
|
||||
if (flags & RENAME_EXCHANGE)
|
||||
{
|
||||
if (destnode == NULL)
|
||||
{
|
||||
errno = ENOENT;
|
||||
@ -2641,9 +2637,124 @@ ovl_rename (fuse_req_t req, fuse_ino_t parent, const char *name,
|
||||
destnode = get_node_up (lo, destnode);
|
||||
if (destnode == NULL)
|
||||
goto error;
|
||||
}
|
||||
else
|
||||
|
||||
|
||||
ret = syscall (SYS_renameat2, srcfd, name, destfd, newname, flags);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
|
||||
rm1 = hash_delete (destpnode->children, destnode);
|
||||
rm2 = hash_delete (pnode->children, node);
|
||||
|
||||
tmp = node->path;
|
||||
node->path = destnode->path;
|
||||
destnode->path = tmp;
|
||||
|
||||
tmp = node->name;
|
||||
node->name = destnode->name;
|
||||
destnode->name = tmp;
|
||||
|
||||
node = insert_node (destpnode, node, true);
|
||||
if (node == NULL)
|
||||
{
|
||||
node_free (rm1);
|
||||
node_free (rm2);
|
||||
goto error;
|
||||
}
|
||||
destnode = insert_node (pnode, destnode, true);
|
||||
if (destnode == NULL)
|
||||
{
|
||||
node_free (rm1);
|
||||
node_free (rm2);
|
||||
goto error;
|
||||
}
|
||||
if ((update_paths (node) < 0) || (update_paths (destnode) < 0))
|
||||
goto error;
|
||||
|
||||
if (delete_whiteout (lo, destfd, NULL, newname) < 0)
|
||||
goto error;
|
||||
|
||||
ret = 0;
|
||||
goto cleanup;
|
||||
|
||||
error:
|
||||
ret = -1;
|
||||
|
||||
cleanup:
|
||||
saved_errno = errno;
|
||||
if (srcfd >= 0)
|
||||
close (srcfd);
|
||||
if (destfd >= 0)
|
||||
close (destfd);
|
||||
errno = saved_errno;
|
||||
|
||||
fuse_reply_err (req, ret == 0 ? 0 : errno);
|
||||
}
|
||||
|
||||
static void
|
||||
ovl_rename_direct (fuse_req_t req, fuse_ino_t parent, const char *name,
|
||||
fuse_ino_t newparent, const char *newname,
|
||||
unsigned int flags)
|
||||
{
|
||||
struct ovl_node *pnode, *node, *destnode, *destpnode;
|
||||
struct ovl_data *lo = ovl_data (req);
|
||||
int ret;
|
||||
int saved_errno;
|
||||
int srcfd = -1;
|
||||
int destfd = -1;
|
||||
struct ovl_node key, *rm = NULL;
|
||||
|
||||
node = do_lookup_file (lo, parent, name);
|
||||
if (node == NULL)
|
||||
{
|
||||
fuse_reply_err (req, ENOENT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (node_dirp (node))
|
||||
{
|
||||
node = load_dir (lo, node, node->layer, node->path, node->name);
|
||||
if (node == NULL)
|
||||
{
|
||||
fuse_reply_err (req, errno);
|
||||
return;
|
||||
}
|
||||
|
||||
if (node->layer != get_upper_layer (lo) || node->present_lowerdir)
|
||||
{
|
||||
fuse_reply_err (req, EXDEV);
|
||||
return;
|
||||
}
|
||||
}
|
||||
pnode = node->parent;
|
||||
|
||||
destpnode = do_lookup_file (lo, newparent, NULL);
|
||||
destnode = NULL;
|
||||
|
||||
pnode = get_node_up (lo, pnode);
|
||||
if (pnode == NULL)
|
||||
goto error;
|
||||
|
||||
ret = TEMP_FAILURE_RETRY (openat (node_dirfd (pnode), pnode->path, O_DIRECTORY));
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
srcfd = ret;
|
||||
|
||||
destpnode = get_node_up (lo, destpnode);
|
||||
if (destpnode == NULL)
|
||||
goto error;
|
||||
|
||||
ret = TEMP_FAILURE_RETRY (openat (node_dirfd (destpnode), destpnode->path, O_DIRECTORY));
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
destfd = ret;
|
||||
|
||||
destnode = do_lookup_file (lo, newparent, newname);
|
||||
|
||||
node = get_node_up (lo, node);
|
||||
if (node == NULL)
|
||||
goto error;
|
||||
|
||||
key.name = (char *) newname;
|
||||
if (flags & RENAME_NOREPLACE)
|
||||
{
|
||||
@ -2716,47 +2827,7 @@ ovl_rename (fuse_req_t req, fuse_ino_t parent, const char *name,
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & RENAME_EXCHANGE)
|
||||
{
|
||||
struct ovl_node *rm1, *rm2;
|
||||
char *tmp;
|
||||
|
||||
ret = syscall (SYS_renameat2, srcfd, name, destfd, newname, flags);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
|
||||
rm1 = hash_delete (destpnode->children, destnode);
|
||||
rm2 = hash_delete (pnode->children, node);
|
||||
|
||||
tmp = node->path;
|
||||
node->path = destnode->path;
|
||||
destnode->path = tmp;
|
||||
|
||||
tmp = node->name;
|
||||
node->name = destnode->name;
|
||||
destnode->name = tmp;
|
||||
|
||||
node = insert_node (destpnode, node, true);
|
||||
if (node == NULL)
|
||||
{
|
||||
node_free (rm1);
|
||||
node_free (rm2);
|
||||
goto error;
|
||||
}
|
||||
destnode = insert_node (pnode, destnode, true);
|
||||
if (destnode == NULL)
|
||||
{
|
||||
node_free (rm1);
|
||||
node_free (rm2);
|
||||
goto error;
|
||||
}
|
||||
if ((update_paths (node) < 0) || (update_paths (destnode) < 0))
|
||||
goto error;
|
||||
}
|
||||
else
|
||||
{
|
||||
unlinkat (destfd, newname, 0);
|
||||
|
||||
/* Try to create the whiteout atomically, if it fails do the
|
||||
@ -2789,7 +2860,6 @@ ovl_rename (fuse_req_t req, fuse_ino_t parent, const char *name,
|
||||
goto error;
|
||||
if (update_paths (node) < 0)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (delete_whiteout (lo, destfd, NULL, newname) < 0)
|
||||
goto error;
|
||||
@ -2811,6 +2881,20 @@ ovl_rename (fuse_req_t req, fuse_ino_t parent, const char *name,
|
||||
fuse_reply_err (req, ret == 0 ? 0 : errno);
|
||||
}
|
||||
|
||||
static void
|
||||
ovl_rename (fuse_req_t req, fuse_ino_t parent, const char *name,
|
||||
fuse_ino_t newparent, const char *newname,
|
||||
unsigned int flags)
|
||||
{
|
||||
if (ovl_debug (req))
|
||||
fprintf (stderr, "ovl_rename(ino=%" PRIu64 "s, name=%s , ino=%" PRIu64 "s, name=%s)\n", parent, name, newparent, newname);
|
||||
|
||||
if (flags & RENAME_EXCHANGE)
|
||||
ovl_rename_exchange (req, parent, name, newparent, newname, flags);
|
||||
else
|
||||
ovl_rename_direct (req, parent, name, newparent, newname, flags);
|
||||
}
|
||||
|
||||
static void
|
||||
ovl_statfs (fuse_req_t req, fuse_ino_t ino)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user