repo: Fix race condition in async checkout
When multiple threads need to uncompress an object, there was a race condition where thread A could get EEXIST, unlink, then thread B calls linkat(), then thread A tries to link() but fails. We can just loop in this case.
This commit is contained in:
parent
8e4b296a96
commit
f4327cc6a0
|
|
@ -3194,6 +3194,7 @@ checkout_file_hardlink (OstreeRepo *self,
|
||||||
gboolean ret_was_supported = FALSE;
|
gboolean ret_was_supported = FALSE;
|
||||||
ot_lobj GFile *dir = NULL;
|
ot_lobj GFile *dir = NULL;
|
||||||
|
|
||||||
|
again:
|
||||||
if (dirfd != -1 &&
|
if (dirfd != -1 &&
|
||||||
linkat (-1, gs_file_get_path_cached (source),
|
linkat (-1, gs_file_get_path_cached (source),
|
||||||
dirfd, gs_file_get_basename_cached (destination), 0) != -1)
|
dirfd, gs_file_get_basename_cached (destination), 0) != -1)
|
||||||
|
|
@ -3218,11 +3219,7 @@ checkout_file_hardlink (OstreeRepo *self,
|
||||||
* So we can't make this atomic.
|
* So we can't make this atomic.
|
||||||
*/
|
*/
|
||||||
(void) unlink (gs_file_get_path_cached (destination));
|
(void) unlink (gs_file_get_path_cached (destination));
|
||||||
if (link (gs_file_get_path_cached (source), gs_file_get_path_cached (destination)) < 0)
|
goto again;
|
||||||
{
|
|
||||||
ot_util_set_error_from_errno (error, errno);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
ret_was_supported = TRUE;
|
ret_was_supported = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue