[ostree] repo: Fix race condition in async checkout



commit f4327cc6a0f3fb0df9de52d03d8f0384d10c264c
Author: Colin Walters <walters verbum org>
Date:   Tue Apr 30 19:34:20 2013 -0400

    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.

 src/libostree/ostree-repo.c |    7 ++-----
 1 files changed, 2 insertions(+), 5 deletions(-)
---
diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c
index e793875..f4ad8fe 100644
--- a/src/libostree/ostree-repo.c
+++ b/src/libostree/ostree-repo.c
@@ -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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]