From patchwork Mon Oct 4 16:57:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Neeraj Singh (WINDOWS-SFS)" X-Patchwork-Id: 12534341 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8E6B4C433FE for ; Mon, 4 Oct 2021 16:57:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 719FA61357 for ; Mon, 4 Oct 2021 16:57:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237882AbhJDQ7m (ORCPT ); Mon, 4 Oct 2021 12:59:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56952 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237868AbhJDQ7k (ORCPT ); Mon, 4 Oct 2021 12:59:40 -0400 Received: from mail-wm1-x333.google.com (mail-wm1-x333.google.com [IPv6:2a00:1450:4864:20::333]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7F4ADC061749 for ; Mon, 4 Oct 2021 09:57:51 -0700 (PDT) Received: by mail-wm1-x333.google.com with SMTP id p21so4255181wmq.1 for ; Mon, 04 Oct 2021 09:57:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=bRdReQSxU0phNxYyS0xHl7/Uw1JEvVeHEIF6saI/aGw=; b=cA058F1sRlTF2u+qyPDBv7/IDQh5wnnS3VBKQwuyzM1/wb/TWiQC3NErz1RDi+y5AX BHzJWw51yon/FYYmmQdIa9hrYc9s4vqLpuY60SJL8Sldqz8SSKQkXYnHAMdoU6jXpXyX 7iKbWkRp0s48DSvQqabRiztn/VscRj9nZhQUsK7u8F+FkFUTeABg6uCtcZ+wrdFWybk6 q+gZqWFlse6Sm9i5ZhCXaeSKCp71Z+d8BpYs/Q7D3w13PC5Z4aqi7IpZv/CvGQLlvN41 COMQNHKhv8dOIvsFLUWbxQQ3NBUvwc0ix9GXNYyNfBRRKe2jM7HDYxiGw27zULML/3FY NKOA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=bRdReQSxU0phNxYyS0xHl7/Uw1JEvVeHEIF6saI/aGw=; b=llGHb2Mra1RfzR/u6MVTfJhmq7d8DLETVtChlMv9fE3AhMUqz9Hh1JJBtoaEAmHjwq m4ZzT1w4yzjxCi8UKrUC+MzM5lpLHJYdSg2X8DQf5g0r6wfVNV7AromzpUB9dGI7jrMG KiHa7XomoORxn3irHxE4R6EJyUNJJCr4KZYMWDuU/v3fGOB2aIVizYYhgB/MLdPZ70np Ti8p51ykRlzmwLpXRqnnrC+Ktm/pysAM2JJgByn8KdA+DqGC29Dv2+yplQd5Azz6Igho yb89NTJRNARy3U6En/QJEB0m5ETDQF9m178K3iVEtFqx2tBJL60Iu2EfxYrM8hCEd8JD XTEg== X-Gm-Message-State: AOAM533rzuE/1Feb34sNrBMTQl/qswW17BmB5Zn6ouIUydhlQx5vc7IH MAdfxdOV7caqz5tT2q2n+0YO0eWFWYE= X-Google-Smtp-Source: ABdhPJyXjbH/bA73IvAVq/oBiBMcrzknhyIxnGD+5bRtRV8yN8c48o0rDrEAKpvyU1jIAUgKJHoX7g== X-Received: by 2002:a1c:1d92:: with SMTP id d140mr20290350wmd.17.1633366670084; Mon, 04 Oct 2021 09:57:50 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id 61sm14960771wrl.94.2021.10.04.09.57.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Oct 2021 09:57:49 -0700 (PDT) Message-Id: In-Reply-To: References: Date: Mon, 04 Oct 2021 16:57:39 +0000 Subject: [PATCH v8 1/9] tmp-objdir: new API for creating temporary writable databases Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Neeraj-Personal , Johannes Schindelin , Jeff King , Jeff Hostetler , Christoph Hellwig , =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsA==?= Bjarmason , "Randall S. Becker" , Bagas Sanjaya , Elijah Newren , "Neeraj K. Singh" , Neeraj Singh Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Neeraj Singh From: Neeraj Singh The tmp_objdir API provides the ability to create temporary object directories, but was designed with the goal of having subprocesses access these object stores, followed by the main process migrating objects from it to the main object store or just deleting it. The subprocesses would view it as their primary datastore and write to it. Here we add the tmp_objdir_replace_primary_odb function that replaces the current process's writable "main" object directory with the specified one. The previous main object directory is restored in either tmp_objdir_migrate or tmp_objdir_destroy. For the --remerge-diff usecase, add a new `will_destroy` flag in `struct object_database` to mark ephemeral object databases that do not require fsync durability. Add 'git prune' support for removing temporary object databases, and make sure that they have a name starting with tmp_ and containing an operation-specific name. Based-on-patch-by: Elijah Newren Signed-off-by: Neeraj Singh --- builtin/prune.c | 22 +++++++++++++++++---- builtin/receive-pack.c | 2 +- object-file.c | 44 ++++++++++++++++++++++++++++++++++++++++-- object-store.h | 19 ++++++++++++++++++ object.c | 2 +- tmp-objdir.c | 30 +++++++++++++++++++++++++--- tmp-objdir.h | 14 +++++++++++--- 7 files changed, 119 insertions(+), 14 deletions(-) diff --git a/builtin/prune.c b/builtin/prune.c index 02c6ab7cbaa..9c72ecf5a58 100644 --- a/builtin/prune.c +++ b/builtin/prune.c @@ -18,6 +18,7 @@ static int show_only; static int verbose; static timestamp_t expire; static int show_progress = -1; +static struct strbuf remove_dir_buf = STRBUF_INIT; static int prune_tmp_file(const char *fullpath) { @@ -26,10 +27,19 @@ static int prune_tmp_file(const char *fullpath) return error("Could not stat '%s'", fullpath); if (st.st_mtime > expire) return 0; - if (show_only || verbose) - printf("Removing stale temporary file %s\n", fullpath); - if (!show_only) - unlink_or_warn(fullpath); + if (S_ISDIR(st.st_mode)) { + if (show_only || verbose) + printf("Removing stale temporary directory %s\n", fullpath); + if (!show_only) { + strbuf_addstr(&remove_dir_buf, fullpath); + remove_dir_recursively(&remove_dir_buf, 0); + } + } else { + if (show_only || verbose) + printf("Removing stale temporary file %s\n", fullpath); + if (!show_only) + unlink_or_warn(fullpath); + } return 0; } @@ -97,6 +107,9 @@ static int prune_cruft(const char *basename, const char *path, void *data) static int prune_subdir(unsigned int nr, const char *path, void *data) { + if (verbose) + printf("Removing directory %s\n", path); + if (!show_only) rmdir(path); return 0; @@ -185,5 +198,6 @@ int cmd_prune(int argc, const char **argv, const char *prefix) prune_shallow(show_only ? PRUNE_SHOW_ONLY : 0); } + strbuf_release(&remove_dir_buf); return 0; } diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index 48960a9575b..418a42ca069 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -2208,7 +2208,7 @@ static const char *unpack(int err_fd, struct shallow_info *si) strvec_push(&child.args, alt_shallow_file); } - tmp_objdir = tmp_objdir_create(); + tmp_objdir = tmp_objdir_create("incoming"); if (!tmp_objdir) { if (err_fd > 0) close(err_fd); diff --git a/object-file.c b/object-file.c index be4f94ecf3b..990381abee5 100644 --- a/object-file.c +++ b/object-file.c @@ -751,6 +751,43 @@ void add_to_alternates_memory(const char *reference) '\n', NULL, 0); } +struct object_directory *set_temporary_primary_odb(const char *dir, int will_destroy) +{ + struct object_directory *new_odb; + + /* + * Make sure alternates are initialized, or else our entry may be + * overwritten when they are. + */ + prepare_alt_odb(the_repository); + + /* + * Make a new primary odb and link the old primary ODB in as an + * alternate + */ + new_odb = xcalloc(1, sizeof(*new_odb)); + new_odb->path = xstrdup(dir); + new_odb->will_destroy = will_destroy; + new_odb->next = the_repository->objects->odb; + the_repository->objects->odb = new_odb; + return new_odb->next; +} + +void restore_primary_odb(struct object_directory *restore_odb, const char *old_path) +{ + struct object_directory *cur_odb = the_repository->objects->odb; + + if (strcmp(old_path, cur_odb->path)) + BUG("expected %s as primary object store; found %s", + old_path, cur_odb->path); + + if (cur_odb->next != restore_odb) + BUG("we expect the old primary object store to be the first alternate"); + + the_repository->objects->odb = restore_odb; + free_object_directory(cur_odb); +} + /* * Compute the exact path an alternate is at and returns it. In case of * error NULL is returned and the human readable error is added to `err` @@ -1888,8 +1925,11 @@ int hash_object_file(const struct git_hash_algo *algo, const void *buf, /* Finalize a file on disk, and close it. */ static void close_loose_object(int fd) { - if (fsync_object_files) - fsync_or_die(fd, "loose object file"); + if (!the_repository->objects->odb->will_destroy) { + if (fsync_object_files) + fsync_or_die(fd, "loose object file"); + } + if (close(fd) != 0) die_errno(_("error when closing loose object file")); } diff --git a/object-store.h b/object-store.h index c5130d8baea..74b1b5872a6 100644 --- a/object-store.h +++ b/object-store.h @@ -27,6 +27,11 @@ struct object_directory { uint32_t loose_objects_subdir_seen[8]; /* 256 bits */ struct oidtree *loose_objects_cache; + /* + * This object store is ephemeral, so there is no need to fsync. + */ + int will_destroy; + /* * Path to the alternative object store. If this is a relative path, * it is relative to the current working directory. @@ -58,6 +63,17 @@ void add_to_alternates_file(const char *dir); */ void add_to_alternates_memory(const char *dir); +/* + * Replace the current writable object directory with the specified temporary + * object directory; returns the former primary object directory. + */ +struct object_directory *set_temporary_primary_odb(const char *dir, int will_destroy); + +/* + * Restore a previous ODB replaced by set_temporary_main_odb. + */ +void restore_primary_odb(struct object_directory *restore_odb, const char *old_path); + /* * Populate and return the loose object cache array corresponding to the * given object ID. @@ -68,6 +84,9 @@ struct oidtree *odb_loose_cache(struct object_directory *odb, /* Empty the loose object cache for the specified object directory. */ void odb_clear_loose_cache(struct object_directory *odb); +/* Clear and free the specified object directory */ +void free_object_directory(struct object_directory *odb); + struct packed_git { struct hashmap_entry packmap_ent; struct packed_git *next; diff --git a/object.c b/object.c index 4e85955a941..98635bc4043 100644 --- a/object.c +++ b/object.c @@ -513,7 +513,7 @@ struct raw_object_store *raw_object_store_new(void) return o; } -static void free_object_directory(struct object_directory *odb) +void free_object_directory(struct object_directory *odb) { free(odb->path); odb_clear_loose_cache(odb); diff --git a/tmp-objdir.c b/tmp-objdir.c index b8d880e3626..45d42a7bcf0 100644 --- a/tmp-objdir.c +++ b/tmp-objdir.c @@ -11,6 +11,7 @@ struct tmp_objdir { struct strbuf path; struct strvec env; + struct object_directory *prev_odb; }; /* @@ -38,6 +39,9 @@ static int tmp_objdir_destroy_1(struct tmp_objdir *t, int on_signal) if (t == the_tmp_objdir) the_tmp_objdir = NULL; + if (!on_signal && t->prev_odb) + restore_primary_odb(t->prev_odb, t->path.buf); + /* * This may use malloc via strbuf_grow(), but we should * have pre-grown t->path sufficiently so that this @@ -52,6 +56,7 @@ static int tmp_objdir_destroy_1(struct tmp_objdir *t, int on_signal) */ if (!on_signal) tmp_objdir_free(t); + return err; } @@ -121,7 +126,7 @@ static int setup_tmp_objdir(const char *root) return ret; } -struct tmp_objdir *tmp_objdir_create(void) +struct tmp_objdir *tmp_objdir_create(const char *prefix) { static int installed_handlers; struct tmp_objdir *t; @@ -129,11 +134,16 @@ struct tmp_objdir *tmp_objdir_create(void) if (the_tmp_objdir) BUG("only one tmp_objdir can be used at a time"); - t = xmalloc(sizeof(*t)); + t = xcalloc(1, sizeof(*t)); strbuf_init(&t->path, 0); strvec_init(&t->env); - strbuf_addf(&t->path, "%s/incoming-XXXXXX", get_object_directory()); + /* + * Use a string starting with tmp_ so that the builtin/prune.c code + * can recognize any stale objdirs left behind by a crash and delete + * them. + */ + strbuf_addf(&t->path, "%s/tmp_objdir-%s-XXXXXX", get_object_directory(), prefix); /* * Grow the strbuf beyond any filename we expect to be placed in it. @@ -269,6 +279,13 @@ int tmp_objdir_migrate(struct tmp_objdir *t) if (!t) return 0; + if (t->prev_odb) { + if (the_repository->objects->odb->will_destroy) + BUG("migrating an ODB that was marked for destruction"); + restore_primary_odb(t->prev_odb, t->path.buf); + t->prev_odb = NULL; + } + strbuf_addbuf(&src, &t->path); strbuf_addstr(&dst, get_object_directory()); @@ -292,3 +309,10 @@ void tmp_objdir_add_as_alternate(const struct tmp_objdir *t) { add_to_alternates_memory(t->path.buf); } + +void tmp_objdir_replace_primary_odb(struct tmp_objdir *t, int will_destroy) +{ + if (t->prev_odb) + BUG("the primary object database is already replaced"); + t->prev_odb = set_temporary_primary_odb(t->path.buf, will_destroy); +} diff --git a/tmp-objdir.h b/tmp-objdir.h index b1e45b4c75d..75754cbfba6 100644 --- a/tmp-objdir.h +++ b/tmp-objdir.h @@ -10,7 +10,7 @@ * * Example: * - * struct tmp_objdir *t = tmp_objdir_create(); + * struct tmp_objdir *t = tmp_objdir_create("incoming"); * if (!run_command_v_opt_cd_env(cmd, 0, NULL, tmp_objdir_env(t)) && * !tmp_objdir_migrate(t)) * printf("success!\n"); @@ -22,9 +22,10 @@ struct tmp_objdir; /* - * Create a new temporary object directory; returns NULL on failure. + * Create a new temporary object directory with the specified prefix; + * returns NULL on failure. */ -struct tmp_objdir *tmp_objdir_create(void); +struct tmp_objdir *tmp_objdir_create(const char *prefix); /* * Return a list of environment strings, suitable for use with @@ -51,4 +52,11 @@ int tmp_objdir_destroy(struct tmp_objdir *); */ void tmp_objdir_add_as_alternate(const struct tmp_objdir *); +/* + * Replaces the main object store in the current process with the temporary + * object directory and makes the former main object store an alternate. + * If will_destroy is nonzero, the object directory may not be migrated. + */ +void tmp_objdir_replace_primary_odb(struct tmp_objdir *, int will_destroy); + #endif /* TMP_OBJDIR_H */ From patchwork Mon Oct 4 16:57:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Neeraj Singh (WINDOWS-SFS)" X-Patchwork-Id: 12534345 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 77633C4332F for ; Mon, 4 Oct 2021 16:57:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5DAF9613CF for ; Mon, 4 Oct 2021 16:57:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237897AbhJDQ7n (ORCPT ); Mon, 4 Oct 2021 12:59:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56960 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237877AbhJDQ7l (ORCPT ); Mon, 4 Oct 2021 12:59:41 -0400 Received: from mail-wr1-x436.google.com (mail-wr1-x436.google.com [IPv6:2a00:1450:4864:20::436]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 151ACC061745 for ; Mon, 4 Oct 2021 09:57:52 -0700 (PDT) Received: by mail-wr1-x436.google.com with SMTP id o20so13935194wro.3 for ; Mon, 04 Oct 2021 09:57:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=RM2kaD4zPcEkoFHN9UJthugd2LTz0cfzsm58mTjVpOw=; b=FHa3Ihb3WyWkqL7zpJUfdRpxCJSyCt3vAv0eIhkC6Lr09zAYB3DVSqUQb2p2r0Lv2m 42s7Gt6DskEo5T8eM6HRzlBmioBYjZy/N/2wgp8MXjDtcQVuzmCFOmjZ7qY4Md9R8R8r Nw1spDMf2YCxfnQ0N4TcFy/T5eIMSlkV6vrNYkegpnN8UZROkKz9oqfmFQ5kmvdNRrhV hMwjhTQ48luJ5Rms3KlzmiRMOxZoIcaWySKNx7MPtS7qIQhZLEpD5UNDWk36bobUydGN w8tXqWu76ejla9jh17iafxyXUeK9Y6G4Q0jt2bmq+cQevul6D8yGV9y87J3PHrmus0/6 cKIA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=RM2kaD4zPcEkoFHN9UJthugd2LTz0cfzsm58mTjVpOw=; b=koGYdFgQ2Yx6TuTb9X1hpW/uv6PrhEotXoX6ZQ1opQ9dggSHa30dVMNqweocNl0kbo vCypM/AsbR4urfOncXPtTWst+6IoNjVBV3BH50rCKdPIpkgArBwuQWNI1ya1P7hG9uSH WKou2KW8AcZYWYdN4+Pwc8IFgg3Ih6GXwR+NNNnkrYxwU8uissw4W1rwIqBz7o/bS+95 idH5diMbtH3ooh8uvBUFu9v1O0wY6TlFbvoQm1cXv4zbPPny5rOix0aJmv0Z9XBlemBH 0OFqoA2njgjJuzTVHSi3z8xs4TizUUes6XEdgjfc980l62AEstofMiwif0vyr/JfDdiF gRUA== X-Gm-Message-State: AOAM531PZT5Xkx4eWBn1QI5axWxVuz/yavYPejPAdhZf7bLxqzX0g2DA jRA6mWtWkF1DpAeKMCk3bHYY/gki2aE= X-Google-Smtp-Source: ABdhPJz+1kDDy2vD9HPh3pP4bCLZbMK/6teVLW4GfW7BGtBjyoW2luNeWWJ7TARro43bLI4Szx+9AA== X-Received: by 2002:adf:bd8a:: with SMTP id l10mr4221728wrh.159.1633366670722; Mon, 04 Oct 2021 09:57:50 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id g21sm14666949wmk.10.2021.10.04.09.57.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Oct 2021 09:57:50 -0700 (PDT) Message-Id: In-Reply-To: References: Date: Mon, 04 Oct 2021 16:57:40 +0000 Subject: [PATCH v8 2/9] tmp-objdir: disable ref updates when replacing the primary odb Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Neeraj-Personal , Johannes Schindelin , Jeff King , Jeff Hostetler , Christoph Hellwig , =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsA==?= Bjarmason , "Randall S. Becker" , Bagas Sanjaya , Elijah Newren , "Neeraj K. Singh" , Neeraj Singh Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Neeraj Singh From: Neeraj Singh When creating a subprocess with a temporary ODB, we set the GIT_QUARANTINE_ENVIRONMENT env var to tell child Git processes not to update refs, since the tmp-objdir may go away. Introduce a similar mechanism for in-process temporary ODBs when we call tmp_objdir_replace_primary_odb. Now both mechanisms set the disable_ref_updates flag on the odb, which is queried by the ref_transaction_prepare function. Note: This change adds an assumption that the state of the_repository is relevant for any ref transaction that might be initiated. Unwinding this assumption should be straightforward by saving the relevant repository to query in the transaction or the ref_store. Peff's test case was invoking ref updates via the cachetextconv setting. That particular code silently does nothing when a ref update is forbidden. See the call to notes_cache_put in fill_textconv where errors are ignored. Reported-by: Jeff King Signed-off-by: Neeraj Singh --- environment.c | 4 ++++ object-file.c | 6 ++++++ object-store.h | 9 ++++++++- refs.c | 2 +- repository.c | 2 ++ repository.h | 1 + 6 files changed, 22 insertions(+), 2 deletions(-) diff --git a/environment.c b/environment.c index b4ba4fa22db..46ec5072c05 100644 --- a/environment.c +++ b/environment.c @@ -176,6 +176,10 @@ void setup_git_env(const char *git_dir) args.graft_file = getenv_safe(&to_free, GRAFT_ENVIRONMENT); args.index_file = getenv_safe(&to_free, INDEX_ENVIRONMENT); args.alternate_db = getenv_safe(&to_free, ALTERNATE_DB_ENVIRONMENT); + if (getenv(GIT_QUARANTINE_ENVIRONMENT)) { + args.disable_ref_updates = 1; + } + repo_set_gitdir(the_repository, git_dir, &args); strvec_clear(&to_free); diff --git a/object-file.c b/object-file.c index 990381abee5..f16441afb93 100644 --- a/object-file.c +++ b/object-file.c @@ -767,6 +767,12 @@ struct object_directory *set_temporary_primary_odb(const char *dir, int will_des */ new_odb = xcalloc(1, sizeof(*new_odb)); new_odb->path = xstrdup(dir); + + /* + * Disable ref updates while a temporary odb is active, since + * the objects in the database may roll back. + */ + new_odb->disable_ref_updates = 1; new_odb->will_destroy = will_destroy; new_odb->next = the_repository->objects->odb; the_repository->objects->odb = new_odb; diff --git a/object-store.h b/object-store.h index 74b1b5872a6..bd53bdf2f2e 100644 --- a/object-store.h +++ b/object-store.h @@ -27,10 +27,17 @@ struct object_directory { uint32_t loose_objects_subdir_seen[8]; /* 256 bits */ struct oidtree *loose_objects_cache; + /* + * This is a temporary object store created by the tmp_objdir + * facility. Disable ref updates since the objects in the store + * might be discarded on rollback. + */ + unsigned int disable_ref_updates : 1; + /* * This object store is ephemeral, so there is no need to fsync. */ - int will_destroy; + unsigned int will_destroy : 1; /* * Path to the alternative object store. If this is a relative path, diff --git a/refs.c b/refs.c index 8b9f7c3a80a..7c182607dcf 100644 --- a/refs.c +++ b/refs.c @@ -2126,7 +2126,7 @@ int ref_transaction_prepare(struct ref_transaction *transaction, break; } - if (getenv(GIT_QUARANTINE_ENVIRONMENT)) { + if (the_repository->objects->odb->disable_ref_updates) { strbuf_addstr(err, _("ref updates forbidden inside quarantine environment")); return -1; diff --git a/repository.c b/repository.c index 710a3b4bf87..18e0526da01 100644 --- a/repository.c +++ b/repository.c @@ -80,6 +80,8 @@ void repo_set_gitdir(struct repository *repo, expand_base_dir(&repo->objects->odb->path, o->object_dir, repo->commondir, "objects"); + repo->objects->odb->disable_ref_updates = o->disable_ref_updates; + free(repo->objects->alternate_db); repo->objects->alternate_db = xstrdup_or_null(o->alternate_db); expand_base_dir(&repo->graft_file, o->graft_file, diff --git a/repository.h b/repository.h index 3740c93bc0f..77316367d99 100644 --- a/repository.h +++ b/repository.h @@ -162,6 +162,7 @@ struct set_gitdir_args { const char *graft_file; const char *index_file; const char *alternate_db; + int disable_ref_updates; }; void repo_set_gitdir(struct repository *repo, const char *root, From patchwork Mon Oct 4 16:57:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Neeraj Singh (WINDOWS-SFS)" X-Patchwork-Id: 12534347 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 93AFDC433EF for ; Mon, 4 Oct 2021 16:58:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7898B613CF for ; Mon, 4 Oct 2021 16:58:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237877AbhJDQ7v (ORCPT ); Mon, 4 Oct 2021 12:59:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56962 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237878AbhJDQ7m (ORCPT ); Mon, 4 Oct 2021 12:59:42 -0400 Received: from mail-wm1-x334.google.com (mail-wm1-x334.google.com [IPv6:2a00:1450:4864:20::334]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 978F4C061746 for ; Mon, 4 Oct 2021 09:57:52 -0700 (PDT) Received: by mail-wm1-x334.google.com with SMTP id t16-20020a1c7710000000b003049690d882so20216802wmi.5 for ; Mon, 04 Oct 2021 09:57:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=0YFH/7O9dujfKmmu6ZRk/KJCH7LOCPzTEaGTMr5K95k=; b=dbtWF86oX7UdSpUukdxEKgC1IYhk/Oz5U86Z/GB4z/vTIkAEPlWdiE3vJGrwneEIFE Crz532JdtDJZXqzX2hALBjCBHgKuIE/VgbKqJpKWX3FFH0oKH26zW+0/VXs8YGR4+R68 H3diBCX0C91Dpyjv6nULLJMGagmNuvazy0skeNhAXiX4X2tasZ+6KI2GFQit6aHNKsDD 4dju8TVZB7Ytks1ehtSYQWkV1J6T0VdLd4XkP0hkNvYbELreZEH3g1TYS6AukMSQedKY T1CG1ELIPXpTOuRHoHsDSv/cJ8Z+sNN4pdyMDIB9lRJG6k4aShD/BXhROgReeyITZbbt cLVQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=0YFH/7O9dujfKmmu6ZRk/KJCH7LOCPzTEaGTMr5K95k=; b=Eojm1A7FW6yQoM4DpoqoduL/0Xa1HKXgiQICxnbMqc72IGtOIY9j/kLUfGWYMOEJUH L9jWwBDciHSnRS3XvJwQF/HQyILuvKYH044I5Ei3/QOGJttVmcmrmEU3vydDQq43/+Vk 9fCeUaknfrIyLENZ9CvE0TX1my60QipKQan9yIG+SfMever0tHVMOCv9UrRDQkJ45PEH JXouV581zEupeJ6/vX5qjHroNJfjpYFPK7DQQ8MY6OYrjZ2eK8AMew1z3/sZYkXr0z8I ty/DOWty97GPaMJTAkggZ9ik9KlDfx+2rK9mIl4dhqRFjLv+QjB2zSLDaGzFBNixuWjx KGpA== X-Gm-Message-State: AOAM532LjVqfDaup6321CKOvGGou+t4y2h0l5eoeR9nV08PgrHeTpMHc mO5EFRgsnonL/EXdZHhest/s1xJrDy4= X-Google-Smtp-Source: ABdhPJxzblJRs+AEUcIbZYHKdhDyC8O9uB+rHRSSZOhiH0nxYidaq0U4RXy63Qurhk9b+nmJp7M7aw== X-Received: by 2002:a05:600c:350a:: with SMTP id h10mr19444070wmq.163.1633366671245; Mon, 04 Oct 2021 09:57:51 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id o8sm8494727wme.38.2021.10.04.09.57.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Oct 2021 09:57:50 -0700 (PDT) Message-Id: <9335646ed91d3472191b8be233839b3a583c9718.1633366667.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Mon, 04 Oct 2021 16:57:41 +0000 Subject: [PATCH v8 3/9] bulk-checkin: rename 'state' variable and separate 'plugged' boolean Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Neeraj-Personal , Johannes Schindelin , Jeff King , Jeff Hostetler , Christoph Hellwig , =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsA==?= Bjarmason , "Randall S. Becker" , Bagas Sanjaya , Elijah Newren , "Neeraj K. Singh" , Neeraj Singh Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Neeraj Singh From: Neeraj Singh Preparation for adding bulk-fsync to the bulk-checkin.c infrastructure. * Rename 'state' variable to 'bulk_checkin_state', since we will later be adding 'bulk_fsync_state'. This also makes the variable easier to find in the debugger, since the name is more unique. * Move the 'plugged' data member of 'bulk_checkin_state' into a separate static variable. Doing this avoids resetting the variable in finish_bulk_checkin when zeroing the 'bulk_checkin_state'. As-is, we seem to unintentionally disable the plugging functionality the first time a new packfile must be created due to packfile size limits. While disabling the plugging state only results in suboptimal behavior for the current code, it would be fatal for the bulk-fsync functionality later in this patch series. Signed-off-by: Neeraj Singh --- bulk-checkin.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/bulk-checkin.c b/bulk-checkin.c index 8785b2ac806..6ae18401e04 100644 --- a/bulk-checkin.c +++ b/bulk-checkin.c @@ -10,9 +10,9 @@ #include "packfile.h" #include "object-store.h" -static struct bulk_checkin_state { - unsigned plugged:1; +static int bulk_checkin_plugged; +static struct bulk_checkin_state { char *pack_tmp_name; struct hashfile *f; off_t offset; @@ -21,7 +21,7 @@ static struct bulk_checkin_state { struct pack_idx_entry **written; uint32_t alloc_written; uint32_t nr_written; -} state; +} bulk_checkin_state; static void finish_tmp_packfile(struct strbuf *basename, const char *pack_tmp_name, @@ -277,21 +277,23 @@ int index_bulk_checkin(struct object_id *oid, int fd, size_t size, enum object_type type, const char *path, unsigned flags) { - int status = deflate_to_pack(&state, oid, fd, size, type, + int status = deflate_to_pack(&bulk_checkin_state, oid, fd, size, type, path, flags); - if (!state.plugged) - finish_bulk_checkin(&state); + if (!bulk_checkin_plugged) + finish_bulk_checkin(&bulk_checkin_state); return status; } void plug_bulk_checkin(void) { - state.plugged = 1; + assert(!bulk_checkin_plugged); + bulk_checkin_plugged = 1; } void unplug_bulk_checkin(void) { - state.plugged = 0; - if (state.f) - finish_bulk_checkin(&state); + assert(bulk_checkin_plugged); + bulk_checkin_plugged = 0; + if (bulk_checkin_state.f) + finish_bulk_checkin(&bulk_checkin_state); } From patchwork Mon Oct 4 16:57:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Neeraj Singh (WINDOWS-SFS)" X-Patchwork-Id: 12534355 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D81E1C433F5 for ; Mon, 4 Oct 2021 16:58:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A71D8613CF for ; Mon, 4 Oct 2021 16:58:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237948AbhJDQ7w (ORCPT ); Mon, 4 Oct 2021 12:59:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56970 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237884AbhJDQ7m (ORCPT ); Mon, 4 Oct 2021 12:59:42 -0400 Received: from mail-wm1-x32f.google.com (mail-wm1-x32f.google.com [IPv6:2a00:1450:4864:20::32f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6699CC061749 for ; Mon, 4 Oct 2021 09:57:53 -0700 (PDT) Received: by mail-wm1-x32f.google.com with SMTP id g193-20020a1c20ca000000b0030d55f1d984so8996474wmg.3 for ; Mon, 04 Oct 2021 09:57:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=673udaiQu1W9lf18GyEjHb4LZBpGTf79FXfKBRPHB58=; b=q2FEomtyQTIe3lqfLD/UWtpCXlTBdDw2EWstdcjJWsQpiZ3mUPNOb2kf8Cox5BiqB5 CBVW1bPDqPn/4sHQw2j4c9Gc2kmBPMaT4PCAnCa17BDAXELcemi7OOrd8d6ohpjH4vKF iEmk/yzM7bQXGSE/bMwIUxkCZy8cdFVnY9agkOJTJyUBM45iQPz+78RtRIdKX5y5jlim ETk93J0Z7Qbn2ys8kGsLvzQjPKHZYK8lW9hBOd2TBqofvYuLxohVTolcj2mMXaGDWjvo 5vASQlLFR9FBgA/FFf7rrkwQGXtTBtgIBwh1wk5MCKBEiqgBf3+2cszEjqTYKbm8spD1 LzBA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=673udaiQu1W9lf18GyEjHb4LZBpGTf79FXfKBRPHB58=; b=FOqyzd7KeKz/qLR384R0Ci3l6bFlaQeBSVC9FyNFyu7POBo17cvCWsPbRQvaVaR6at 8bQMrgcb8HIaowaa6R46cjzaab0p3JzcqWTqIfKKlgGGbzXPB1Q+bOtCI91vMEIsJngV s+Siso2p1JlQBcY033ucmw6SlylBXH3lVoJufBW3qeXJ48wtIQCnXZZBW02qjPJY3stv aLqjrDv92h0baOGhw6hgx/VrEUMYBjjr10M0U/kNVNNLZDOpkjPaG4nAoGBkIfdgTaV/ ZUXXvo3zhpGRqyIYZjoFpVj0gK9qtSFMJxvo/R9D87DyuaUxLAcmQozPe3U0ejiBOVYa zVcg== X-Gm-Message-State: AOAM530hV8Ig+1tehhEkmF7wQa7sKybGW/+KOOJ9vAgKXxrka38tqING d5Kq+AFoZwp7i2cWATAS159CuwYJ/uc= X-Google-Smtp-Source: ABdhPJwaUkHk8McJ6glvHb7ZFMheBnbGG5OIiOViCSFHsKMDo+q39QLG1kL5X7dDpNi6oWJplYwtLA== X-Received: by 2002:a7b:c20f:: with SMTP id x15mr18647000wmi.10.1633366671905; Mon, 04 Oct 2021 09:57:51 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id i6sm4599851wrv.61.2021.10.04.09.57.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Oct 2021 09:57:51 -0700 (PDT) Message-Id: In-Reply-To: References: Date: Mon, 04 Oct 2021 16:57:42 +0000 Subject: [PATCH v8 4/9] core.fsyncobjectfiles: batched disk flushes Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Neeraj-Personal , Johannes Schindelin , Jeff King , Jeff Hostetler , Christoph Hellwig , =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsA==?= Bjarmason , "Randall S. Becker" , Bagas Sanjaya , Elijah Newren , "Neeraj K. Singh" , Neeraj Singh Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Neeraj Singh From: Neeraj Singh When adding many objects to a repo with core.fsyncObjectFiles set to true, the cost of fsync'ing each object file can become prohibitive. One major source of the cost of fsync is the implied flush of the hardware writeback cache within the disk drive. Fortunately, Windows, and macOS offer mechanisms to write data from the filesystem page cache without initiating a hardware flush. Linux has the sync_file_range API, which issues a pagecache writeback request reliably after version 5.2. This patch introduces a new 'core.fsyncObjectFiles = batch' option that batches up hardware flushes. It hooks into the bulk-checkin plugging and unplugging functionality and takes advantage of tmp-objdir. When the new mode is enabled do the following for each new object: 1. Create the object in a tmp-objdir. 2. Issue a pagecache writeback request and wait for it to complete. At the end of the entire transaction when unplugging bulk checkin: 1. Issue an fsync against a dummy file to flush the hardware writeback cache, which should by now have processed the tmp-objdir writes. 2. Rename all of the tmp-objdir files to their final names. 3. When updating the index and/or refs, we assume that Git will issue another fsync internal to that operation. This is not the case today, but may be a good extension to those components. On a filesystem with a singular journal that is updated during name operations (e.g. create, link, rename, etc), such as NTFS, HFS+, or XFS we would expect the fsync to trigger a journal writeout so that this sequence is enough to ensure that the user's data is durable by the time the git command returns. This change also updates the macOS code to trigger a real hardware flush via fnctl(fd, F_FULLFSYNC) when fsync_or_die is called. Previously, on macOS there was no guarantee of durability since a simple fsync(2) call does not flush any hardware caches. _Performance numbers_: Linux - Hyper-V VM running Kernel 5.11 (Ubuntu 20.04) on a fast SSD. Mac - macOS 11.5.1 running on a Mac mini on a 1TB Apple SSD. Windows - Same host as Linux, a preview version of Windows 11. This number is from a patch later in the series. Adding 500 files to the repo with 'git add' Times reported in seconds. core.fsyncObjectFiles | Linux | Mac | Windows ----------------------|-------|-------|-------- false | 0.06 | 0.35 | 0.61 true | 1.88 | 11.18 | 2.47 batch | 0.15 | 0.41 | 1.53 Signed-off-by: Neeraj Singh --- Documentation/config/core.txt | 29 +++++++++++---- Makefile | 6 ++++ bulk-checkin.c | 68 +++++++++++++++++++++++++++++++++++ bulk-checkin.h | 2 ++ cache.h | 8 ++++- config.c | 7 +++- config.mak.uname | 1 + configure.ac | 8 +++++ environment.c | 2 +- git-compat-util.h | 7 ++++ object-file.c | 12 ++++++- wrapper.c | 44 +++++++++++++++++++++++ write-or-die.c | 2 +- 13 files changed, 185 insertions(+), 11 deletions(-) diff --git a/Documentation/config/core.txt b/Documentation/config/core.txt index c04f62a54a1..200b4d9f06e 100644 --- a/Documentation/config/core.txt +++ b/Documentation/config/core.txt @@ -548,12 +548,29 @@ core.whitespace:: errors. The default tab width is 8. Allowed values are 1 to 63. core.fsyncObjectFiles:: - This boolean will enable 'fsync()' when writing object files. -+ -This is a total waste of time and effort on a filesystem that orders -data writes properly, but can be useful for filesystems that do not use -journalling (traditional UNIX filesystems) or that only journal metadata -and not file contents (OS X's HFS+, or Linux ext3 with "data=writeback"). + A value indicating the level of effort Git will expend in + trying to make objects added to the repo durable in the event + of an unclean system shutdown. This setting currently only + controls loose objects in the object store, so updates to any + refs or the index may not be equally durable. ++ +* `false` allows data to remain in file system caches according to + operating system policy, whence it may be lost if the system loses power + or crashes. +* `true` triggers a data integrity flush for each loose object added to the + object store. This is the safest setting that is likely to ensure durability + across all operating systems and file systems that honor the 'fsync' system + call. However, this setting comes with a significant performance cost on + common hardware. Git does not currently fsync parent directories for + newly-added files, so some filesystems may still allow data to be lost on + system crash. +* `batch` enables an experimental mode that uses interfaces available in some + operating systems to write loose object data with a minimal set of FLUSH + CACHE (or equivalent) commands sent to the storage controller. If the + operating system interfaces are not available, this mode behaves the same as + `true`. This mode is expected to be as safe as `true` on macOS for repos + stored on HFS+ or APFS filesystems and on Windows for repos stored on NTFS or + ReFS. core.preloadIndex:: Enable parallel index preload for operations like 'git diff' diff --git a/Makefile b/Makefile index a9f9b689f0c..313b3dc7cd6 100644 --- a/Makefile +++ b/Makefile @@ -406,6 +406,8 @@ all:: # # Define HAVE_CLOCK_MONOTONIC if your platform has CLOCK_MONOTONIC. # +# Define HAVE_SYNC_FILE_RANGE if your platform has sync_file_range. +# # Define NEEDS_LIBRT if your platform requires linking with librt (glibc version # before 2.17) for clock_gettime and CLOCK_MONOTONIC. # @@ -1874,6 +1876,10 @@ ifdef HAVE_CLOCK_MONOTONIC BASIC_CFLAGS += -DHAVE_CLOCK_MONOTONIC endif +ifdef HAVE_SYNC_FILE_RANGE + BASIC_CFLAGS += -DHAVE_SYNC_FILE_RANGE +endif + ifdef NEEDS_LIBRT EXTLIBS += -lrt endif diff --git a/bulk-checkin.c b/bulk-checkin.c index 6ae18401e04..4deee1af46e 100644 --- a/bulk-checkin.c +++ b/bulk-checkin.c @@ -3,14 +3,20 @@ */ #include "cache.h" #include "bulk-checkin.h" +#include "lockfile.h" #include "repository.h" #include "csum-file.h" #include "pack.h" #include "strbuf.h" +#include "string-list.h" +#include "tmp-objdir.h" #include "packfile.h" #include "object-store.h" static int bulk_checkin_plugged; +static int needs_batch_fsync; + +static struct tmp_objdir *bulk_fsync_objdir; static struct bulk_checkin_state { char *pack_tmp_name; @@ -79,6 +85,34 @@ clear_exit: reprepare_packed_git(the_repository); } +/* + * Cleanup after batch-mode fsync_object_files. + */ +static void do_batch_fsync(void) +{ + /* + * Issue a full hardware flush against a temporary file to ensure + * that all objects are durable before any renames occur. The code in + * fsync_loose_object_bulk_checkin has already issued a writeout + * request, but it has not flushed any writeback cache in the storage + * hardware. + */ + + if (needs_batch_fsync) { + struct strbuf temp_path = STRBUF_INIT; + struct tempfile *temp; + + strbuf_addf(&temp_path, "%s/bulk_fsync_XXXXXX", get_object_directory()); + temp = xmks_tempfile(temp_path.buf); + fsync_or_die(get_tempfile_fd(temp), get_tempfile_path(temp)); + delete_tempfile(&temp); + strbuf_release(&temp_path); + } + + if (bulk_fsync_objdir) + tmp_objdir_migrate(bulk_fsync_objdir); +} + static int already_written(struct bulk_checkin_state *state, struct object_id *oid) { int i; @@ -273,6 +307,25 @@ static int deflate_to_pack(struct bulk_checkin_state *state, return 0; } +void fsync_loose_object_bulk_checkin(int fd) +{ + assert(fsync_object_files == FSYNC_OBJECT_FILES_BATCH); + + /* + * If we have a plugged bulk checkin, we issue a call that + * cleans the filesystem page cache but avoids a hardware flush + * command. Later on we will issue a single hardware flush + * before as part of do_batch_fsync. + */ + if (bulk_checkin_plugged && + git_fsync(fd, FSYNC_WRITEOUT_ONLY) >= 0) { + if (!needs_batch_fsync) + needs_batch_fsync = 1; + } else { + fsync_or_die(fd, "loose object file"); + } +} + int index_bulk_checkin(struct object_id *oid, int fd, size_t size, enum object_type type, const char *path, unsigned flags) @@ -287,6 +340,19 @@ int index_bulk_checkin(struct object_id *oid, void plug_bulk_checkin(void) { assert(!bulk_checkin_plugged); + + /* + * A temporary object directory is used to hold the files + * while they are not fsynced. + */ + if (fsync_object_files == FSYNC_OBJECT_FILES_BATCH) { + bulk_fsync_objdir = tmp_objdir_create("bulk-fsync"); + if (!bulk_fsync_objdir) + die(_("Could not create temporary object directory for core.fsyncobjectfiles=batch")); + + tmp_objdir_replace_primary_odb(bulk_fsync_objdir, 0); + } + bulk_checkin_plugged = 1; } @@ -296,4 +362,6 @@ void unplug_bulk_checkin(void) bulk_checkin_plugged = 0; if (bulk_checkin_state.f) finish_bulk_checkin(&bulk_checkin_state); + + do_batch_fsync(); } diff --git a/bulk-checkin.h b/bulk-checkin.h index b26f3dc3b74..08f292379b6 100644 --- a/bulk-checkin.h +++ b/bulk-checkin.h @@ -6,6 +6,8 @@ #include "cache.h" +void fsync_loose_object_bulk_checkin(int fd); + int index_bulk_checkin(struct object_id *oid, int fd, size_t size, enum object_type type, const char *path, unsigned flags); diff --git a/cache.h b/cache.h index f6295f3b048..1ed8137b5e6 100644 --- a/cache.h +++ b/cache.h @@ -984,7 +984,13 @@ void reset_shared_repository(void); extern int read_replace_refs; extern char *git_replace_ref_base; -extern int fsync_object_files; +enum fsync_object_files_mode { + FSYNC_OBJECT_FILES_OFF, + FSYNC_OBJECT_FILES_ON, + FSYNC_OBJECT_FILES_BATCH +}; + +extern enum fsync_object_files_mode fsync_object_files; extern int core_preload_index; extern int precomposed_unicode; extern int protect_hfs; diff --git a/config.c b/config.c index 2edf835262f..8315d020eeb 100644 --- a/config.c +++ b/config.c @@ -1506,7 +1506,12 @@ static int git_default_core_config(const char *var, const char *value, void *cb) } if (!strcmp(var, "core.fsyncobjectfiles")) { - fsync_object_files = git_config_bool(var, value); + if (value && !strcmp(value, "batch")) + fsync_object_files = FSYNC_OBJECT_FILES_BATCH; + else if (git_config_bool(var, value)) + fsync_object_files = FSYNC_OBJECT_FILES_ON; + else + fsync_object_files = FSYNC_OBJECT_FILES_OFF; return 0; } diff --git a/config.mak.uname b/config.mak.uname index 76516aaa9a5..e6d482fbcc6 100644 --- a/config.mak.uname +++ b/config.mak.uname @@ -53,6 +53,7 @@ ifeq ($(uname_S),Linux) HAVE_CLOCK_MONOTONIC = YesPlease # -lrt is needed for clock_gettime on glibc <= 2.16 NEEDS_LIBRT = YesPlease + HAVE_SYNC_FILE_RANGE = YesPlease HAVE_GETDELIM = YesPlease SANE_TEXT_GREP=-a FREAD_READS_DIRECTORIES = UnfortunatelyYes diff --git a/configure.ac b/configure.ac index 031e8d3fee8..c711037d625 100644 --- a/configure.ac +++ b/configure.ac @@ -1090,6 +1090,14 @@ AC_COMPILE_IFELSE([CLOCK_MONOTONIC_SRC], [AC_MSG_RESULT([no]) HAVE_CLOCK_MONOTONIC=]) GIT_CONF_SUBST([HAVE_CLOCK_MONOTONIC]) + +# +# Define HAVE_SYNC_FILE_RANGE=YesPlease if sync_file_range is available. +GIT_CHECK_FUNC(sync_file_range, + [HAVE_SYNC_FILE_RANGE=YesPlease], + [HAVE_SYNC_FILE_RANGE]) +GIT_CONF_SUBST([HAVE_SYNC_FILE_RANGE]) + # # Define NO_SETITIMER if you don't have setitimer. GIT_CHECK_FUNC(setitimer, diff --git a/environment.c b/environment.c index 46ec5072c05..0ace9fa2167 100644 --- a/environment.c +++ b/environment.c @@ -42,7 +42,7 @@ const char *git_attributes_file; const char *git_hooks_path; int zlib_compression_level = Z_BEST_SPEED; int pack_compression_level = Z_DEFAULT_COMPRESSION; -int fsync_object_files; +enum fsync_object_files_mode fsync_object_files; size_t packed_git_window_size = DEFAULT_PACKED_GIT_WINDOW_SIZE; size_t packed_git_limit = DEFAULT_PACKED_GIT_LIMIT; size_t delta_base_cache_limit = 96 * 1024 * 1024; diff --git a/git-compat-util.h b/git-compat-util.h index 7c99eef6612..9daee873782 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -1213,6 +1213,13 @@ __attribute__((format (printf, 1, 2))) NORETURN void BUG(const char *fmt, ...); #endif +enum fsync_action { + FSYNC_WRITEOUT_ONLY, + FSYNC_HARDWARE_FLUSH +}; + +int git_fsync(int fd, enum fsync_action action); + /* * Preserves errno, prints a message, but gives no warning for ENOENT. * Returns 0 on success, which includes trying to unlink an object that does diff --git a/object-file.c b/object-file.c index f16441afb93..b035d88f309 100644 --- a/object-file.c +++ b/object-file.c @@ -1932,8 +1932,18 @@ int hash_object_file(const struct git_hash_algo *algo, const void *buf, static void close_loose_object(int fd) { if (!the_repository->objects->odb->will_destroy) { - if (fsync_object_files) + switch (fsync_object_files) { + case FSYNC_OBJECT_FILES_OFF: + break; + case FSYNC_OBJECT_FILES_ON: fsync_or_die(fd, "loose object file"); + break; + case FSYNC_OBJECT_FILES_BATCH: + fsync_loose_object_bulk_checkin(fd); + break; + default: + BUG("Invalid fsync_object_files mode."); + } } if (close(fd) != 0) diff --git a/wrapper.c b/wrapper.c index 7c6586af321..bb4f9f043ce 100644 --- a/wrapper.c +++ b/wrapper.c @@ -540,6 +540,50 @@ int xmkstemp_mode(char *filename_template, int mode) return fd; } +int git_fsync(int fd, enum fsync_action action) +{ + switch (action) { + case FSYNC_WRITEOUT_ONLY: + +#ifdef __APPLE__ + /* + * on macOS, fsync just causes filesystem cache writeback but does not + * flush hardware caches. + */ + return fsync(fd); +#endif + +#ifdef HAVE_SYNC_FILE_RANGE + /* + * On linux 2.6.17 and above, sync_file_range is the way to issue + * a writeback without a hardware flush. An offset of 0 and size of 0 + * indicates writeout of the entire file and the wait flags ensure that all + * dirty data is written to the disk (potentially in a disk-side cache) + * before we continue. + */ + + return sync_file_range(fd, 0, 0, SYNC_FILE_RANGE_WAIT_BEFORE | + SYNC_FILE_RANGE_WRITE | + SYNC_FILE_RANGE_WAIT_AFTER); +#endif + + errno = ENOSYS; + return -1; + + case FSYNC_HARDWARE_FLUSH: + +#ifdef __APPLE__ + return fcntl(fd, F_FULLFSYNC); +#else + return fsync(fd); +#endif + + default: + BUG("unexpected git_fsync(%d) call", action); + } + +} + static int warn_if_unremovable(const char *op, const char *file, int rc) { int err; diff --git a/write-or-die.c b/write-or-die.c index 0b1ec8190b6..cc8291d9794 100644 --- a/write-or-die.c +++ b/write-or-die.c @@ -57,7 +57,7 @@ void fprintf_or_die(FILE *f, const char *fmt, ...) void fsync_or_die(int fd, const char *msg) { - while (fsync(fd) < 0) { + while (git_fsync(fd, FSYNC_HARDWARE_FLUSH) < 0) { if (errno != EINTR) die_errno("fsync error on '%s'", msg); } From patchwork Mon Oct 4 16:57:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Neeraj Singh (WINDOWS-SFS)" X-Patchwork-Id: 12534349 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8D822C433EF for ; Mon, 4 Oct 2021 16:58:06 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7B68A61357 for ; Mon, 4 Oct 2021 16:58:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237960AbhJDQ7y (ORCPT ); Mon, 4 Oct 2021 12:59:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56976 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237889AbhJDQ7n (ORCPT ); Mon, 4 Oct 2021 12:59:43 -0400 Received: from mail-wm1-x334.google.com (mail-wm1-x334.google.com [IPv6:2a00:1450:4864:20::334]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EDE22C061753 for ; Mon, 4 Oct 2021 09:57:53 -0700 (PDT) Received: by mail-wm1-x334.google.com with SMTP id s24so13980361wmh.4 for ; Mon, 04 Oct 2021 09:57:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=fv7nQ5ZUwa4uFFNumJcqLSj/tyOInbTAFP+n8tQn3ko=; b=LZ/LYkNqQ3O9dyC60IxG2iRCgYz0XAor8wzW0gw684NiJU6BLyr2b6reyJ1rPO1oMZ h+NkFjUrXudHUqBe4SyvepFjIRsQEV9UZT115it8gu4j71ZGdmrmhxkI2KU9WE2Ms9p6 n4GZfA8oU56mX9pbrF7wxjChX5Af8+8D11vofYdhSVPFOhVyehPLGiKfRIerCmGocQn8 xv7G7PyPlrtn5tQVGhbBlsKItwPSKuQNK0wLeTYTkExw34rDGAcQ10NmlzF8mpwj1hav C09MwzqPWANIl8aCaoXnxupCJW6hyoS9+AL2/d8x3ire3foooHUXyvkMS3bp/v0fcu/G O8kw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=fv7nQ5ZUwa4uFFNumJcqLSj/tyOInbTAFP+n8tQn3ko=; b=TyLVRqV8Jpe7mNkmoFnEWkcEV64PiuRbNaI6CXRfbkNt7jwKmkbX+njXVBjpKYJd5m E+S7POwx8ZyYzg2pDnybko/rdHffamT7qSg+bqN1K8sazpQekNePkL2izA3pWw+OiMt3 Dm6UTMbg7SjWkObB9fAKONOyM8HVe8Dj3xalK2nFkm8383q7N8Qvdg2ObHCpI5m2gA65 i9mO4Y60Tb31iEKTt5JoJ27B7BYtPQAgA5sDsFswLrGNJjQJye6URiP5E/PUEz/bySDl I49QLfMMXhoqCcbDScQOvPB4X2VO3gRN/pXfZhXlkVyone5Oh6D3w0gfBIXT88bvhRV5 OEgg== X-Gm-Message-State: AOAM530U7/15ot5K6xrpjPpZ2hTioJJiDonQ9jZZ3D3xb1f8gIftgzB9 qn03juzBlRmcMmruCZ/Qhc9e9dlDM88= X-Google-Smtp-Source: ABdhPJzSvIW+3O+cfFFsf2YkujGCYfKRs9tQ8q3RfyWkBr+rYb9JpMGNsc3kf9RsBP1T8H5BxsNxvw== X-Received: by 2002:a05:600c:21ca:: with SMTP id x10mr13281615wmj.106.1633366672559; Mon, 04 Oct 2021 09:57:52 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id i14sm2110824wmq.29.2021.10.04.09.57.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Oct 2021 09:57:52 -0700 (PDT) Message-Id: <8df32eaaa9a9c41b6d9d49a50630952f14f33495.1633366667.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Mon, 04 Oct 2021 16:57:43 +0000 Subject: [PATCH v8 5/9] core.fsyncobjectfiles: add windows support for batch mode Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Neeraj-Personal , Johannes Schindelin , Jeff King , Jeff Hostetler , Christoph Hellwig , =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsA==?= Bjarmason , "Randall S. Becker" , Bagas Sanjaya , Elijah Newren , "Neeraj K. Singh" , Neeraj Singh Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Neeraj Singh From: Neeraj Singh This commit adds a win32 implementation for fsync_no_flush that is called git_fsync. The 'NtFlushBuffersFileEx' function being called is available since Windows 8. If the function is not available, we return -1 and Git falls back to doing a full fsync. The operating system is told to flush data only without a hardware flush primitive. A later full fsync will cause the metadata log to be flushed and then the disk cache to be flushed on NTFS and ReFS. Other filesystems will treat this as a full flush operation. I added a new file here for this system call so as not to conflict with downstream changes in the git-for-windows repository related to fscache. Signed-off-by: Neeraj Singh --- compat/mingw.h | 3 +++ compat/win32/flush.c | 28 ++++++++++++++++++++++++++++ config.mak.uname | 2 ++ contrib/buildsystems/CMakeLists.txt | 3 ++- wrapper.c | 4 ++++ 5 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 compat/win32/flush.c diff --git a/compat/mingw.h b/compat/mingw.h index c9a52ad64a6..6074a3d3ced 100644 --- a/compat/mingw.h +++ b/compat/mingw.h @@ -329,6 +329,9 @@ int mingw_getpagesize(void); #define getpagesize mingw_getpagesize #endif +int win32_fsync_no_flush(int fd); +#define fsync_no_flush win32_fsync_no_flush + struct rlimit { unsigned int rlim_cur; }; diff --git a/compat/win32/flush.c b/compat/win32/flush.c new file mode 100644 index 00000000000..75324c24ee7 --- /dev/null +++ b/compat/win32/flush.c @@ -0,0 +1,28 @@ +#include "../../git-compat-util.h" +#include +#include "lazyload.h" + +int win32_fsync_no_flush(int fd) +{ + IO_STATUS_BLOCK io_status; + +#define FLUSH_FLAGS_FILE_DATA_ONLY 1 + + DECLARE_PROC_ADDR(ntdll.dll, NTSTATUS, NtFlushBuffersFileEx, + HANDLE FileHandle, ULONG Flags, PVOID Parameters, ULONG ParameterSize, + PIO_STATUS_BLOCK IoStatusBlock); + + if (!INIT_PROC_ADDR(NtFlushBuffersFileEx)) { + errno = ENOSYS; + return -1; + } + + memset(&io_status, 0, sizeof(io_status)); + if (NtFlushBuffersFileEx((HANDLE)_get_osfhandle(fd), FLUSH_FLAGS_FILE_DATA_ONLY, + NULL, 0, &io_status)) { + errno = EINVAL; + return -1; + } + + return 0; +} diff --git a/config.mak.uname b/config.mak.uname index e6d482fbcc6..34c93314a50 100644 --- a/config.mak.uname +++ b/config.mak.uname @@ -451,6 +451,7 @@ endif CFLAGS = BASIC_CFLAGS = -nologo -I. -Icompat/vcbuild/include -DWIN32 -D_CONSOLE -DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE COMPAT_OBJS = compat/msvc.o compat/winansi.o \ + compat/win32/flush.o \ compat/win32/path-utils.o \ compat/win32/pthread.o compat/win32/syslog.o \ compat/win32/trace2_win32_process_info.o \ @@ -626,6 +627,7 @@ ifneq (,$(findstring MINGW,$(uname_S))) COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\" COMPAT_OBJS += compat/mingw.o compat/winansi.o \ compat/win32/trace2_win32_process_info.o \ + compat/win32/flush.o \ compat/win32/path-utils.o \ compat/win32/pthread.o compat/win32/syslog.o \ compat/win32/dirent.o diff --git a/contrib/buildsystems/CMakeLists.txt b/contrib/buildsystems/CMakeLists.txt index 171b4124afe..b573a5ee122 100644 --- a/contrib/buildsystems/CMakeLists.txt +++ b/contrib/buildsystems/CMakeLists.txt @@ -261,7 +261,8 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Windows") NOGDI OBJECT_CREATION_MODE=1 __USE_MINGW_ANSI_STDIO=0 USE_NED_ALLOCATOR OVERRIDE_STRDUP MMAP_PREVENTS_DELETE USE_WIN32_MMAP UNICODE _UNICODE HAVE_WPGMPTR ENSURE_MSYSTEM_IS_SET) - list(APPEND compat_SOURCES compat/mingw.c compat/winansi.c compat/win32/path-utils.c + list(APPEND compat_SOURCES compat/mingw.c compat/winansi.c + compat/win32/flush.c compat/win32/path-utils.c compat/win32/pthread.c compat/win32mmap.c compat/win32/syslog.c compat/win32/trace2_win32_process_info.c compat/win32/dirent.c compat/nedmalloc/nedmalloc.c compat/strdup.c) diff --git a/wrapper.c b/wrapper.c index bb4f9f043ce..1a1e2fba9c9 100644 --- a/wrapper.c +++ b/wrapper.c @@ -567,6 +567,10 @@ int git_fsync(int fd, enum fsync_action action) SYNC_FILE_RANGE_WAIT_AFTER); #endif +#ifdef fsync_no_flush + return fsync_no_flush(fd); +#endif + errno = ENOSYS; return -1; From patchwork Mon Oct 4 16:57:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Neeraj Singh (WINDOWS-SFS)" X-Patchwork-Id: 12534351 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BDE0BC4332F for ; Mon, 4 Oct 2021 16:58:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AB71D61264 for ; Mon, 4 Oct 2021 16:58:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237912AbhJDQ7z (ORCPT ); Mon, 4 Oct 2021 12:59:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57006 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237917AbhJDQ7u (ORCPT ); Mon, 4 Oct 2021 12:59:50 -0400 Received: from mail-wm1-x32f.google.com (mail-wm1-x32f.google.com [IPv6:2a00:1450:4864:20::32f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9F46EC0613EC for ; Mon, 4 Oct 2021 09:57:54 -0700 (PDT) Received: by mail-wm1-x32f.google.com with SMTP id a131-20020a1c7f89000000b0030d4c90fa87so521082wmd.2 for ; Mon, 04 Oct 2021 09:57:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=hJTprmd6l9eGdcrH8bWYEQJ64Pw67KrU1jFu1jkOkoM=; b=LN2ZzZJF9LC5p7sEIja6I7f/ExAfhCPKu9Z9cSLLxQu41GfGJueL4G0IpACJVLC3hu 4HzLsy09fQ9vR1aGVWx6P5oNarRoZs2PdOkcaxcgF4hJeCEOMFQu822h1EceVkxogUNa ipQPgUEUf9YgwmHVVcCupf337lzf27/RL/PhLmpi/gQ8sNBZNfqb9k8jdDWaGIbKQXSx eJghkQ/nrgIFeFmETqKuyjntQ/tnQT/SnzDkh3t/u5j/a/GVXQ2m/LHs5FVroNk944/I zj3p50Ee89IEFkxw/iLniait1/g66/U8ox+6thN+998VSFidGsHYOooQjxB09TtT/kGg 3tHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=hJTprmd6l9eGdcrH8bWYEQJ64Pw67KrU1jFu1jkOkoM=; b=x7qyhwxv1An5klkuQkwPH62bD0UZOBafGLs2yEN53KxTQjrIYsFlPWFQ7MYrdNzoTy AiZKMd6M7PYSl3qK4x/w9UZywOC0vaTwl7QPmsz9lgbFFJaF/XViMPVuEO3qStEWmRex oSJ1oIOn7atudRc9UCGc5gYBjtx09C8nN70oyAQ48GHg8kTuzyd8qSLZa884mJoy4Brt E6WgH5XDIjZUOkRs8v67Ss3XAXhLTJ2jZHB/fegHEb1f9aau73xBpR/pKSPWNDI4kSFn gazHguzO4+NUDdLdSdynkre5lea8UVNk6h4uTB3OOEEXEZAfg5BpyBNKvl2rsmc3YB7Y QN7Q== X-Gm-Message-State: AOAM532/sfGyddC0vuVWvWNJ2cvgdX7ZaVSmqIgYaYGpx4Ctvs5nxkHP eCRBGvFFxFToRy8UGKTWn/w2563l4fk= X-Google-Smtp-Source: ABdhPJzcPpM+wEQWIBsqLbppz0yqCm1WvLCJ1uYYT4AH9S53ssTi/jBQWlze0R8/3GNSGUeLuEADIw== X-Received: by 2002:a1c:ac81:: with SMTP id v123mr20024370wme.94.1633366673325; Mon, 04 Oct 2021 09:57:53 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id i92sm14634234wri.28.2021.10.04.09.57.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Oct 2021 09:57:53 -0700 (PDT) Message-Id: <15767270984a87d6112ece4057dd10bb22bad1eb.1633366667.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Mon, 04 Oct 2021 16:57:44 +0000 Subject: [PATCH v8 6/9] update-index: use the bulk-checkin infrastructure Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Neeraj-Personal , Johannes Schindelin , Jeff King , Jeff Hostetler , Christoph Hellwig , =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsA==?= Bjarmason , "Randall S. Becker" , Bagas Sanjaya , Elijah Newren , "Neeraj K. Singh" , Neeraj Singh Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Neeraj Singh From: Neeraj Singh The update-index functionality is used internally by 'git stash push' to setup the internal stashed commit. This change enables bulk-checkin for update-index infrastructure to speed up adding new objects to the object database by leveraging the pack functionality and the new bulk-fsync functionality. There is some risk with this change, since under batch fsync, the object files will not be available until the update-index is entirely complete. This usage is unlikely, since any tool invoking update-index and expecting to see objects would have to synchronize with the update-index process after passing it a file path. Signed-off-by: Neeraj Singh --- builtin/update-index.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/builtin/update-index.c b/builtin/update-index.c index 187203e8bb5..dc7368bb1ee 100644 --- a/builtin/update-index.c +++ b/builtin/update-index.c @@ -5,6 +5,7 @@ */ #define USE_THE_INDEX_COMPATIBILITY_MACROS #include "cache.h" +#include "bulk-checkin.h" #include "config.h" #include "lockfile.h" #include "quote.h" @@ -1088,6 +1089,9 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) the_index.updated_skipworktree = 1; + /* we might be adding many objects to the object database */ + plug_bulk_checkin(); + /* * Custom copy of parse_options() because we want to handle * filename arguments as they come. @@ -1168,6 +1172,8 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) strbuf_release(&buf); } + /* by now we must have added all of the new objects */ + unplug_bulk_checkin(); if (split_index > 0) { if (git_config_get_split_index() == 0) warning(_("core.splitIndex is set to false; " From patchwork Mon Oct 4 16:57:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Neeraj Singh (WINDOWS-SFS)" X-Patchwork-Id: 12534353 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2C59FC43217 for ; Mon, 4 Oct 2021 16:58:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1444761357 for ; Mon, 4 Oct 2021 16:58:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237901AbhJDQ74 (ORCPT ); Mon, 4 Oct 2021 12:59:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57010 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237925AbhJDQ7v (ORCPT ); Mon, 4 Oct 2021 12:59:51 -0400 Received: from mail-wr1-x435.google.com (mail-wr1-x435.google.com [IPv6:2a00:1450:4864:20::435]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4E52CC061783 for ; Mon, 4 Oct 2021 09:57:55 -0700 (PDT) Received: by mail-wr1-x435.google.com with SMTP id r18so4648172wrg.6 for ; Mon, 04 Oct 2021 09:57:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=Wx/NRBAYoIBhOKGldB61QZt0lf65wQv8k/Ky8embUfk=; b=Z3fb3lypPkLB1ZwMqd9jUfSL0Qvbq2M5kqcdAzjdEEuY592GkV6veDqriEPxWo8T2h vHE5PvFdzDMSW+7LCme2dnKc00dcZy5qXP3Z9uIeo6aDWkdz7ah9HNhenIKX861IWDwI bPM/PZOSYjaSsd0PAjZA2Y1Us9u1OCeYxYIgNpfRChBq0YQOo7M1Fs/TQ1L78ZJo2o0W 46xgcqMdB7578rRzIUbd90E4SCWcdkKWfKp9sjgVSkszoNgJZncxuwB7+GtNF6mz6Zyu n0rqhujGMjQqsus6/EwmPGDMxxllvOUOxV/8vUoej9DKQpBEdPxfNxCQZA8BVSkzMTke 72bg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=Wx/NRBAYoIBhOKGldB61QZt0lf65wQv8k/Ky8embUfk=; b=sFceHVZTB2x44z3pWmdjuary6z8s5GiVrW8o2B3TA+Z6QM/RkacTVsHhwlsWEfgiHm dG3XOT9NayVVenDzXFCdDzijj9T8Lnwl3Ht0pA8O/pDuzrZrzrN8fu95Xr5lJLlqpqgO JQua1RI6FnOJYaHPFfLzGFNB5xI5dPs/nAATE/a/yCfEpkdcZFW88xoyB6JUmWcN976i yl0w9cNjagf1ROz6nKEPdEd4XCPRIFFGby5BnmV7tHQYlhimvJz7U0K1DRFxSxd73IR9 bOD5SNwsr87saEoBi3uNz97mqLuVfoBTvCsBw8wsswLgNlIujHWjAFqEG2HMQKtSGYD/ kIDw== X-Gm-Message-State: AOAM530oA1u98X817NNeIJSrWEwKR7i4J5KF6sB9DRIw/TNoHrMi12i4 7zUYhpnC9rearJ9B9ld1Waw4P19n3dQ= X-Google-Smtp-Source: ABdhPJyMZfygcP8e1klyjkOmuji8IoxLYOY85yUBoQL3IMi2s9ZvoJThJJUzU/Mb6CL59yo/dNaLWw== X-Received: by 2002:adf:bc52:: with SMTP id a18mr2076286wrh.245.1633366673936; Mon, 04 Oct 2021 09:57:53 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id o1sm15053179wru.91.2021.10.04.09.57.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Oct 2021 09:57:53 -0700 (PDT) Message-Id: In-Reply-To: References: Date: Mon, 04 Oct 2021 16:57:45 +0000 Subject: [PATCH v8 7/9] unpack-objects: use the bulk-checkin infrastructure Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Neeraj-Personal , Johannes Schindelin , Jeff King , Jeff Hostetler , Christoph Hellwig , =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsA==?= Bjarmason , "Randall S. Becker" , Bagas Sanjaya , Elijah Newren , "Neeraj K. Singh" , Neeraj Singh Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Neeraj Singh From: Neeraj Singh The unpack-objects functionality is used by fetch, push, and fast-import to turn the transfered data into object database entries when there are fewer objects than the 'unpacklimit' setting. By enabling bulk-checkin when unpacking objects, we can take advantage of batched fsyncs. Signed-off-by: Neeraj Singh --- builtin/unpack-objects.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c index 4a9466295ba..51eb4f7b531 100644 --- a/builtin/unpack-objects.c +++ b/builtin/unpack-objects.c @@ -1,5 +1,6 @@ #include "builtin.h" #include "cache.h" +#include "bulk-checkin.h" #include "config.h" #include "object-store.h" #include "object.h" @@ -503,10 +504,12 @@ static void unpack_all(void) if (!quiet) progress = start_progress(_("Unpacking objects"), nr_objects); CALLOC_ARRAY(obj_list, nr_objects); + plug_bulk_checkin(); for (i = 0; i < nr_objects; i++) { unpack_one(i); display_progress(progress, i + 1); } + unplug_bulk_checkin(); stop_progress(&progress); if (delta_list) From patchwork Mon Oct 4 16:57:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Neeraj Singh (WINDOWS-SFS)" X-Patchwork-Id: 12534357 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AB486C433FE for ; Mon, 4 Oct 2021 16:58:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 944E961357 for ; Mon, 4 Oct 2021 16:58:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237939AbhJDQ75 (ORCPT ); Mon, 4 Oct 2021 12:59:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57016 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237932AbhJDQ7v (ORCPT ); Mon, 4 Oct 2021 12:59:51 -0400 Received: from mail-wr1-x433.google.com (mail-wr1-x433.google.com [IPv6:2a00:1450:4864:20::433]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 19A72C061786 for ; Mon, 4 Oct 2021 09:57:56 -0700 (PDT) Received: by mail-wr1-x433.google.com with SMTP id t2so8415096wrb.8 for ; Mon, 04 Oct 2021 09:57:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=8AgoE4x6pFlEAgdAVwM5FjKoJLl1pgqUb7ScpI1FJL0=; b=nVISyDov2cUf7Q0wtJTBiU/eFYzJU/x5j+NwSgeAU6/LGVSGcyYEYRnuosK+IsA8OR zDESv/g7iTdGm3EncvHUV34K9dU1YXbRFjWjh6iMiEmVYbLrG/waojwVakqRYGjrsGPa +9NM9gP32n3GbKBfXijnD/87bCr9ColQgHZzBghQLK6pd8/JdOGzYRoCMU3yGHDvuz8J CWs97ISKR+dEegE//Uma8SWXPG6r31poR3DtO+J8HS2fP134dgaO+O5QjreJ5loctuHP VlMMbDgOCk2xdDAwOzQnpxjwBHNrGgCNeoFJfGvq1+cBLybp9j1ufxuGYIxbnlNf+lVf 3VLg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=8AgoE4x6pFlEAgdAVwM5FjKoJLl1pgqUb7ScpI1FJL0=; b=llw4NvS5QzEM0a8U3nAJyMkPf5BFGemyyu7HVLn6Yd6Ezau27kgStfeSZ84bC/Tn9w GD+eIIwcUBpZQ1hJAh6BwO0iInQ9MdcbLFpcY6OlER/VGc5LjWcTYWst28wdKGmy4R9v 9ly2tOZBnbyNTB32UavrN0Lv8bMrFxYYc4bxeVlYqrSsLB2D38TqxG4WGSGgC6gM0Dfd tfxtspYwieRcIJCu1DCXIPwO1Ddmy+0f2nsdUQJVChYTwY7OCD1xa61ufcD5JIAQ/R3D QnJU5xK9ZlDRCjgejwtmF1G9l8Q4L2ZqDVJ1W3NhrHzLUi+9nuUOr+9zAPbGH0xYMHsX T5QQ== X-Gm-Message-State: AOAM5326h100WemIgIp94cuA8maiAt0AWgAJYz5vnpm0PKEOcuz6sEGm BqRGg0pldVYL5mHnXrqJEr6IGfVymPI= X-Google-Smtp-Source: ABdhPJyXldX28OPBqltxhBYvF1rAbDJ3LhUC2JygZ+jWQ/XkKGlLa9S0FVF6UXO8PykVLJ+8qTgtkg== X-Received: by 2002:a5d:6305:: with SMTP id i5mr5240814wru.33.1633366674666; Mon, 04 Oct 2021 09:57:54 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id c15sm15144683wrs.19.2021.10.04.09.57.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Oct 2021 09:57:54 -0700 (PDT) Message-Id: <811d6d315098924b0f588c83c74dacef829eb147.1633366667.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Mon, 04 Oct 2021 16:57:46 +0000 Subject: [PATCH v8 8/9] core.fsyncobjectfiles: tests for batch mode Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Neeraj-Personal , Johannes Schindelin , Jeff King , Jeff Hostetler , Christoph Hellwig , =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsA==?= Bjarmason , "Randall S. Becker" , Bagas Sanjaya , Elijah Newren , "Neeraj K. Singh" , Neeraj Singh Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Neeraj Singh From: Neeraj Singh Add test cases to exercise batch mode for: * 'git add' * 'git stash' * 'git update-index' * 'git unpack-objects' These tests ensure that the added data winds up in the object database. In this change we introduce a new test helper lib-unique-files.sh. The goal of this library is to create a tree of files that have different oids from any other files that may have been created in the current test repo. This helps us avoid missing validation of an object being added due to it already being in the repo. Signed-off-by: Neeraj Singh --- t/lib-unique-files.sh | 36 ++++++++++++++++++++++++++++++++++++ t/t3700-add.sh | 20 ++++++++++++++++++++ t/t3903-stash.sh | 14 ++++++++++++++ t/t5300-pack-object.sh | 30 +++++++++++++++++++----------- 4 files changed, 89 insertions(+), 11 deletions(-) create mode 100644 t/lib-unique-files.sh diff --git a/t/lib-unique-files.sh b/t/lib-unique-files.sh new file mode 100644 index 00000000000..a7de4ca8512 --- /dev/null +++ b/t/lib-unique-files.sh @@ -0,0 +1,36 @@ +# Helper to create files with unique contents + + +# Create multiple files with unique contents. Takes the number of +# directories, the number of files in each directory, and the base +# directory. +# +# test_create_unique_files 2 3 my_dir -- Creates 2 directories with 3 files +# each in my_dir, all with unique +# contents. + +test_create_unique_files() { + test "$#" -ne 3 && BUG "3 param" + + local dirs=$1 + local files=$2 + local basedir=$3 + local counter=0 + test_tick + local basedata=$test_tick + + + rm -rf $basedir + + for i in $(test_seq $dirs) + do + local dir=$basedir/dir$i + + mkdir -p "$dir" + for j in $(test_seq $files) + do + counter=$((counter + 1)) + echo "$basedata.$counter" >"$dir/file$j.txt" + done + done +} diff --git a/t/t3700-add.sh b/t/t3700-add.sh index 4086e1ebbc9..36049a53ff7 100755 --- a/t/t3700-add.sh +++ b/t/t3700-add.sh @@ -7,6 +7,8 @@ test_description='Test of git add, including the -- option.' . ./test-lib.sh +. $TEST_DIRECTORY/lib-unique-files.sh + # Test the file mode "$1" of the file "$2" in the index. test_mode_in_index () { case "$(git ls-files -s "$2")" in @@ -33,6 +35,24 @@ test_expect_success \ 'Test that "git add -- -q" works' \ 'touch -- -q && git add -- -q' +test_expect_success 'git add: core.fsyncobjectfiles=batch' " + test_create_unique_files 2 4 fsync-files && + git -c core.fsyncobjectfiles=batch add -- ./fsync-files/ && + rm -f fsynced_files && + git ls-files --stage fsync-files/ > fsynced_files && + test_line_count = 8 fsynced_files && + awk -- '{print \$2}' fsynced_files | xargs -n1 git cat-file -e +" + +test_expect_success 'git update-index: core.fsyncobjectfiles=batch' " + test_create_unique_files 2 4 fsync-files2 && + find fsync-files2 ! -type d -print | xargs git -c core.fsyncobjectfiles=batch update-index --add -- && + rm -f fsynced_files2 && + git ls-files --stage fsync-files2/ > fsynced_files2 && + test_line_count = 8 fsynced_files2 && + awk -- '{print \$2}' fsynced_files2 | xargs -n1 git cat-file -e +" + test_expect_success \ 'git add: Test that executable bit is not used if core.filemode=0' \ 'git config core.filemode 0 && diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh index 873aa56e359..2fc819e5584 100755 --- a/t/t3903-stash.sh +++ b/t/t3903-stash.sh @@ -9,6 +9,7 @@ GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME . ./test-lib.sh +. $TEST_DIRECTORY/lib-unique-files.sh diff_cmp () { for i in "$1" "$2" @@ -1293,6 +1294,19 @@ test_expect_success 'stash handles skip-worktree entries nicely' ' git rev-parse --verify refs/stash:A.t ' +test_expect_success 'stash with core.fsyncobjectfiles=batch' " + test_create_unique_files 2 4 fsync-files && + git -c core.fsyncobjectfiles=batch stash push -u -- ./fsync-files/ && + rm -f fsynced_files && + + # The files were untracked, so use the third parent, + # which contains the untracked files + git ls-tree -r stash^3 -- ./fsync-files/ > fsynced_files && + test_line_count = 8 fsynced_files && + awk -- '{print \$3}' fsynced_files | xargs -n1 git cat-file -e +" + + test_expect_success 'stash -c stash.useBuiltin=false warning ' ' expected="stash.useBuiltin support has been removed" && diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh index e13a8842075..38663dc1393 100755 --- a/t/t5300-pack-object.sh +++ b/t/t5300-pack-object.sh @@ -162,23 +162,23 @@ test_expect_success 'pack-objects with bogus arguments' ' check_unpack () { test_when_finished "rm -rf git2" && - git init --bare git2 && - git -C git2 unpack-objects -n <"$1".pack && - git -C git2 unpack-objects <"$1".pack && - (cd .git && find objects -type f -print) | - while read path - do - cmp git2/$path .git/$path || { - echo $path differs. - return 1 - } - done + git $2 init --bare git2 && + ( + git $2 -C git2 unpack-objects -n <"$1".pack && + git $2 -C git2 unpack-objects <"$1".pack && + git $2 -C git2 cat-file --batch-check="%(objectname)" + ) current && + cmp obj-list current } test_expect_success 'unpack without delta' ' check_unpack test-1-${packname_1} ' +test_expect_success 'unpack without delta (core.fsyncobjectfiles=batch)' ' + check_unpack test-1-${packname_1} "-c core.fsyncobjectfiles=batch" +' + test_expect_success 'pack with REF_DELTA' ' packname_2=$(git pack-objects --progress test-2 stderr) && check_deltas stderr -gt 0 @@ -188,6 +188,10 @@ test_expect_success 'unpack with REF_DELTA' ' check_unpack test-2-${packname_2} ' +test_expect_success 'unpack with REF_DELTA (core.fsyncobjectfiles=batch)' ' + check_unpack test-2-${packname_2} "-c core.fsyncobjectfiles=batch" +' + test_expect_success 'pack with OFS_DELTA' ' packname_3=$(git pack-objects --progress --delta-base-offset test-3 \ stderr) && @@ -198,6 +202,10 @@ test_expect_success 'unpack with OFS_DELTA' ' check_unpack test-3-${packname_3} ' +test_expect_success 'unpack with OFS_DELTA (core.fsyncobjectfiles=batch)' ' + check_unpack test-3-${packname_3} "-c core.fsyncobjectfiles=batch" +' + test_expect_success 'compare delta flavors' ' perl -e '\'' defined($_ = -s $_) or die for @ARGV; From patchwork Mon Oct 4 16:57:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Neeraj Singh (WINDOWS-SFS)" X-Patchwork-Id: 12534359 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3069EC433EF for ; Mon, 4 Oct 2021 16:58:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1EA7A6138B for ; Mon, 4 Oct 2021 16:58:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237977AbhJDRAA (ORCPT ); Mon, 4 Oct 2021 13:00:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57012 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237931AbhJDQ7v (ORCPT ); Mon, 4 Oct 2021 12:59:51 -0400 Received: from mail-wr1-x42b.google.com (mail-wr1-x42b.google.com [IPv6:2a00:1450:4864:20::42b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AFBC7C061787 for ; Mon, 4 Oct 2021 09:57:56 -0700 (PDT) Received: by mail-wr1-x42b.google.com with SMTP id r18so4648292wrg.6 for ; Mon, 04 Oct 2021 09:57:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=THp3oyYMQZ0IyvYbWDVtqI55HStotyepThNgwaAMuqY=; b=DlsRgTF0HIe9FWtKkEJmZde0Maiso7nen6Wx76tg9HsV577g4tqa2qmlQfeD4hPneD P8BS8JXfQOa5FsKBhZY8/Nq/cga05AUJ2jPUEoMm2vgc+8nfaMcGDJHezv35CzNVBS9w P8gnyj3vWtmNT8YcMwJXidt8PIZjisIg/HzqyG6n239syX8i5OSaOcnVQJ8ntpLYUdvr jT+/AdKaJ+HDmJJ/JD7HDWZtHNygRmiiO2KfV5AswflJEv6gMKckO7VO+5zFv/OH6kvI BYootW4rdu5uk+oLDOq++LNeOqi00R98Ico5DPuDt8uHYphw9iQ/vNrEJHtKPjVyYahD M5sQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=THp3oyYMQZ0IyvYbWDVtqI55HStotyepThNgwaAMuqY=; b=yPtaJd3kX2Mz0Lv20eOyQaSUVuBrl46FaC8ubAFwn/Tq3MD806BfLeVK8YJ7X/1Nvl lsKMxjq0Xlp9vpm6+OkZa/qnQ6E5K59AeRdzE8wgJ7sJBhvkvq17YYWU+RKghsQVwfYD 5o2G1El32eD8purnjsV3CRlyXxqCeW7JjpwSiMY7h7/nkqHYdb3As4OnrhwBsM/Uj5OO YUbjRbOKcZsSq/jFnI6bFlGuvO4M5Re+8q9/YrT6cUfqGmlbCaEnOdahBYb8vFfs7R4M xbNTIdQbNcIYBZSspz+/g+jlp9lJHyJOOcWtyKO9OgQ1VahYzzm0WnhA/rtTPmrXMsoe 8uHw== X-Gm-Message-State: AOAM531OwPXFvUNqH/QjrwYy/cuBxRV5GdcXcPKZtdsRfguxn3e06aoT ZcpYOMalHofCAv1vTAqqcc0LM5tanGg= X-Google-Smtp-Source: ABdhPJyaRpALayhoqVpVkOpjB8XB8K3UWG/6T6l5fgopPikjAo+gbWT9IAfdkIfz6wiiDRya90jXAA== X-Received: by 2002:adf:8b86:: with SMTP id o6mr4191965wra.193.1633366675353; Mon, 04 Oct 2021 09:57:55 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id j6sm1274715wrh.76.2021.10.04.09.57.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Oct 2021 09:57:54 -0700 (PDT) Message-Id: In-Reply-To: References: Date: Mon, 04 Oct 2021 16:57:47 +0000 Subject: [PATCH v8 9/9] core.fsyncobjectfiles: performance tests for add and stash Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Neeraj-Personal , Johannes Schindelin , Jeff King , Jeff Hostetler , Christoph Hellwig , =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsA==?= Bjarmason , "Randall S. Becker" , Bagas Sanjaya , Elijah Newren , "Neeraj K. Singh" , Neeraj Singh Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Neeraj Singh From: Neeraj Singh Add a basic performance test for "git add" and "git stash" of a lot of new objects with various fsync settings. Signed-off-by: Neeraj Singh --- t/perf/p3700-add.sh | 43 ++++++++++++++++++++++++++++++++++++++++ t/perf/p3900-stash.sh | 46 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100755 t/perf/p3700-add.sh create mode 100755 t/perf/p3900-stash.sh diff --git a/t/perf/p3700-add.sh b/t/perf/p3700-add.sh new file mode 100755 index 00000000000..e93c08a2e70 --- /dev/null +++ b/t/perf/p3700-add.sh @@ -0,0 +1,43 @@ +#!/bin/sh +# +# This test measures the performance of adding new files to the object database +# and index. The test was originally added to measure the effect of the +# core.fsyncObjectFiles=batch mode, which is why we are testing different values +# of that setting explicitly and creating a lot of unique objects. + +test_description="Tests performance of add" + +. ./perf-lib.sh + +. $TEST_DIRECTORY/lib-unique-files.sh + +test_perf_default_repo +test_checkout_worktree + +dir_count=10 +files_per_dir=50 +total_files=$((dir_count * files_per_dir)) + +# We need to create the files each time we run the perf test, but +# we do not want to measure the cost of creating the files, so run +# the tet once. +if test "${GIT_PERF_REPEAT_COUNT-1}" -ne 1 +then + echo "warning: Setting GIT_PERF_REPEAT_COUNT=1" >&2 + GIT_PERF_REPEAT_COUNT=1 +fi + +for m in false true batch +do + test_expect_success "create the files for core.fsyncObjectFiles=$m" ' + git reset --hard && + # create files across directories + test_create_unique_files $dir_count $files_per_dir files + ' + + test_perf "add $total_files files (core.fsyncObjectFiles=$m)" " + git -c core.fsyncobjectfiles=$m add files + " +done + +test_done diff --git a/t/perf/p3900-stash.sh b/t/perf/p3900-stash.sh new file mode 100755 index 00000000000..c9fcd0c03eb --- /dev/null +++ b/t/perf/p3900-stash.sh @@ -0,0 +1,46 @@ +#!/bin/sh +# +# This test measures the performance of adding new files to the object database +# and index. The test was originally added to measure the effect of the +# core.fsyncObjectFiles=batch mode, which is why we are testing different values +# of that setting explicitly and creating a lot of unique objects. + +test_description="Tests performance of stash" + +. ./perf-lib.sh + +. $TEST_DIRECTORY/lib-unique-files.sh + +test_perf_default_repo +test_checkout_worktree + +dir_count=10 +files_per_dir=50 +total_files=$((dir_count * files_per_dir)) + +# We need to create the files each time we run the perf test, but +# we do not want to measure the cost of creating the files, so run +# the tet once. +if test "${GIT_PERF_REPEAT_COUNT-1}" -ne 1 +then + echo "warning: Setting GIT_PERF_REPEAT_COUNT=1" >&2 + GIT_PERF_REPEAT_COUNT=1 +fi + +for m in false true batch +do + test_expect_success "create the files for core.fsyncObjectFiles=$m" ' + git reset --hard && + # create files across directories + test_create_unique_files $dir_count $files_per_dir files + ' + + # We only stash files in the 'files' subdirectory since + # the perf test infrastructure creates files in the + # current working directory that need to be preserved + test_perf "stash 500 files (core.fsyncObjectFiles=$m)" " + git -c core.fsyncobjectfiles=$m stash push -u -- files + " +done + +test_done