diff --git a/src/libostree/ostree-repo-private.h b/src/libostree/ostree-repo-private.h index b36e6d9405..bbc8b45638 100644 --- a/src/libostree/ostree-repo-private.h +++ b/src/libostree/ostree-repo-private.h @@ -60,6 +60,7 @@ struct OstreeRepo { gboolean writable; gboolean in_transaction; gboolean disable_fsync; + gboolean enable_syncfs; GHashTable *loose_object_devino_hash; GHashTable *updated_uncompressed_dirs; GHashTable *object_sizes; diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index b5b780eba3..421e0d8e98 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -2064,6 +2064,15 @@ ostree_repo_pull_with_options (OstreeRepo *self, } } + if (self->enable_syncfs) + { + if (syncfs (self->tmp_dir_fd) < 0) + { + g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errno), g_strerror (errno)); + goto out; + } + } + ret = TRUE; out: g_main_context_unref (pull_data->main_context); diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index 22abe91423..90865d70a8 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -1418,6 +1418,22 @@ ostree_repo_set_disable_fsync (OstreeRepo *self, self->disable_fsync = disable_fsync; } +/** + * ostree_repo_set_enable_syncfs: + * @self: An #OstreeRepo + * @enable_syncfs: If %TRUE, use syncfs instead of fsync + * + * Use syncfs to synchronize the file system containing the repository + * instead of calling fsync on each file. + * Should offer better performance as the sync is done only once. + */ +void +ostree_repo_set_enable_syncfs (OstreeRepo *self, + gboolean enable_syncfs) +{ + self->enable_syncfs = enable_syncfs; +} + /** * ostree_repo_get_path: diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h index 9154b43175..062cf3d3c1 100644 --- a/src/libostree/ostree-repo.h +++ b/src/libostree/ostree-repo.h @@ -52,6 +52,9 @@ gboolean ostree_repo_open (OstreeRepo *self, void ostree_repo_set_disable_fsync (OstreeRepo *self, gboolean disable_fsync); +void ostree_repo_set_enable_syncfs (OstreeRepo *self, + gboolean enable_syncfs); + gboolean ostree_repo_is_system (OstreeRepo *repo); gboolean ostree_repo_create (OstreeRepo *self, diff --git a/src/ostree/ot-builtin-pull.c b/src/ostree/ot-builtin-pull.c index 0846605464..bd7c132df9 100644 --- a/src/ostree/ot-builtin-pull.c +++ b/src/ostree/ot-builtin-pull.c @@ -28,11 +28,13 @@ #include "otutil.h" static gboolean opt_disable_fsync; +static gboolean opt_enable_syncfs; static gboolean opt_mirror; static char* opt_subpath; static int opt_depth = 0; static GOptionEntry options[] = { + { "enable-syncfs", 0, 0, G_OPTION_ARG_NONE, &opt_enable_syncfs, "Use syncfs() instead of fsync()", NULL }, { "disable-fsync", 0, 0, G_OPTION_ARG_NONE, &opt_disable_fsync, "Do not invoke fsync()", NULL }, { "mirror", 0, 0, G_OPTION_ARG_NONE, &opt_mirror, "Write refs suitable for a mirror", NULL }, { "subpath", 0, 0, G_OPTION_ARG_STRING, &opt_subpath, "Only pull the provided subpath", NULL }, @@ -63,6 +65,12 @@ ostree_builtin_pull (int argc, char **argv, GCancellable *cancellable, GError ** goto out; } + if (opt_enable_syncfs) + { + ostree_repo_set_disable_fsync (repo, TRUE); + ostree_repo_set_enable_syncfs (repo, TRUE); + } + if (opt_disable_fsync) ostree_repo_set_disable_fsync (repo, TRUE); diff --git a/tests/pull-test.sh b/tests/pull-test.sh index 5aee090f9d..68e6d2f7dd 100755 --- a/tests/pull-test.sh +++ b/tests/pull-test.sh @@ -39,6 +39,7 @@ function verify_initial_contents() { repo_init ${CMD_PREFIX} ostree --repo=repo pull origin main ${CMD_PREFIX} ostree --repo=repo pull origin:main +${CMD_PREFIX} ostree --repo=repo pull --enable-syncfs origin:main ${CMD_PREFIX} ostree --repo=repo fsck echo "ok pull"