Split index file version specific functionality to their own functions,
to prepare for moving the index file version specific parts to their own
file.  This makes it easier to add a new index file format later.

Signed-off-by: Thomas Gummerer <t.gumme...@gmail.com>
---
 cache.h              |   5 +-
 read-cache.c         | 130 +++++++++++++++++++++++++++++++++------------------
 test-index-version.c |   2 +-
 3 files changed, 90 insertions(+), 47 deletions(-)

diff --git a/cache.h b/cache.h
index c288678..7af853b 100644
--- a/cache.h
+++ b/cache.h
@@ -100,9 +100,12 @@ unsigned long git_deflate_bound(git_zstream *, unsigned 
long);
  */
 
 #define CACHE_SIGNATURE 0x44495243     /* "DIRC" */
-struct cache_header {
+struct cache_version_header {
        unsigned int hdr_signature;
        unsigned int hdr_version;
+};
+
+struct cache_header {
        unsigned int hdr_entries;
 };
 
diff --git a/read-cache.c b/read-cache.c
index d5201f9..93947bf 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -1268,10 +1268,8 @@ struct ondisk_cache_entry_extended {
                            ondisk_cache_entry_extended_size(ce_namelen(ce)) : \
                            ondisk_cache_entry_size(ce_namelen(ce)))
 
-static int verify_hdr(struct cache_header *hdr, unsigned long size)
+static int verify_hdr_version(struct cache_version_header *hdr, unsigned long 
size)
 {
-       git_SHA_CTX c;
-       unsigned char sha1[20];
        int hdr_version;
 
        if (hdr->hdr_signature != htonl(CACHE_SIGNATURE))
@@ -1279,10 +1277,22 @@ static int verify_hdr(struct cache_header *hdr, 
unsigned long size)
        hdr_version = ntohl(hdr->hdr_version);
        if (hdr_version < INDEX_FORMAT_LB || INDEX_FORMAT_UB < hdr_version)
                return error("bad index version %d", hdr_version);
+       return 0;
+}
+
+static int verify_hdr(void *mmap, unsigned long size)
+{
+       git_SHA_CTX c;
+       unsigned char sha1[20];
+
+       if (size < sizeof(struct cache_version_header)
+           + sizeof(struct cache_header) + 20)
+               die("index file smaller than expected");
+
        git_SHA1_Init(&c);
-       git_SHA1_Update(&c, hdr, size - 20);
+       git_SHA1_Update(&c, mmap, size - 20);
        git_SHA1_Final(sha1, &c);
-       if (hashcmp(sha1, (unsigned char *)hdr + size - 20))
+       if (hashcmp(sha1, (unsigned char *)mmap + size - 20))
                return error("bad index file sha1 signature");
        return 0;
 }
@@ -1424,47 +1434,19 @@ static struct cache_entry *create_from_disk(struct 
ondisk_cache_entry *ondisk,
        return ce;
 }
 
-/* remember to discard_cache() before reading a different cache! */
-int read_index_from(struct index_state *istate, const char *path)
+static int read_index_v2(struct index_state *istate, void *mmap, unsigned long 
mmap_size)
 {
-       int fd, i;
-       struct stat st;
+       int i;
        unsigned long src_offset;
-       struct cache_header *hdr;
-       void *mmap;
-       size_t mmap_size;
+       struct cache_version_header *hdr;
+       struct cache_header *hdr_v2;
        struct strbuf previous_name_buf = STRBUF_INIT, *previous_name;
 
-       if (istate->initialized)
-               return istate->cache_nr;
-
-       istate->timestamp.sec = 0;
-       istate->timestamp.nsec = 0;
-       fd = open(path, O_RDONLY);
-       if (fd < 0) {
-               if (errno == ENOENT)
-                       return 0;
-               die_errno("index file open failed");
-       }
-
-       if (fstat(fd, &st))
-               die_errno("cannot stat the open index");
-
-       mmap_size = xsize_t(st.st_size);
-       if (mmap_size < sizeof(struct cache_header) + 20)
-               die("index file smaller than expected");
-
-       mmap = xmmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 
0);
-       if (mmap == MAP_FAILED)
-               die_errno("unable to map index file");
-       close(fd);
-
        hdr = mmap;
-       if (verify_hdr(hdr, mmap_size) < 0)
-               goto unmap;
+       hdr_v2 = (struct cache_header *)((char *)mmap + sizeof(*hdr));
 
        istate->version = ntohl(hdr->hdr_version);
-       istate->cache_nr = ntohl(hdr->hdr_entries);
+       istate->cache_nr = ntohl(hdr_v2->hdr_entries);
        istate->cache_alloc = alloc_nr(istate->cache_nr);
        istate->cache = xcalloc(istate->cache_alloc, sizeof(*istate->cache));
        istate->initialized = 1;
@@ -1474,7 +1456,7 @@ int read_index_from(struct index_state *istate, const 
char *path)
        else
                previous_name = NULL;
 
-       src_offset = sizeof(*hdr);
+       src_offset = sizeof(*hdr) + sizeof(*hdr_v2);
        for (i = 0; i < istate->cache_nr; i++) {
                struct ondisk_cache_entry *disk_ce;
                struct cache_entry *ce;
@@ -1487,8 +1469,6 @@ int read_index_from(struct index_state *istate, const 
char *path)
                src_offset += consumed;
        }
        strbuf_release(&previous_name_buf);
-       istate->timestamp.sec = st.st_mtime;
-       istate->timestamp.nsec = ST_MTIME_NSEC(st);
 
        while (src_offset <= mmap_size - 20 - 8) {
                /* After an array of active_nr index entries,
@@ -1508,6 +1488,58 @@ int read_index_from(struct index_state *istate, const 
char *path)
                src_offset += 8;
                src_offset += extsize;
        }
+       return 0;
+unmap:
+       munmap(mmap, mmap_size);
+       die("index file corrupt");
+}
+
+/* remember to discard_cache() before reading a different cache! */
+int read_index_from(struct index_state *istate, const char *path)
+{
+       int fd;
+       struct stat st;
+       struct cache_version_header *hdr;
+       void *mmap;
+       size_t mmap_size;
+
+       errno = EBUSY;
+       if (istate->initialized)
+               return istate->cache_nr;
+
+       errno = ENOENT;
+       istate->timestamp.sec = 0;
+       istate->timestamp.nsec = 0;
+       fd = open(path, O_RDONLY);
+       if (fd < 0) {
+               if (errno == ENOENT)
+                       return 0;
+               die_errno("index file open failed");
+       }
+
+       if (fstat(fd, &st))
+               die_errno("cannot stat the open index");
+
+       errno = EINVAL;
+       mmap_size = xsize_t(st.st_size);
+       if (mmap_size < sizeof(struct cache_header) + 20)
+               die("index file smaller than expected");
+
+       mmap = xmmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 
0);
+       close(fd);
+       if (mmap == MAP_FAILED)
+               die_errno("unable to map index file");
+
+       hdr = mmap;
+       if (verify_hdr_version(hdr, mmap_size) < 0)
+               goto unmap;
+
+       if (verify_hdr(mmap, mmap_size) < 0)
+               goto unmap;
+
+       read_index_v2(istate, mmap, mmap_size);
+       istate->timestamp.sec = st.st_mtime;
+       istate->timestamp.nsec = ST_MTIME_NSEC(st);
        munmap(mmap, mmap_size);
        return istate->cache_nr;
 
@@ -1771,10 +1803,11 @@ void update_index_if_able(struct index_state *istate, 
struct lock_file *lockfile
                rollback_lock_file(lockfile);
 }
 
-int write_index(struct index_state *istate, int newfd)
+static int write_index_v2(struct index_state *istate, int newfd)
 {
        git_SHA_CTX c;
-       struct cache_header hdr;
+       struct cache_version_header hdr;
+       struct cache_header hdr_v2;
        int i, err, removed, extended, hdr_version;
        struct cache_entry **cache = istate->cache;
        int entries = istate->cache_nr;
@@ -1804,11 +1837,13 @@ int write_index(struct index_state *istate, int newfd)
 
        hdr.hdr_signature = htonl(CACHE_SIGNATURE);
        hdr.hdr_version = htonl(hdr_version);
-       hdr.hdr_entries = htonl(entries - removed);
+       hdr_v2.hdr_entries = htonl(entries - removed);
 
        git_SHA1_Init(&c);
        if (ce_write(&c, newfd, &hdr, sizeof(hdr)) < 0)
                return -1;
+       if (ce_write(&c, newfd, &hdr_v2, sizeof(hdr_v2)) < 0)
+               return -1;
 
        previous_name = (hdr_version == 4) ? &previous_name_buf : NULL;
        for (i = 0; i < entries; i++) {
@@ -1854,6 +1889,11 @@ int write_index(struct index_state *istate, int newfd)
        return 0;
 }
 
+int write_index(struct index_state *istate, int newfd)
+{
+       return write_index_v2(istate, newfd);
+}
+
 /*
  * Read the index file that is potentially unmerged into given
  * index_state, dropping any unmerged entries.  Returns true if
diff --git a/test-index-version.c b/test-index-version.c
index 05d4699..4c0386f 100644
--- a/test-index-version.c
+++ b/test-index-version.c
@@ -2,7 +2,7 @@
 
 int main(int argc, char **argv)
 {
-       struct cache_header hdr;
+       struct cache_version_header hdr;
        int version;
 
        memset(&hdr,0,sizeof(hdr));
-- 
1.8.3.453.g1dfc63d

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to