core: Attempt direct link() and fallback on EEXIST
Rather than always doing: 1) make temporary link 2) unlink() target 3) rename() Just try making the link, and only do the second two if the file already exists. This reduces system call traffic a lot.
This commit is contained in:
parent
f7bbf41132
commit
fb71519cd6
|
|
@ -4120,37 +4120,27 @@ checkout_file_hardlink (OstreeRepo *self,
|
||||||
{
|
{
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
ot_lobj GFile *dir = NULL;
|
ot_lobj GFile *dir = NULL;
|
||||||
ot_lobj GFile *temp_file = NULL;
|
|
||||||
|
|
||||||
if (overwrite_mode == OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES)
|
if (link (ot_gfile_get_path_cached (source), ot_gfile_get_path_cached (destination)) < 0)
|
||||||
{
|
{
|
||||||
dir = g_file_get_parent (destination);
|
if (errno == EEXIST && overwrite_mode == OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES)
|
||||||
if (!ostree_create_temp_hardlink (dir, (GFile*)source, NULL, "link",
|
{
|
||||||
&temp_file, cancellable, error))
|
/* Idiocy, from man rename(2)
|
||||||
goto out;
|
*
|
||||||
|
* "If oldpath and newpath are existing hard links referring to
|
||||||
/* Idiocy, from man rename(2)
|
* the same file, then rename() does nothing, and returns a
|
||||||
*
|
* success status."
|
||||||
* "If oldpath and newpath are existing hard links referring to
|
*
|
||||||
* the same file, then rename() does nothing, and returns a
|
* So we can't make this atomic.
|
||||||
* success status."
|
*/
|
||||||
*
|
(void) unlink (ot_gfile_get_path_cached (destination));
|
||||||
* So we can't make this atomic.
|
if (link (ot_gfile_get_path_cached (source), ot_gfile_get_path_cached (destination)) < 0)
|
||||||
*/
|
{
|
||||||
|
ot_util_set_error_from_errno (error, errno);
|
||||||
(void) unlink (ot_gfile_get_path_cached (destination));
|
goto out;
|
||||||
|
}
|
||||||
if (rename (ot_gfile_get_path_cached (temp_file),
|
|
||||||
ot_gfile_get_path_cached (destination)) < 0)
|
|
||||||
{
|
|
||||||
ot_util_set_error_from_errno (error, errno);
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
g_clear_object (&temp_file);
|
else
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (link (ot_gfile_get_path_cached (source), ot_gfile_get_path_cached (destination)) < 0)
|
|
||||||
{
|
{
|
||||||
ot_util_set_error_from_errno (error, errno);
|
ot_util_set_error_from_errno (error, errno);
|
||||||
goto out;
|
goto out;
|
||||||
|
|
@ -4159,8 +4149,6 @@ checkout_file_hardlink (OstreeRepo *self,
|
||||||
|
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
out:
|
out:
|
||||||
if (temp_file)
|
|
||||||
(void) unlink (ot_gfile_get_path_cached (temp_file));
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue