summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff King <peff@peff.net>2014-01-15 06:17:48 -0500
committerJunio C Hamano <gitster@pobox.com>2014-01-16 14:33:46 -0800
commit1a6d8b91489ad4a7b7d267b46a3e838b004157f1 (patch)
tree378ef94598da25719d848ddada2984bedf768b3c
parentae4f07fbccaab6dc93be52c0f34e137dd9fcbcf4 (diff)
downloadgit-1a6d8b91489ad4a7b7d267b46a3e838b004157f1.tar.gz
do not discard revindex when re-preparing packfiles
When an object lookup fails, we re-read the objects/pack directory to pick up any new packfiles that may have been created since our last read. We also discard any pack revindex structs we've allocated. The discarding is a problem for the pack-bitmap code, which keeps a pointer to the revindex for the bitmapped pack. After the discard, the pointer is invalid, and we may read free()d memory. Other revindex users do not keep a bare pointer to the revindex; instead, they always access it through revindex_for_pack(), which lazily builds the revindex. So one solution is to teach the pack-bitmap code a similar trick. It would be slightly less efficient, but probably not all that noticeable. However, it turns out this discarding is not actually necessary. When we call reprepare_packed_git, we do not throw away our old pack list. We keep the existing entries, and only add in new ones. So there is no safety problem; we will still have the pack struct that matches each revindex. The packfile itself may go away, of course, but we are already prepared to handle that, and it may happen outside of reprepare_packed_git anyway. Throwing away the revindex may save some RAM if the pack never gets reused (about 12 bytes per object). But it also wastes some CPU time (to regenerate the index) if the pack does get reused. It's hard to say which is more valuable, but in either case, it happens very rarely (only when we race with a simultaneous repack). Just leaving the revindex in place is simple and safe both for current and future code. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--pack-revindex.c11
-rw-r--r--pack-revindex.h1
-rw-r--r--sha1_file.c1
3 files changed, 0 insertions, 13 deletions
diff --git a/pack-revindex.c b/pack-revindex.c
index 0bb13b1ba6..5bd7c61980 100644
--- a/pack-revindex.c
+++ b/pack-revindex.c
@@ -245,14 +245,3 @@ struct revindex_entry *find_pack_revindex(struct packed_git *p, off_t ofs)
return pridx->revindex + pos;
}
-
-void discard_revindex(void)
-{
- if (pack_revindex_hashsz) {
- int i;
- for (i = 0; i < pack_revindex_hashsz; i++)
- free(pack_revindex[i].revindex);
- free(pack_revindex);
- pack_revindex_hashsz = 0;
- }
-}
diff --git a/pack-revindex.h b/pack-revindex.h
index 866ca9c571..d737f98965 100644
--- a/pack-revindex.h
+++ b/pack-revindex.h
@@ -15,6 +15,5 @@ struct pack_revindex *revindex_for_pack(struct packed_git *p);
int find_revindex_position(struct pack_revindex *pridx, off_t ofs);
struct revindex_entry *find_pack_revindex(struct packed_git *p, off_t ofs);
-void discard_revindex(void);
#endif
diff --git a/sha1_file.c b/sha1_file.c
index 129496250c..36d55c05f7 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -1279,7 +1279,6 @@ void prepare_packed_git(void)
void reprepare_packed_git(void)
{
- discard_revindex();
prepare_packed_git_run_once = 0;
prepare_packed_git();
}