[ostree] sysroot: Don't individually fsync dirs in checkout, rely on syncfs



commit dc9239dd7b09ef5e104309b4dbf0e136889da274
Author: Colin Walters <walters verbum org>
Date:   Wed Jan 13 10:15:21 2016 -0500

    sysroot: Don't individually fsync dirs in checkout, rely on syncfs
    
    Originally, a lot of the `fsync()` calls here were added for the
    wrong reason - I was chasing a bug that ended up being the extlinux
    bootloader not parsing 64 bit ext4 filesystems.  But since it looked
    like corruption, I tried adding a lot more `fsync()` calls.
    
    All we should have to do is use `syncfs()`.  If that doesn't work,
    it's a kernel bug.
    
    I'm making this change because skipping the individual fsyncs can be a
    major performance win - it's easier for the FS to optimize, we do more
    in parallel, etc.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=757117

 doc/ostree-sections.txt               |    1 +
 src/libostree/ostree-repo.c           |   13 +++++++++++++
 src/libostree/ostree-repo.h           |    2 ++
 src/libostree/ostree-sysroot-deploy.c |   18 ++++++++++++++----
 4 files changed, 30 insertions(+), 4 deletions(-)
---
diff --git a/doc/ostree-sections.txt b/doc/ostree-sections.txt
index d448d6d..4b22e25 100644
--- a/doc/ostree-sections.txt
+++ b/doc/ostree-sections.txt
@@ -220,6 +220,7 @@ ostree_repo_new_for_sysroot_path
 ostree_repo_new_default
 ostree_repo_open
 ostree_repo_set_disable_fsync
+ostree_repo_get_disable_fsync
 ostree_repo_is_system
 ostree_repo_is_writable
 ostree_repo_create
diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c
index 415421a..d5b9aea 100644
--- a/src/libostree/ostree-repo.c
+++ b/src/libostree/ostree-repo.c
@@ -2384,6 +2384,19 @@ ostree_repo_set_disable_fsync (OstreeRepo    *self,
   self->disable_fsync = disable_fsync;
 }
 
+/**
+ * ostree_repo_get_disable_fsync:
+ * @self: An #OstreeRepo
+ *
+ * For more information see ostree_repo_set_disable_fsync().
+ *
+ * Returns: Whether or not fsync() is enabled for this repo.
+ */
+gboolean
+ostree_repo_get_disable_fsync (OstreeRepo    *self)
+{
+  return self->disable_fsync;
+}
 
 /* Replace the contents of a file, honoring the repository's fsync
  * policy.
diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h
index 5bc2520..fd2b7f0 100644
--- a/src/libostree/ostree-repo.h
+++ b/src/libostree/ostree-repo.h
@@ -56,6 +56,8 @@ gboolean      ostree_repo_open   (OstreeRepo     *self,
 void          ostree_repo_set_disable_fsync (OstreeRepo    *self,
                                              gboolean       disable_fsync);
 
+gboolean      ostree_repo_get_disable_fsync (OstreeRepo    *self);
+
 gboolean      ostree_repo_is_system (OstreeRepo   *repo);
 
 gboolean      ostree_repo_is_writable (OstreeRepo  *self,
diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c
index 041b0b2..1524a86 100644
--- a/src/libostree/ostree-sysroot-deploy.c
+++ b/src/libostree/ostree-sysroot-deploy.c
@@ -540,10 +540,20 @@ checkout_deployment_tree (OstreeSysroot     *sysroot,
   if (!glnx_shutil_rm_rf_at (osdeploy_dfd, checkout_target_name, cancellable, error))
     goto out;
 
-  if (!ostree_repo_checkout_tree_at (repo, &checkout_opts, osdeploy_dfd,
-                                     checkout_target_name, csum,
-                                     cancellable, error))
-    goto out;
+ /* We end up using syncfs for the entire filesystem, so turn off
+   * OstreeRepo level fsync.
+   */
+  { gboolean fsync_was_disabled = ostree_repo_get_disable_fsync (repo);
+    gboolean checkout_success;
+
+    ostree_repo_set_disable_fsync (repo, TRUE);
+    checkout_success = ostree_repo_checkout_tree_at (repo, &checkout_opts, osdeploy_dfd,
+                                                     checkout_target_name, csum,
+                                                     cancellable, error);
+    ostree_repo_set_disable_fsync (repo, fsync_was_disabled);
+    if (!checkout_success)
+      goto out;
+  }
 
   if (!glnx_opendirat (osdeploy_dfd, checkout_target_name, TRUE, &ret_fd, error))
     goto out;


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