mirror of
https://github.com/containers/fuse-overlayfs.git
synced 2025-09-08 23:07:28 -04:00
containerfs: simplify hide_node
use a hard link so we don't modify the destination file before a rename(2). Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
This commit is contained in:
parent
f2b97eeea5
commit
f131a755fa
59
main.c
59
main.c
@ -245,34 +245,42 @@ get_node_path (struct lo_node *node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
hide_node (struct lo_data *lo, struct lo_node *node)
|
hide_node (struct lo_data *lo, struct lo_node *node, bool unlink_src)
|
||||||
{
|
{
|
||||||
char dest[PATH_MAX];
|
char dest[PATH_MAX];
|
||||||
char *newpath;
|
char *newpath;
|
||||||
int ret;
|
static unsigned long counter = 1;
|
||||||
|
|
||||||
node->hidden = 1;
|
node->hidden = 1;
|
||||||
node->parent = NULL;
|
node->parent = NULL;
|
||||||
|
|
||||||
sprintf (dest, "%s/tmp-XXXXXX", lo->workdir);
|
asprintf (&newpath, "%s/%lu", lo->workdir, counter++);
|
||||||
ret = mkstemp (dest);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
close (ret);
|
|
||||||
|
|
||||||
newpath = strdup (dest);
|
|
||||||
if (newpath == NULL)
|
if (newpath == NULL)
|
||||||
{
|
{
|
||||||
unlink (dest);
|
unlink (dest);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (rename (node->path, newpath) < 0)
|
|
||||||
|
/* Might be leftover from a previous run. */
|
||||||
|
unlink (newpath);
|
||||||
|
|
||||||
|
if (unlink_src)
|
||||||
{
|
{
|
||||||
free (newpath);
|
if (rename (node->path, newpath) < 0)
|
||||||
unlink (dest);
|
{
|
||||||
return -1;
|
free (newpath);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (link (node->path, newpath) < 0)
|
||||||
|
{
|
||||||
|
free (newpath);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
free (node->path);
|
free (node->path);
|
||||||
node->path = newpath;
|
node->path = newpath;
|
||||||
|
|
||||||
@ -1733,7 +1741,7 @@ do_rm (fuse_req_t req, fuse_ino_t parent, const char *name, bool dirp)
|
|||||||
rm = hash_delete (pnode->children, &key);
|
rm = hash_delete (pnode->children, &key);
|
||||||
if (rm)
|
if (rm)
|
||||||
{
|
{
|
||||||
hide_node (lo, rm);
|
hide_node (lo, rm, true);
|
||||||
node_free (rm);
|
node_free (rm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2360,22 +2368,6 @@ lo_flock (fuse_req_t req, fuse_ino_t ino,
|
|||||||
fuse_reply_err (req, ret == 0 ? 0 : errno);
|
fuse_reply_err (req, ret == 0 ? 0 : errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* used to recover a failed lo_rename. */
|
|
||||||
static struct lo_node *
|
|
||||||
unhide_node (struct lo_node *node, struct lo_node *parent)
|
|
||||||
{
|
|
||||||
char b[PATH_MAX];
|
|
||||||
|
|
||||||
if (node->path == NULL)
|
|
||||||
return node;
|
|
||||||
|
|
||||||
sprintf (b, "%s/%s", parent->path, node->name);
|
|
||||||
rename (node->path, b);
|
|
||||||
free (node->path);
|
|
||||||
node->path = strdup (b);
|
|
||||||
return insert_node (parent, node, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct lo_node *
|
static struct lo_node *
|
||||||
get_node_up_rec (struct lo_data *lo, struct lo_node *node)
|
get_node_up_rec (struct lo_data *lo, struct lo_node *node)
|
||||||
{
|
{
|
||||||
@ -2503,7 +2495,7 @@ lo_rename (fuse_req_t req, fuse_ino_t parent, const char *name,
|
|||||||
rm = NULL;
|
rm = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rm && !rm->not_exists && hide_node (lo, rm) < 0)
|
if (rm && !rm->not_exists && hide_node (lo, rm, false) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2511,9 +2503,6 @@ lo_rename (fuse_req_t req, fuse_ino_t parent, const char *name,
|
|||||||
ret = syscall (SYS_renameat2, srcfd, name, destfd, newname, flags);
|
ret = syscall (SYS_renameat2, srcfd, name, destfd, newname, flags);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
if (rm)
|
|
||||||
destpnode = unhide_node (rm, destpnode);
|
|
||||||
|
|
||||||
pnode->dirty = destpnode->dirty = 1;
|
pnode->dirty = destpnode->dirty = 1;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user