Commit 0ddfcb40 by Carlos Martín Nieto

Switch to index_version as "git_pack_file is ready" flag

We use p->index_map.data to check whether the struct has been set up
and all the information about the index is stored there. This variable
gets set up halfway through the setup process, however, and a thread
can come along and use fields that haven't been written to yet.

Crucially, pack_entry_find_offset() needs to read the index version
(which is written after index_map) to know the offset and stride
length to pass to sha1_entry_pos(). If these values are wrong,
assertions in it will fail, as it will be reading bogus data.

Make index_version the last field to be written and switch from using
p->index_map.data to p->index_version as "git_pack_file is ready" flag
as we can use it to know if every field has been written.
parent 34bd5999
...@@ -293,8 +293,8 @@ static int pack_index_check(const char *path, struct git_pack_file *p) ...@@ -293,8 +293,8 @@ static int pack_index_check(const char *path, struct git_pack_file *p)
} }
} }
p->index_version = version;
p->num_objects = nr; p->num_objects = nr;
p->index_version = version;
return 0; return 0;
} }
...@@ -304,7 +304,7 @@ static int pack_index_open(struct git_pack_file *p) ...@@ -304,7 +304,7 @@ static int pack_index_open(struct git_pack_file *p)
int error = 0; int error = 0;
size_t name_len, base_len; size_t name_len, base_len;
if (p->index_map.data) if (p->index_version > -1)
return 0; return 0;
name_len = strlen(p->pack_name); name_len = strlen(p->pack_name);
...@@ -320,7 +320,7 @@ static int pack_index_open(struct git_pack_file *p) ...@@ -320,7 +320,7 @@ static int pack_index_open(struct git_pack_file *p)
if ((error = git_mutex_lock(&p->lock)) < 0) if ((error = git_mutex_lock(&p->lock)) < 0)
return error; return error;
if (!p->index_map.data) if (p->index_version == -1)
error = pack_index_check(idx_name, p); error = pack_index_check(idx_name, p);
git__free(idx_name); git__free(idx_name);
...@@ -826,7 +826,7 @@ static int packfile_open(struct git_pack_file *p) ...@@ -826,7 +826,7 @@ static int packfile_open(struct git_pack_file *p)
git_oid sha1; git_oid sha1;
unsigned char *idx_sha1; unsigned char *idx_sha1;
if (!p->index_map.data && pack_index_open(p) < 0) if (p->index_version == -1 && pack_index_open(p) < 0)
return git_odb__error_notfound("failed to open packfile", NULL); return git_odb__error_notfound("failed to open packfile", NULL);
/* if mwf opened by another thread, return now */ /* if mwf opened by another thread, return now */
...@@ -942,6 +942,7 @@ int git_packfile_alloc(struct git_pack_file **pack_out, const char *path) ...@@ -942,6 +942,7 @@ int git_packfile_alloc(struct git_pack_file **pack_out, const char *path)
p->mwf.size = st.st_size; p->mwf.size = st.st_size;
p->pack_local = 1; p->pack_local = 1;
p->mtime = (git_time_t)st.st_mtime; p->mtime = (git_time_t)st.st_mtime;
p->index_version = -1;
git_mutex_init(&p->lock); git_mutex_init(&p->lock);
...@@ -1058,7 +1059,7 @@ static int pack_entry_find_offset( ...@@ -1058,7 +1059,7 @@ static int pack_entry_find_offset(
*offset_out = 0; *offset_out = 0;
if (index == NULL) { if (p->index_version == -1) {
int error; int error;
if ((error = pack_index_open(p)) < 0) if ((error = pack_index_open(p)) < 0)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment