From patchwork Fri Sep 24 23:53:22 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: 12517075 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 7A554C433EF for ; Fri, 24 Sep 2021 23:53:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 58EBE60E75 for ; Fri, 24 Sep 2021 23:53:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236932AbhIXXzH (ORCPT ); Fri, 24 Sep 2021 19:55:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54832 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232695AbhIXXzG (ORCPT ); Fri, 24 Sep 2021 19:55:06 -0400 Received: from mail-wr1-x42d.google.com (mail-wr1-x42d.google.com [IPv6:2a00:1450:4864:20::42d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 581B6C061613 for ; Fri, 24 Sep 2021 16:53:32 -0700 (PDT) Received: by mail-wr1-x42d.google.com with SMTP id d6so31935621wrc.11 for ; Fri, 24 Sep 2021 16:53:32 -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=qaojmrOCfEqu729QPdI/H8/1KHs81q8gLQkfiU1S9D8=; b=S1b0vgtFdY9MrfV3UAPyr1cZzZ+NgT6VyTiYwJPM6IFM6d4WlC0D9IU0iujVvQPk1H 3wAr1OMLc9/El1Qb+5wKL2JV+ylWyz+MbEjMBmixcY5uL+xE1p+0UcODb+L8tbjFFY4I zDOO/kZStppD6p0IANdKlvPp5sPf6DpxCoJayzXYmzNgkNrkMnP5njLo1X9IncInna9k je9S6fQqP3ZeDpduEvVBdpmovV6N4CH+/RG8HAnA/UWB8sdxmMxlM7T3uEeoumV7itZp ie6aic86vPSCKZ1KMbnM0bGs1NbmLhSmI3Y0ayyBIq6CkLw+0iiLQQT4xcg5es1rRHpb E+0g== 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=qaojmrOCfEqu729QPdI/H8/1KHs81q8gLQkfiU1S9D8=; b=1br1ZuNec4jmXYbWDWFSZqixOspJBmHs3fM6Gm1F2hMa6XvS+ssxa4bAG/6Z8hKA5w j9x/hk1GrxcBHWoOKtBXC9y0lW0lL6MLXfUIfZ38UGg4nfwggNjlpjIdBENLfZDXBIHf JaFHK2FKYgIkIlOENUbGVYOJ/+f9WdM/jnGyYZmxZbPufKGCXbYNq+F3RqMO8GiLf9JG OmmSux4uP4yz9ZBW/FEnHacpgiYVPI0agPF25oKy+o1oMO2LYrQZimuIUPvip4pU8qdH peorAUoamtHQl5nzMdmPRWlPYy7jvuBjQIAGDm1N2BdA3iEuqH2rpR5tyFtNdI/GOjxZ AkXQ== X-Gm-Message-State: AOAM532ja6Cj7TZR9ZSMcjXpsRmPwePnIKWpMxzLRvNfDCzOxNkk2Vot vKCCRpdVNWH4xAnHXC8b4zLA1WJZkJY= X-Google-Smtp-Source: ABdhPJwy6qhHxXeUMOBg83m+ueWkAAcIOouU0Xn3AgSz5oOwgwN5jexZ+Hsc7kkaJCSl4WWxJuJf+g== X-Received: by 2002:adf:a549:: with SMTP id j9mr3319203wrb.353.1632527610867; Fri, 24 Sep 2021 16:53:30 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id h1sm9526680wmb.7.2021.09.24.16.53.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Sep 2021 16:53:30 -0700 (PDT) Message-Id: In-Reply-To: References: Date: Fri, 24 Sep 2021 23:53:22 +0000 Subject: [PATCH v6 1/8] object-file.c: do not rename in a temp 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 , "Neeraj K. Singh" , Neeraj Singh Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Neeraj Singh From: Neeraj Singh If a temporary ODB is active, as determined by GIT_QUARANTINE_PATH being set, create object files with their final names. This avoids an extra rename beyond what is needed to merge the temporary ODB in tmp_objdir_migrate. Creating an object file with the expected final name should be okay since the git process writing to the temporary object store is the only writer, and it only invokes write_loose_object/create_object_file after checking that the object doesn't exist. Signed-off-by: Neeraj Singh --- environment.c | 4 ++++ object-file.c | 51 ++++++++++++++++++++++++++++++++++---------------- object-store.h | 6 ++++++ repository.c | 2 ++ repository.h | 1 + 5 files changed, 48 insertions(+), 16 deletions(-) diff --git a/environment.c b/environment.c index d6b22ede7ea..d9ba68402e9 100644 --- a/environment.c +++ b/environment.c @@ -177,6 +177,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.object_dir_is_temp = 1; + } + repo_set_gitdir(the_repository, git_dir, &args); strvec_clear(&to_free); diff --git a/object-file.c b/object-file.c index a8be8994814..ab593515cec 100644 --- a/object-file.c +++ b/object-file.c @@ -1800,12 +1800,17 @@ static void write_object_file_prepare(const struct git_hash_algo *algo, } /* - * Move the just written object into its final resting place. + * Move the just written object into its final resting place, + * unless it is already there, as indicated by an empty string for + * tmpfile. */ int finalize_object_file(const char *tmpfile, const char *filename) { int ret = 0; + if (!*tmpfile) + goto out; + if (object_creation_mode == OBJECT_CREATION_USES_RENAMES) goto try_rename; else if (link(tmpfile, filename)) @@ -1878,21 +1883,37 @@ static inline int directory_size(const char *filename) } /* - * This creates a temporary file in the same directory as the final - * 'filename' + * This creates a loose object file for the specified object id. + * If we're working in a temporary object directory, the file is + * created with its final filename, otherwise it is created with + * a temporary name and renamed by finalize_object_file. + * If no rename is required, an empty string is returned in tmp. * * We want to avoid cross-directory filename renames, because those * can have problems on various filesystems (FAT, NFS, Coda). */ -static int create_tmpfile(struct strbuf *tmp, const char *filename) +static int create_objfile(const struct object_id *oid, struct strbuf *tmp, + struct strbuf *filename) { - int fd, dirlen = directory_size(filename); + int fd, dirlen, is_retrying = 0; + const char *object_name; + static const int object_mode = 0444; + loose_object_path(the_repository, filename, oid); + dirlen = directory_size(filename->buf); + +retry_create: strbuf_reset(tmp); - strbuf_add(tmp, filename, dirlen); - strbuf_addstr(tmp, "tmp_obj_XXXXXX"); - fd = git_mkstemp_mode(tmp->buf, 0444); - if (fd < 0 && dirlen && errno == ENOENT) { + if (!the_repository->objects->odb->is_temp) { + strbuf_add(tmp, filename->buf, dirlen); + object_name = "tmp_obj_XXXXXX"; + strbuf_addstr(tmp, object_name); + fd = git_mkstemp_mode(tmp->buf, object_mode); + } else { + fd = open(filename->buf, O_CREAT | O_EXCL | O_RDWR, object_mode); + } + + if (fd < 0 && dirlen && errno == ENOENT && !is_retrying) { /* * Make sure the directory exists; note that the contents * of the buffer are undefined after mkstemp returns an @@ -1900,15 +1921,15 @@ static int create_tmpfile(struct strbuf *tmp, const char *filename) * scratch. */ strbuf_reset(tmp); - strbuf_add(tmp, filename, dirlen - 1); + strbuf_add(tmp, filename->buf, dirlen - 1); if (mkdir(tmp->buf, 0777) && errno != EEXIST) return -1; if (adjust_shared_perm(tmp->buf)) return -1; /* Try again */ - strbuf_addstr(tmp, "/tmp_obj_XXXXXX"); - fd = git_mkstemp_mode(tmp->buf, 0444); + is_retrying = 1; + goto retry_create; } return fd; } @@ -1925,14 +1946,12 @@ static int write_loose_object(const struct object_id *oid, char *hdr, static struct strbuf tmp_file = STRBUF_INIT; static struct strbuf filename = STRBUF_INIT; - loose_object_path(the_repository, &filename, oid); - - fd = create_tmpfile(&tmp_file, filename.buf); + fd = create_objfile(oid, &tmp_file, &filename); if (fd < 0) { if (errno == EACCES) return error(_("insufficient permission for adding an object to repository database %s"), get_object_directory()); else - return error_errno(_("unable to create temporary file")); + return error_errno(_("unable to create object file")); } /* Set it up */ diff --git a/object-store.h b/object-store.h index b4dc6668aa2..f8c883a5730 100644 --- a/object-store.h +++ b/object-store.h @@ -26,6 +26,12 @@ struct object_directory { uint32_t loose_objects_subdir_seen[8]; /* 256 bits */ struct oidtree *loose_objects_cache; + /* + * This is a temporary object store, so there is no need to + * create new objects via rename. + */ + int is_temp; + /* * Path to the alternative object store. If this is a relative path, * it is relative to the current working directory. diff --git a/repository.c b/repository.c index b2bf44c6faf..a16de04dfa8 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->is_temp = o->object_dir_is_temp; + 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..d3711367a6f 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 object_dir_is_temp; }; void repo_set_gitdir(struct repository *repo, const char *root, From patchwork Fri Sep 24 23:53:23 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: 12517077 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 C735AC433FE for ; Fri, 24 Sep 2021 23:53:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id ABE52604DB for ; Fri, 24 Sep 2021 23:53:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245016AbhIXXzI (ORCPT ); Fri, 24 Sep 2021 19:55:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54836 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235874AbhIXXzG (ORCPT ); Fri, 24 Sep 2021 19:55:06 -0400 Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com [IPv6:2a00:1450:4864:20::430]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B2FB6C061571 for ; Fri, 24 Sep 2021 16:53:32 -0700 (PDT) Received: by mail-wr1-x430.google.com with SMTP id w29so31987876wra.8 for ; Fri, 24 Sep 2021 16:53:32 -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=7X2vP95Nrih2/ZYF5MeQkFO3N7Ybz8M6MMt6amHXYUA=; b=RHXLDyCHpMx9ls3U4mHL1tguKOjEy1+9EkKRD/mmBMb73vKPIijCvXj46ooeAn2G3V NZdsuqdSp1G7fF+rl1dt2ZlMXRJkC5GZYFgJ1Jjb3ymk5M1Mr9x8vB+zQHtWTsJQZoBC GURXkxQkC2SKUJea+AH5v99fjmKO6KA06IniXiHZlj/vNDOzal13psDHBm41rnXyfEHw g0L+ycwL0nCkOLdtbGbH/9sYjL+Cyh823aK3/iBjpF9Hr90MrbZye7kMsWp3IFuhvWit GYAcGR0vQcxRGSq8XQubnVde+Eycu3phDOuVWAE5Il1C1zY2+uMBlatXhAG53M+pljFe nY3g== 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=7X2vP95Nrih2/ZYF5MeQkFO3N7Ybz8M6MMt6amHXYUA=; b=P0H+jbUtMli/z39DfH9LDteQdAu6WhLKBvAFmIwu7LEvt8RAaSOtU2pxVPMn0ClpXf kihmDDy9btEqFJabvo6hRW0/6GTRD6rfckqbnNk39A1b4houV0WfedqOzfoNjDh1Qznn 6tYHt+GPFT71x5l2l57CTztVtfc0SPfSNXjROVvI1rfzG5eYVO/sxjCllhNWuV2yV8xN Z+5HWsCBDIXZW+UrIadPzQZwxXd8DzYpnV90oymT9HJcyNTNa04dvP9VKtdGRvrhw9lf 6iH+cO53+0tr3Y9dpO3Cl62/RXNaNNlJG7LiavZBf0MGVo8P5g62sHlb8fZTIFdQCk1y i3qQ== X-Gm-Message-State: AOAM5335rI9Rf1s2IzObD+7do1v+jFyFA0YlN4TTByaNyV85FWrSZyd1 BnUDNy+auhLB0tIrCsfLJnxYUcYeGps= X-Google-Smtp-Source: ABdhPJxlt/wqHSlmlfmyzwcw8nX+DpZCJt6zMsN2teAVy20a4WhAtIFK7oN0BKzRqCiOQcLcEMNKmw== X-Received: by 2002:a7b:c3d2:: with SMTP id t18mr4541087wmj.33.1632527611373; Fri, 24 Sep 2021 16:53:31 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id h18sm11212363wmq.23.2021.09.24.16.53.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Sep 2021 16:53:31 -0700 (PDT) Message-Id: In-Reply-To: References: Date: Fri, 24 Sep 2021 23:53:23 +0000 Subject: [PATCH v6 2/8] 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 , "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 b023d9959aa..f117d62c908 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_bulk_checkin(struct bulk_checkin_state *state) { @@ -260,21 +260,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 Fri Sep 24 23:53:24 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: 12517081 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 C7D45C433EF for ; Fri, 24 Sep 2021 23:53:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id ABE43604DB for ; Fri, 24 Sep 2021 23:53:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343517AbhIXXzJ (ORCPT ); Fri, 24 Sep 2021 19:55:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54842 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238839AbhIXXzH (ORCPT ); Fri, 24 Sep 2021 19:55:07 -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 91EA6C061571 for ; Fri, 24 Sep 2021 16:53:33 -0700 (PDT) Received: by mail-wr1-x435.google.com with SMTP id d6so31935706wrc.11 for ; Fri, 24 Sep 2021 16:53:33 -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=RTWUmdODPPQAVZeFRwama7vCDijw/jenr4RaolZwtOo=; b=TjRX/EsBv6uAut9pVsBsexrXN4LBYej6tqlDvEhuHPIamh54CPl+A1t9zQsch7oCVI ReXDXudCf6DNuz9c1zWNUrlNbZ+eRCsaOGTjPJiPp72a7ZyMG7TzsCWlbVy6Q9uKCozo RyzlSvNbp22CIDk8eN4QSBA2vx8DSN9k2G33Y9Rf1EzTRjIMwEm6MF+h0eogJHO3X0EC 8pIY8I+nlaavHJWWLXhgnv2qQQqwTCSC6+kWc0i3G1DomVhD8EVS9tCjRU8tC83NHGuK Wib5qPjN2mtcFQYwerlBcnF0lZvjeLprRy9wg7jmYKhmlK3HdEXJ8NcQRm5nLqf7aGbM voXQ== 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=RTWUmdODPPQAVZeFRwama7vCDijw/jenr4RaolZwtOo=; b=WajYMqtu+i03fNT9iBpRfV/k/CXluBDI8f1s0bYjG0zvD4dazrws7GjGiVW6Z14WA/ x068bdqRkBrWZIQziyG460F+QKlEwtYSXP6qvDotu3Q+3E4omZJOy1uGUcRMcqlu3N9c lDk2OKN++DgwDWDNr1dNjPb5KVP62QqRP11vU8y0v40VnTVoWFF94EIOw3f4aj5pB7jF 7CBvfmjL++ZmaEl/dCmUG99WSJCnvisR2q/GDGhgm9Lcjazesria8A20J+nUZ84ZINA6 UBZKTyfLzkVEXJn19ufC3feY2eCaP8yAPfaYXMHxZlX3kkohL1sDkfIuEcRt6d5P6rna 5GTA== X-Gm-Message-State: AOAM531lOQlRVrVsaoBLx9eae3+kvAOcS2/ggrGtnM7tiIIfQWeBIIug CJ1vUTrhOVaAVjBbQOiICFsYmWuySDM= X-Google-Smtp-Source: ABdhPJzV47aRwDAonLCysMhLG/NdIunXzA3o51ReG4FR5VoH3DGkdk20JGjCEZql6uqLJJnbYqRaUA== X-Received: by 2002:a05:600c:2e43:: with SMTP id q3mr4677015wmf.119.1632527612015; Fri, 24 Sep 2021 16:53:32 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id d8sm10156183wrv.80.2021.09.24.16.53.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Sep 2021 16:53:31 -0700 (PDT) Message-Id: <543ea3569342165363c1602ce36683a54dce7a0b.1632527609.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Fri, 24 Sep 2021 23:53:24 +0000 Subject: [PATCH v6 3/8] 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 , "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 we 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 we: 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 | 70 +++++++++++++++++++++++++++++++++++ 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 | 67 ++++++++++++++++++++++++++++++++- object-store.h | 16 ++++++++ object.c | 2 +- tmp-objdir.c | 20 +++++++++- tmp-objdir.h | 6 +++ wrapper.c | 44 ++++++++++++++++++++++ write-or-die.c | 2 +- 17 files changed, 284 insertions(+), 13 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 429c276058d..326c7607e0f 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. # @@ -1896,6 +1898,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 f117d62c908..957a6238684 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; @@ -62,6 +68,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; @@ -256,6 +290,26 @@ 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) { + assert(the_repository->objects->odb->is_temp); + 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) @@ -270,6 +324,20 @@ int index_bulk_checkin(struct object_id *oid, void plug_bulk_checkin(void) { assert(!bulk_checkin_plugged); + + /* + * Create a temporary object directory if the current + * object directory is not already temporary. + */ + if (fsync_object_files == FSYNC_OBJECT_FILES_BATCH && + !the_repository->objects->odb->is_temp) { + bulk_fsync_objdir = tmp_objdir_create(); + if (!bulk_fsync_objdir) + die(_("Could not create temporary object directory for core.fsyncobjectfiles=batch")); + + tmp_objdir_replace_main_odb(bulk_fsync_objdir); + } + bulk_checkin_plugged = 1; } @@ -279,4 +347,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 d23de693680..d1897fe9d92 100644 --- a/cache.h +++ b/cache.h @@ -985,7 +985,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 cb4a8058bff..1b403e00241 100644 --- a/config.c +++ b/config.c @@ -1509,7 +1509,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 d9ba68402e9..f318d59e585 100644 --- a/environment.c +++ b/environment.c @@ -43,7 +43,7 @@ const char *git_hooks_path; int zlib_compression_level = Z_BEST_SPEED; int core_compression_level; 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 b46605300ab..d14e2436276 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -1210,6 +1210,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 ab593515cec..ec22560dd66 100644 --- a/object-file.c +++ b/object-file.c @@ -750,6 +750,60 @@ void add_to_alternates_memory(const char *reference) '\n', NULL, 0); } +struct object_directory *set_temporary_main_odb(const char *dir) +{ + struct object_directory *main_odb, *new_odb, *old_next; + + /* + * Make sure alternates are initialized, or else our entry may be + * overwritten when they are. + */ + prepare_alt_odb(the_repository); + + /* Copy the existing object directory and make it an alternate. */ + main_odb = the_repository->objects->odb; + new_odb = xmalloc(sizeof(*new_odb)); + *new_odb = *main_odb; + *the_repository->objects->odb_tail = new_odb; + the_repository->objects->odb_tail = &(new_odb->next); + new_odb->next = NULL; + + /* + * Reinitialize the main odb with the specified path, being careful + * to keep the next pointer value. + */ + old_next = main_odb->next; + memset(main_odb, 0, sizeof(*main_odb)); + main_odb->next = old_next; + main_odb->is_temp = 1; + main_odb->path = xstrdup(dir); + return new_odb; +} + +void restore_main_odb(struct object_directory *odb) +{ + struct object_directory **prev, *main_odb; + + /* Unlink the saved previous main ODB from the list. */ + prev = &the_repository->objects->odb->next; + assert(*prev); + while (*prev != odb) { + prev = &(*prev)->next; + } + *prev = odb->next; + if (*prev == NULL) + the_repository->objects->odb_tail = prev; + + /* + * Restore the data from the old main odb, being careful to + * keep the next pointer value + */ + main_odb = the_repository->objects->odb; + SWAP(*main_odb, *odb); + main_odb->next = odb->next; + free_object_directory(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` @@ -1867,8 +1921,19 @@ 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) + 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) die_errno(_("error when closing loose object file")); } diff --git a/object-store.h b/object-store.h index f8c883a5730..9bea14e7f3b 100644 --- a/object-store.h +++ b/object-store.h @@ -62,6 +62,19 @@ void add_to_alternates_file(const char *dir); */ void add_to_alternates_memory(const char *dir); +/* + * Replace the current main object directory with the specified temporary + * object directory. We make a copy of the former main object directory, + * add it as an in-memory alternate, and return the copy so that it can + * be restored via restore_main_odb. + */ +struct object_directory *set_temporary_main_odb(const char *dir); + +/* + * Restore a previous ODB replaced by set_temporary_main_odb. + */ +void restore_main_odb(struct object_directory *odb); + /* * Populate and return the loose object cache array corresponding to the * given object ID. @@ -72,6 +85,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..f027c49db4c 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_main_odb; }; /* @@ -50,8 +51,12 @@ static int tmp_objdir_destroy_1(struct tmp_objdir *t, int on_signal) * freeing memory; it may cause a deadlock if the signal * arrived while libc's allocator lock is held. */ - if (!on_signal) + if (!on_signal) { + if (t->prev_main_odb) + restore_main_odb(t->prev_main_odb); tmp_objdir_free(t); + } + return err; } @@ -132,6 +137,7 @@ struct tmp_objdir *tmp_objdir_create(void) t = xmalloc(sizeof(*t)); strbuf_init(&t->path, 0); strvec_init(&t->env); + t->prev_main_odb = NULL; strbuf_addf(&t->path, "%s/incoming-XXXXXX", get_object_directory()); @@ -269,6 +275,11 @@ int tmp_objdir_migrate(struct tmp_objdir *t) if (!t) return 0; + if (t->prev_main_odb) { + restore_main_odb(t->prev_main_odb); + t->prev_main_odb = NULL; + } + strbuf_addbuf(&src, &t->path); strbuf_addstr(&dst, get_object_directory()); @@ -292,3 +303,10 @@ void tmp_objdir_add_as_alternate(const struct tmp_objdir *t) { add_to_alternates_memory(t->path.buf); } + +void tmp_objdir_replace_main_odb(struct tmp_objdir *t) +{ + if (t->prev_main_odb) + BUG("the main object database is already replaced"); + t->prev_main_odb = set_temporary_main_odb(t->path.buf); +} diff --git a/tmp-objdir.h b/tmp-objdir.h index b1e45b4c75d..4b898add05b 100644 --- a/tmp-objdir.h +++ b/tmp-objdir.h @@ -51,4 +51,10 @@ 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. + */ +void tmp_objdir_replace_main_odb(struct tmp_objdir *); + #endif /* TMP_OBJDIR_H */ 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 d33e68f6abb..8f53953d4ab 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 Fri Sep 24 23:53:25 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: 12517087 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 17B54C4332F for ; Fri, 24 Sep 2021 23:53:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id F064261251 for ; Fri, 24 Sep 2021 23:53:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344792AbhIXXzN (ORCPT ); Fri, 24 Sep 2021 19:55:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54844 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232695AbhIXXzH (ORCPT ); Fri, 24 Sep 2021 19:55:07 -0400 Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com [IPv6:2a00:1450:4864:20::430]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D9E2FC061613 for ; Fri, 24 Sep 2021 16:53:33 -0700 (PDT) Received: by mail-wr1-x430.google.com with SMTP id i23so32161013wrb.2 for ; Fri, 24 Sep 2021 16:53:33 -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=aIfeNeqMdPVOWuzbxF8Xf5LIw6D7g8pQZTXhuovtlFi9xpyHgfPCOBxSrvjUZvyDkM 3eYd5rmaCkxLpT3B0La1UjwDaw+HFpXMALNU8/F4Bs1fPOlUfvqdzOMQZSBA4YHXsXS0 aQb7a/YzaK8lgTOxVj3+gHipc15adL4T+OlAa4tPu5FCDV+Hs4+vE4JfQ1Da2LW0TUDO hIecmTxDWDaKydFw4UufOJZAe/YUsVS4QrQMFRAtSxxczDN1JhnaPZnky1KmUaN+xdV8 4nunAPmDBd4VNGeKwcVHlotqaxLRfxd6nyVOIPFA2ldl5dLrJkDYdFqiUP15beG7lTlX RXIg== 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=XoiDpkqjeJeI8roqcOIdYOe4s2iMy2Sy1RFSxJnKzt63CZ+ZwWjw04nDaMxiEQ4IbW 9+iDyTWssS65X7hfpYX+JNH0a4t5Dd2n2sKAi6+EMJlYdvUfKKxCkc7x5Rz+PFrVUF1m hgQMixZZ1f6OuFS4Y+INug7sDCYm70eaP8rPecu27/V5lafOGOgc79nSyyDXu8IDGCXB W5pRiBr/0WK2KeZj05I2s9ycKNpbq7O4APBei28CrfPhhEj2iR6bkXbEA0LA3krGyQ5J yVhYK0hSsAdCiNKcBC47Y+ldtoclheY5PjhfT1Qmon4j4v/3JcdfA2sky2UFAVthXzWz A13w== X-Gm-Message-State: AOAM532b8nKynUh0QZQD069EK6T78g6zALsCrENuNLjPN7ENMkShhTSA eJ4qJi9M3S98XzuR7M5BWAvGAKAUUR4= X-Google-Smtp-Source: ABdhPJxbE2C+/3ZDwoIUeLCzC0CJPSx9BJ/zWAn8TreAuY2PWqbbjFJyCrmtN17frCZM+YA9PCdBmg== X-Received: by 2002:a5d:4a4e:: with SMTP id v14mr14067541wrs.271.1632527612555; Fri, 24 Sep 2021 16:53:32 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id c185sm10344243wma.8.2021.09.24.16.53.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Sep 2021 16:53:32 -0700 (PDT) Message-Id: In-Reply-To: References: Date: Fri, 24 Sep 2021 23:53:25 +0000 Subject: [PATCH v6 4/8] 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 , "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 Fri Sep 24 23:53:26 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: 12517083 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 C0C08C433F5 for ; Fri, 24 Sep 2021 23:53:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A2B0C60E75 for ; Fri, 24 Sep 2021 23:53:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343605AbhIXXzM (ORCPT ); Fri, 24 Sep 2021 19:55:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54846 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235874AbhIXXzI (ORCPT ); Fri, 24 Sep 2021 19:55:08 -0400 Received: from mail-wr1-x432.google.com (mail-wr1-x432.google.com [IPv6:2a00:1450:4864:20::432]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7B4A3C061571 for ; Fri, 24 Sep 2021 16:53:34 -0700 (PDT) Received: by mail-wr1-x432.google.com with SMTP id g16so32108011wrb.3 for ; Fri, 24 Sep 2021 16:53:34 -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=bPtp8drKnn22+eXxachA8rMm7K+kHTNS2XH2nnwkZrcDjoWnTuibT6eV/Bcz4gATRB nun+Lg/st2ONj1zcPnlsN0K2l1vtxD+XDYdJjYSQz71i1URAOd5yKAia8w2yj+lopjkJ n1FUtlE5j7Zsi/fItrpTmjr4rYJtDlcZSyqCN6grft9aZJgQggz6cVJycsB4GM0l+xin WSq23++zX8QdSeHUhAfZw9ImDsMhvODgALvfVkN/TURLRTga3mEeSqIjHbGJi7ONpHW3 bWV/+AH3tGTh8V9VxIo9tKZfDmXw8KT5y2ph6oiWGIdBev+miCqLGc027sygJNXSyb/s h8OQ== 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=fbwHKd9zfpV0eazy8LFSkBJJVGudWgfyglktKne1LB5eDqZET2llnZdBGEEai7YVJU 1KaEzPefVJBHoEyRijM2Q4yw5A7i60CJgjmXhjKSQJRl++q9X522nAJCwHHugRYazAKa l51uewrnA8BVv90TNv/5lDqw0+PTCLf2jaRFNbtFVEAibzTOZ9k7CkHYlPF83jv9aAPD fA3t3/Lyc4DRuuve/fGig1zXwkNT0pLlfIGIsrtyPp2i0TOYh0tNNv/iTSUujJXtiz5F 7ft84NbE/VRwwCIzprTTqv1t1MYC6Hx99zGRxgqbTVhezJte1BGs5fdSc+I6PeoTowss wuyg== X-Gm-Message-State: AOAM5328ypdUusZGsrSAbg0Dx6EdPf/jiMcAQMo95Tdw90F/GNVLSExt gg9+G9IpxfkgDt5Q9ku+sga+IRmMyN4= X-Google-Smtp-Source: ABdhPJzAhn95MrucTcAcQENl43NqOWyai/jt6vvJd7Qvw6KjfSGorWxjI8axFxG5d8i2c0eMUZT54Q== X-Received: by 2002:adf:d233:: with SMTP id k19mr3816611wrh.414.1632527613082; Fri, 24 Sep 2021 16:53:33 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id n7sm9487138wra.37.2021.09.24.16.53.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Sep 2021 16:53:32 -0700 (PDT) Message-Id: <92e18cedab0f9dccb6d64ab93c779d72be4d4cf1.1632527609.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Fri, 24 Sep 2021 23:53:26 +0000 Subject: [PATCH v6 5/8] 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 , "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 Fri Sep 24 23:53:27 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: 12517085 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 BBA6FC433FE for ; Fri, 24 Sep 2021 23:53:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A3DC26125F for ; Fri, 24 Sep 2021 23:53:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344407AbhIXXzO (ORCPT ); Fri, 24 Sep 2021 19:55:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54852 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S245437AbhIXXzJ (ORCPT ); Fri, 24 Sep 2021 19:55:09 -0400 Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com [IPv6:2a00:1450:4864:20::430]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0FB7DC0614ED for ; Fri, 24 Sep 2021 16:53:35 -0700 (PDT) Received: by mail-wr1-x430.google.com with SMTP id d6so31935818wrc.11 for ; Fri, 24 Sep 2021 16:53:34 -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=bDcdRT/gXz5c864Jhg09hYknmkBjA2X5VKTssYJzYp6nmEiTWCI8OfAsniP2pDUWK7 WJggUsdixyN6dDiclkCWINPmAWGQQdySp3N3rxHmLktoOMj1O4djxsPcucuPDr4Uvf93 SjRaGVoUkDV7445NWA4GlYM8WEP6tpRkwSK+a1VyqFC7W4HqL/AD8czSpEUsyd+HClvx 8PQLS0P3jg9vY6TZLbTqLkrUBgz+3/JTL617YhmfcT9CVTV5P5ibrUDBf4XdjuOaNISy 5psbpzxY6morA8uWksxy05hckS4ziCbueullRTlYxxbYmXgPAu9pW5dxvY3QcNL2fkIW s0eQ== 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=Kc1aAMaVc03fCf/Bw6te632dm4OLbQemxd7wH2HMwR4bf1rtKkh51PDj4To89d/nRL QrSMQF8gZXybY8wX/Q4zCiugNUXhvY9/kpinSqIhGP51LqSlIM/D5+dxBzfPFnOr2BPq 2AVk4syGq/CNCNND6XxaGCqM1qTQUtFuSruMf6LAPKDePbxsFXr+MX6HJMcoKIp1Eubo 5VW92xtMZJx8SA+VP9jB9TxXK/KK73eNqzYG4wljVBFlZmGYzcFXQ+9ayJjO/iETHd4Q RaWmR3D9aUNZfDEDzgArW8OEyuX5yLU54VWlMXNNVCozjIMSdkhsBwW1lcAZMAjRL6Mr 23Ug== X-Gm-Message-State: AOAM530NqoAtSF/Q2Wtb/uskjU3m+BCTb2NcOvRCEk/LEwiDsy4WwJK/ gm9W/hajW3bawAkGx5h10oYuiHYk0Cg= X-Google-Smtp-Source: ABdhPJyqDzEdqXe8tP0ZlXoihOsKGwYCWlZL4iXBvxLQ9Rz654ianflZrnAonwSPsWNQ4OGLJmPxJQ== X-Received: by 2002:a5d:598c:: with SMTP id n12mr13779371wri.391.1632527613677; Fri, 24 Sep 2021 16:53:33 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id 135sm14561510wma.32.2021.09.24.16.53.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Sep 2021 16:53:33 -0700 (PDT) Message-Id: In-Reply-To: References: Date: Fri, 24 Sep 2021 23:53:27 +0000 Subject: [PATCH v6 6/8] 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 , "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 Fri Sep 24 23:53:28 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: 12517091 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 172CDC433FE for ; Fri, 24 Sep 2021 23:53:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0449761251 for ; Fri, 24 Sep 2021 23:53:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345243AbhIXXzT (ORCPT ); Fri, 24 Sep 2021 19:55:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54866 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343742AbhIXXzL (ORCPT ); Fri, 24 Sep 2021 19:55:11 -0400 Received: from mail-wr1-x431.google.com (mail-wr1-x431.google.com [IPv6:2a00:1450:4864:20::431]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AB51BC061762 for ; Fri, 24 Sep 2021 16:53:35 -0700 (PDT) Received: by mail-wr1-x431.google.com with SMTP id t18so32149701wrb.0 for ; Fri, 24 Sep 2021 16:53:35 -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=pA+ofcP4pCuoXZS8SEHo7abfjoB2XFYtIlhNTf+xX1Ik7yDlzgMU/Nvef/G85B7DHK HE9dd8RD8erZHgliqlivO2qc3Q5gjZZ1Rm0T2APN4CeQhXK4iZ7b69UleUvFEquBB56/ Z5DbxEqugE7RE4kezxQ5GD5Bh6HIFIuOM3gkSzLrmTCnerAbfV+Dwior4K3n5RoQ8Swc ZPKksm9MzeVx2wVKb6hCH6dOVIt7qfJ21YAdj1UFvtbfeoS0pjXgnVBGi9gezseLy18D STAIR2x+7isDU6W8pl7rtYKIHE4iQeF+ltBQ/EohA/qmd0P6XMQ8x1eEa4UZv9Hqa8Or FRFQ== 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=uFHqDinEKDrpO6BOL7hufrVOCP5JxS2YZ/kS1LdoItZ/FFOMa2utTug2pxQOqm5FUX sol+n/fX69hSs2aGeKCAuRCxcqQAeG1suH5/lNXN8OUL2rRf6MxtcbydC1U2PsvJRsvt 3mwyGuzKQVtQJpsy1kS7d1Iwc1A+cxGFBeiI+5B08JnbPrY5Oi++k4sKqoBioAJSDfI4 qboL0YkwqXmRO2jJxUX8beAmkVFxAE5BzSWyDCDeQDiOXnfxpvyvfxaUtVA8H9EezPYb q8N/jQL+OxoEFIG9C7FCITfKx4UwFAZ6CBWigwqz9jw0Uq79WBH6udllMXMkXujsBEZg CwZw== X-Gm-Message-State: AOAM530eTP1Bp2ovWlo6fSwpRgWzuYhaQXz+jfWOOFFkOj7+ujFS/taV aQGGpjjI6qMz/HJZx5nXsOMQHtuyIks= X-Google-Smtp-Source: ABdhPJyK5qiLRBiuEprDPYYBkuC0ahnks9UE4GsyFP8uUCo8BYACxKLrgpGpQbwBcV/lxYJVJ4+m4A== X-Received: by 2002:adf:fe44:: with SMTP id m4mr14705096wrs.206.1632527614316; Fri, 24 Sep 2021 16:53:34 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id r4sm10561329wma.48.2021.09.24.16.53.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Sep 2021 16:53:34 -0700 (PDT) Message-Id: <385199354fafd65f7822fa13445a94afbe2a4dce.1632527609.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Fri, 24 Sep 2021 23:53:28 +0000 Subject: [PATCH v6 7/8] 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 , "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 Fri Sep 24 23:53:29 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: 12517089 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 DCD4BC433F5 for ; Fri, 24 Sep 2021 23:53:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C73FD60E75 for ; Fri, 24 Sep 2021 23:53:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344648AbhIXXzR (ORCPT ); Fri, 24 Sep 2021 19:55:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54868 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344108AbhIXXzL (ORCPT ); Fri, 24 Sep 2021 19:55:11 -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 36493C061764 for ; Fri, 24 Sep 2021 16:53:36 -0700 (PDT) Received: by mail-wr1-x436.google.com with SMTP id i24so16135477wrc.9 for ; Fri, 24 Sep 2021 16:53:36 -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=WH3Jq0aHPVT5sydxfUXdrRXlgrlzAsk97K7vdGVsueO3h4OjrccC0MimkVaZoyDyrp pWOotxkntyQna8JmoUJ1hSo8tiGqpI4xHRAwiuEm9pVXEZJZ9EC8lMDRIORsRC63FBxy 4mIv/VgmVUx+xGyAaO9syFZ5f4T5I/N2w8fV9IlclKFN0CfqitukzIjgc5TJg3guFBAt gh4OU7IC9iRbCbwmQR6vC8QIsOqLLLiKwhsJVjgod6gf6hAOU1Ry4Nwkz0SRHuVIQQUk N1kUi3OCz6hBh5P03I7yoQjll83EAFOV22S0CFejtmBWeOBR9tN3zXB8HuPsAEPZ3N5z 4rRw== 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=BSSdLQWa8s7leYcykOXICpHDtqkmgbF/O+gASs4UHv2vAHui6IHpe/CBd847ockgq3 VRkgHtkXS+nPXcJ5ERqNSmZCThr+4bKLfKRe840V2l6iYEVAc1tQSMm0Nlipq55Sfd3H yS4t4WgcVsD0pmATEGMPeRGf56pD90kLBdNDu+DI/pGCve8S13aYJQC/S4IspQzSLUX+ p08WyjFL3tXJnivSI0QvIvYDV32omUu+K8eRb3ai253Oe7Hia6O/iCuE5EYHM1KxDjFt QwjjOrTFKpyzGaLjnB9IuDUmxQrj6ZjJo8GuFCDtM63H72v+4PP76wjeVBpM0wCv2dBN zHAw== X-Gm-Message-State: AOAM532lJsfcFORqvRlcMnznqh6ewz81S5LGIFYZkxmZoH/puqH2ixsD mScNfSpUxNBzDuHlHvwpbqCuf+Hu6LU= X-Google-Smtp-Source: ABdhPJwJ8XXpD+jTrTxB/ogFTtmyZKC0RBwR0s0Qpn5Sn4PQcLmz/75lWj4ZArKo9iRc9EdamfxSmA== X-Received: by 2002:adf:f844:: with SMTP id d4mr14387291wrq.370.1632527614819; Fri, 24 Sep 2021 16:53:34 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id x5sm12103892wmk.32.2021.09.24.16.53.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Sep 2021 16:53:34 -0700 (PDT) Message-Id: <504bcc95c562c43b149d3dccf95f6a04761a9321.1632527609.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Fri, 24 Sep 2021 23:53:29 +0000 Subject: [PATCH v6 8/8] 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 , "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