From: Taylor Blau <me@ttaylorr.com>
To: git@vger.kernel.org
Cc: avarab@gmail.com, gitster@pobox.com
Subject: [PATCH v2 0/9] packfile: avoid .idx rename races
Date: Thu, 9 Sep 2021 19:24:21 -0400 [thread overview]
Message-ID: <cover.1631228928.git.me@ttaylorr.com> (raw)
In-Reply-To: <cover.1631157880.git.me@ttaylorr.com>
Here is a relatively small reroll of mine and Ævar's series to prevent
packfile-related races when moving the `.idx` into place before other auxiliary
files are renamed.
All changes are cosmetic, but all of the feedback on the previous round was a
strict improvement in the overall quality, so it seemed pertinent to send an
improved version. Range-diff is below, and thanks in advance for your review.
Taylor Blau (4):
bulk-checkin.c: store checksum directly
pack-write.c: rename `.idx` files after `*.rev`
builtin/repack.c: move `.idx` files into place last
builtin/index-pack.c: move `.idx` files into place last
Ævar Arnfjörð Bjarmason (5):
pack.h: line-wrap the definition of finish_tmp_packfile()
pack-write: refactor renaming in finish_tmp_packfile()
index-pack: refactor renaming in final()
pack-write: split up finish_tmp_packfile() function
pack-objects: rename .idx files into place after .bitmap files
builtin/index-pack.c | 48 +++++++++++++++++------------------
builtin/pack-objects.c | 15 ++++++++---
builtin/repack.c | 2 +-
bulk-checkin.c | 31 +++++++++++++++++------
pack-write.c | 57 +++++++++++++++++++++---------------------
pack.h | 10 +++++++-
6 files changed, 96 insertions(+), 67 deletions(-)
Range-diff against v1:
-: ---------- > 1: 0b07aa4947 pack.h: line-wrap the definition of finish_tmp_packfile()
1: 20b35ce050 ! 2: c46d3c29b4 bulk-checkin.c: store checksum directly
@@ Commit message
Store the hash directly in an unsigned char array. This behaves the same
as writing to the `hash` member, but makes the intent clearer (and
avoids allocating an extra four bytes for the `algo` member of `struct
- object_id`).
+ object_id`). It likewise prevents the possibility of a segfault when
+ reading `algo` (e.g., by calling `oid_to_hex()`) if it is uninitialized.
Signed-off-by: Taylor Blau <me@ttaylorr.com>
2: 35052ef494 ! 3: 2e907e309d pack-write: refactor renaming in finish_tmp_packfile()
@@ pack-write.c: struct hashfile *create_tmp_packfile(char **pack_tmp_name)
return hashfd(fd, *pack_tmp_name);
}
-+static void rename_tmp_packfile(struct strbuf *nb, const char *source,
++static void rename_tmp_packfile(struct strbuf *name_prefix, const char *source,
+ const char *ext)
+{
-+ size_t nb_len = nb->len;
++ size_t name_prefix_len = name_prefix->len;
+
-+ strbuf_addstr(nb, ext);
-+ if (rename(source, nb->buf))
-+ die_errno("unable to rename temporary '*.%s' file to '%s'",
-+ ext, nb->buf);
-+ strbuf_setlen(nb, nb_len);
++ strbuf_addstr(name_prefix, ext);
++ if (rename(source, name_prefix->buf))
++ die_errno("unable to rename temporary file to '%s'",
++ name_prefix->buf);
++ strbuf_setlen(name_prefix, name_prefix_len);
+}
+
void finish_tmp_packfile(struct strbuf *name_buffer,
3: 0fb2c25f5a = 4: 41d34b1f18 pack-write.c: rename `.idx` files after `*.rev`
4: 3b10a97ec0 = 5: 6b340b7eba builtin/repack.c: move `.idx` files into place last
5: 3c9b515907 ! 6: 1e4d0ea0f3 index-pack: refactor renaming in final()
@@ Commit message
helper, this is both a net decrease in lines, and improves the
readability, since we can easily see at a glance that the logic for
writing these three types of files is exactly the same, aside from the
- obviously differing cases of "*final_xyz_name" being NULL, and
- "else_chmod_if" being different.
+ obviously differing cases of "*final_name" being NULL, and
+ "make_read_only_if_same" being different.
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
@@ builtin/index-pack.c: static void write_special_file(const char *suffix, const c
strbuf_release(&name_buf);
}
-+static void rename_tmp_packfile(const char **final_xyz_name,
-+ const char *curr_xyz_name,
-+ struct strbuf *xyz_name, unsigned char *hash,
-+ const char *ext, int else_chmod_if)
++static void rename_tmp_packfile(const char **final_name,
++ const char *curr_name,
++ struct strbuf *name, unsigned char *hash,
++ const char *ext, int make_read_only_if_same)
+{
-+ if (*final_xyz_name != curr_xyz_name) {
-+ if (!*final_xyz_name)
-+ *final_xyz_name = odb_pack_name(xyz_name, hash, ext);
-+ if (finalize_object_file(curr_xyz_name, *final_xyz_name))
++ if (*final_name != curr_name) {
++ if (!*final_name)
++ *final_name = odb_pack_name(name, hash, ext);
++ if (finalize_object_file(curr_name, *final_name))
+ die(_("unable to rename temporary '*.%s' file to '%s"),
-+ ext, *final_xyz_name);
-+ } else if (else_chmod_if) {
-+ chmod(*final_xyz_name, 0444);
++ ext, *final_name);
++ } else if (make_read_only_if_same) {
++ chmod(*final_name, 0444);
+ }
+}
+
6: 8d67a71501 = 7: 906e75d707 builtin/index-pack.c: move `.idx` files into place last
7: 5c553229b0 ! 8: 90bebe4e51 pack-write: split up finish_tmp_packfile() function
@@ bulk-checkin.c: static struct bulk_checkin_state {
unsigned char hash[GIT_MAX_RAWSZ];
## pack-write.c ##
-@@ pack-write.c: static void rename_tmp_packfile(struct strbuf *nb, const char *source,
- strbuf_setlen(nb, nb_len);
+@@ pack-write.c: static void rename_tmp_packfile(struct strbuf *name_prefix, const char *source,
+ strbuf_setlen(name_prefix, name_prefix_len);
}
-void finish_tmp_packfile(struct strbuf *name_buffer,
8: d8286cf107 ! 9: 1409725509 pack-objects: rename .idx files into place after .bitmap files
@@ Commit message
about filesystem races in the face of doing and not doing fsync() (and
if doing fsync(), not doing it properly).
- In particular, in this case of writing to ".git/objects/pack" we only
- write and fsync() the individual files, but if we wanted to guarantee
- that the metadata update was seen in that way by concurrent processes
- we'd need to fsync() on the "fd" of the containing directory. That
- concern is probably more theoretical than not, modern OS's tend to be
- more on the forgiving side than the overly pedantic side of
- implementing POSIX FS semantics.
+ We may want to fsync the containing directory once after renaming the
+ *.idx file into place, but that is outside the scope of this series.
1. https://lore.kernel.org/git/8735qgkvv1.fsf@evledraar.gmail.com/
--
2.33.0.96.g73915697e6
next prev parent reply other threads:[~2021-09-09 23:24 UTC|newest]
Thread overview: 81+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-09-01 2:05 [PATCH 0/2] pack-write,repack: prevent opening packs too early Taylor Blau
2021-09-01 2:06 ` [PATCH 1/2] pack-write.c: rename `.idx` file into place last Taylor Blau
2021-09-01 2:06 ` [PATCH 2/2] builtin/repack.c: move `.idx` files " Taylor Blau
2021-09-01 3:53 ` [PATCH 0/2] pack-write,repack: prevent opening packs too early Jeff King
2021-09-01 4:29 ` Taylor Blau
2021-09-01 4:59 ` Jeff King
2021-09-01 5:12 ` Taylor Blau
2021-09-01 6:08 ` Jeff King
2021-09-01 21:40 ` Taylor Blau
2021-09-07 16:07 ` Jeff King
2021-09-07 19:42 ` [PATCH 0/3] rename *.idx file into place last (also after *.bitmap) Ævar Arnfjörð Bjarmason
2021-09-07 19:42 ` [PATCH 1/3] pack-write: use more idiomatic strbuf usage for packname construction Ævar Arnfjörð Bjarmason
2021-09-07 22:21 ` Taylor Blau
2021-09-07 23:22 ` Ævar Arnfjörð Bjarmason
2021-09-07 19:42 ` [PATCH 2/3] pack-write: split up finish_tmp_packfile() function Ævar Arnfjörð Bjarmason
2021-09-07 22:28 ` Taylor Blau
2021-09-07 19:42 ` [PATCH 3/3] pack-write: rename *.idx file into place last (really!) Ævar Arnfjörð Bjarmason
2021-09-07 22:31 ` Taylor Blau
2021-09-07 22:36 ` [PATCH 0/3] rename *.idx file into place last (also after *.bitmap) Taylor Blau
2021-09-07 19:48 ` [PATCH 0/2] pack-write,repack: prevent opening packs too early Ævar Arnfjörð Bjarmason
2021-09-08 0:38 ` [PATCH v2 0/4] rename *.idx file into place last (also after *.bitmap) Ævar Arnfjörð Bjarmason
2021-09-08 0:38 ` [PATCH v2 1/4] pack.h: line-wrap the definition of finish_tmp_packfile() Ævar Arnfjörð Bjarmason
2021-09-08 0:38 ` [PATCH v2 2/4] pack-write: refactor renaming in finish_tmp_packfile() Ævar Arnfjörð Bjarmason
2021-09-08 4:22 ` Taylor Blau
2021-09-08 0:38 ` [PATCH v2 3/4] pack-write: split up finish_tmp_packfile() function Ævar Arnfjörð Bjarmason
2021-09-08 0:38 ` [PATCH v2 4/4] pack-write: rename *.idx file into place last (really!) Ævar Arnfjörð Bjarmason
2021-09-08 1:14 ` Ævar Arnfjörð Bjarmason
2021-09-08 9:18 ` Ævar Arnfjörð Bjarmason
2021-09-08 4:24 ` Taylor Blau
2021-09-08 22:17 ` [PATCH v2 0/3] prevent opening packs too early Taylor Blau
2021-09-08 22:17 ` [PATCH v2 1/3] pack-write.c: rename `.idx` files into place last Taylor Blau
2021-09-08 22:17 ` [PATCH v2 2/3] builtin/repack.c: move " Taylor Blau
2021-09-08 22:17 ` [PATCH v2 3/3] builtin/index-pack.c: " Taylor Blau
2021-09-08 23:52 ` [PATCH v2 0/3] prevent opening packs too early Ævar Arnfjörð Bjarmason
2021-09-09 0:50 ` Ævar Arnfjörð Bjarmason
2021-09-09 1:13 ` Taylor Blau
2021-09-09 1:33 ` Ævar Arnfjörð Bjarmason
2021-09-09 2:36 ` Ævar Arnfjörð Bjarmason
2021-09-09 2:49 ` Taylor Blau
2021-09-09 3:24 ` [PATCH 0/9] packfile: avoid .idx rename races Taylor Blau
2021-09-09 3:24 ` [PATCH 1/9] pack.h: line-wrap the definition of finish_tmp_packfile() Taylor Blau
2021-09-09 3:24 ` [PATCH 2/9] bulk-checkin.c: store checksum directly Taylor Blau
2021-09-09 7:38 ` Ævar Arnfjörð Bjarmason
2021-09-09 3:24 ` [PATCH 3/9] pack-write: refactor renaming in finish_tmp_packfile() Taylor Blau
2021-09-09 19:29 ` Junio C Hamano
2021-09-09 21:07 ` Taylor Blau
2021-09-09 23:30 ` Junio C Hamano
2021-09-09 23:31 ` Taylor Blau
2021-09-10 1:29 ` Junio C Hamano
2021-09-09 3:24 ` [PATCH 4/9] pack-write.c: rename `.idx` files after `*.rev` Taylor Blau
2021-09-09 7:46 ` Ævar Arnfjörð Bjarmason
2021-09-09 14:37 ` Taylor Blau
2021-09-09 19:32 ` Junio C Hamano
2021-09-09 3:25 ` [PATCH 5/9] builtin/repack.c: move `.idx` files into place last Taylor Blau
2021-09-09 19:38 ` Junio C Hamano
2021-09-09 21:08 ` Taylor Blau
2021-09-09 3:25 ` [PATCH 6/9] index-pack: refactor renaming in final() Taylor Blau
2021-09-09 19:45 ` Junio C Hamano
2021-09-09 21:11 ` Taylor Blau
2021-09-09 3:25 ` [PATCH 7/9] builtin/index-pack.c: move `.idx` files into place last Taylor Blau
2021-09-09 7:52 ` Ævar Arnfjörð Bjarmason
2021-09-09 19:45 ` Junio C Hamano
2021-09-09 3:25 ` [PATCH 8/9] pack-write: split up finish_tmp_packfile() function Taylor Blau
2021-09-09 3:25 ` [PATCH 9/9] pack-objects: rename .idx files into place after .bitmap files Taylor Blau
2021-09-09 7:54 ` Ævar Arnfjörð Bjarmason
2021-09-09 19:52 ` Junio C Hamano
2021-09-09 21:13 ` Taylor Blau
2021-09-09 8:06 ` [PATCH 0/9] packfile: avoid .idx rename races Ævar Arnfjörð Bjarmason
2021-09-09 14:40 ` Taylor Blau
2021-09-09 19:52 ` Junio C Hamano
2021-09-09 23:24 ` Taylor Blau [this message]
2021-09-09 23:24 ` [PATCH v2 1/9] pack.h: line-wrap the definition of finish_tmp_packfile() Taylor Blau
2021-09-09 23:24 ` [PATCH v2 2/9] bulk-checkin.c: store checksum directly Taylor Blau
2021-09-09 23:24 ` [PATCH v2 3/9] pack-write: refactor renaming in finish_tmp_packfile() Taylor Blau
2021-09-09 23:24 ` [PATCH v2 4/9] pack-write.c: rename `.idx` files after `*.rev` Taylor Blau
2021-09-09 23:24 ` [PATCH v2 5/9] builtin/repack.c: move `.idx` files into place last Taylor Blau
2021-09-09 23:24 ` [PATCH v2 6/9] index-pack: refactor renaming in final() Taylor Blau
2021-09-09 23:24 ` [PATCH v2 7/9] builtin/index-pack.c: move `.idx` files into place last Taylor Blau
2021-09-09 23:24 ` [PATCH v2 8/9] pack-write: split up finish_tmp_packfile() function Taylor Blau
2021-09-09 23:25 ` [PATCH v2 9/9] pack-objects: rename .idx files into place after .bitmap files Taylor Blau
2021-09-10 1:35 ` [PATCH v2 0/9] packfile: avoid .idx rename races Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=cover.1631228928.git.me@ttaylorr.com \
--to=me@ttaylorr.com \
--cc=avarab@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).