From dc9239dd7b09ef5e104309b4dbf0e136889da274 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 13 Jan 2016 10:15:21 -0500 Subject: [PATCH] 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 d448d6de..4b22e25b 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 415421af..d5b9aeaf 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 5bc25204..fd2b7f06 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 041b0b25..1524a866 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;