From fb71519cd6e7c3898601cf31124b9257d8e5f037 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 24 May 2012 20:14:51 -0400 Subject: [PATCH] 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. --- src/libostree/ostree-repo.c | 48 ++++++++++++++----------------------- 1 file changed, 18 insertions(+), 30 deletions(-) diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index a2d42436..22745883 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -4120,37 +4120,27 @@ checkout_file_hardlink (OstreeRepo *self, { gboolean ret = FALSE; 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 (!ostree_create_temp_hardlink (dir, (GFile*)source, NULL, "link", - &temp_file, cancellable, error)) - goto out; - - /* Idiocy, from man rename(2) - * - * "If oldpath and newpath are existing hard links referring to - * the same file, then rename() does nothing, and returns a - * success status." - * - * So we can't make this atomic. - */ - - (void) unlink (ot_gfile_get_path_cached (destination)); - - 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; + if (errno == EEXIST && overwrite_mode == OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES) + { + /* Idiocy, from man rename(2) + * + * "If oldpath and newpath are existing hard links referring to + * the same file, then rename() does nothing, and returns a + * success status." + * + * So we can't make this atomic. + */ + (void) unlink (ot_gfile_get_path_cached (destination)); + if (link (ot_gfile_get_path_cached (source), ot_gfile_get_path_cached (destination)) < 0) + { + ot_util_set_error_from_errno (error, errno); + goto out; + } } - g_clear_object (&temp_file); - } - else - { - if (link (ot_gfile_get_path_cached (source), ot_gfile_get_path_cached (destination)) < 0) + else { ot_util_set_error_from_errno (error, errno); goto out; @@ -4159,8 +4149,6 @@ checkout_file_hardlink (OstreeRepo *self, ret = TRUE; out: - if (temp_file) - (void) unlink (ot_gfile_get_path_cached (temp_file)); return ret; }