summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cache.h1
-rw-r--r--fast-import.c6
-rw-r--r--sha1_file.c16
3 files changed, 21 insertions, 2 deletions
diff --git a/cache.h b/cache.h
index 24735bdfee..549f4bbac7 100644
--- a/cache.h
+++ b/cache.h
@@ -561,6 +561,7 @@ extern struct packed_git *find_sha1_pack(const unsigned char *sha1,
extern void pack_report(void);
extern int open_pack_index(struct packed_git *);
extern unsigned char* use_pack(struct packed_git *, struct pack_window **, off_t, unsigned int *);
+extern void close_pack_windows(struct packed_git *);
extern void unuse_pack(struct pack_window **);
extern struct packed_git *add_packed_git(const char *, int, int);
extern const unsigned char *nth_packed_object_sha1(struct packed_git *, uint32_t);
diff --git a/fast-import.c b/fast-import.c
index 4cf5092976..5e89eef1aa 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -917,6 +917,7 @@ static void end_packfile(void)
struct branch *b;
struct tag *t;
+ close_pack_windows(pack_data);
fixup_pack_header_footer(pack_data->pack_fd, pack_data->sha1,
pack_data->pack_name, object_count);
close(pack_data->pack_fd);
@@ -926,7 +927,6 @@ static void end_packfile(void)
new_p = add_packed_git(idx_name, strlen(idx_name), 1);
if (!new_p)
die("core git rejected index %s", idx_name);
- new_p->windows = old_p->windows;
all_packs[pack_id] = new_p;
install_packed_git(new_p);
@@ -1129,8 +1129,10 @@ static void *gfi_unpack_entry(
{
enum object_type type;
struct packed_git *p = all_packs[oe->pack_id];
- if (p == pack_data)
+ if (p == pack_data && p->pack_size < (pack_size + 20)) {
+ close_pack_windows(p);
p->pack_size = pack_size + 20;
+ }
return unpack_entry(p, oe->offset, &type, sizep);
}
diff --git a/sha1_file.c b/sha1_file.c
index 6583797ce5..66a4e00fa8 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -611,6 +611,22 @@ void release_pack_memory(size_t need, int fd)
; /* nothing */
}
+void close_pack_windows(struct packed_git *p)
+{
+ while (p->windows) {
+ struct pack_window *w = p->windows;
+
+ if (w->inuse_cnt)
+ die("pack '%s' still has open windows to it",
+ p->pack_name);
+ munmap(w->base, w->len);
+ pack_mapped -= w->len;
+ pack_open_windows--;
+ p->windows = w->next;
+ free(w);
+ }
+}
+
void unuse_pack(struct pack_window **w_cursor)
{
struct pack_window *w = *w_cursor;