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:
Colin Walters 2013-04-30 19:34:20 -04:00
parent 8e4b296a96
commit f4327cc6a0
1 changed files with 2 additions and 5 deletions

View File

@ -3194,6 +3194,7 @@ checkout_file_hardlink (OstreeRepo *self,
gboolean ret_was_supported = FALSE;
ot_lobj GFile *dir = NULL;
again:
if (dirfd != -1 &&
linkat (-1, gs_file_get_path_cached (source),
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.
*/
(void) unlink (gs_file_get_path_cached (destination));
if (link (gs_file_get_path_cached (source), gs_file_get_path_cached (destination)) < 0)
{
ot_util_set_error_from_errno (error, errno);
goto out;
}
goto again;
ret_was_supported = TRUE;
}
else