Make the sha1 of the index file go at the very end of the file.
authorLinus Torvalds <torvalds@ppc970.osdl.org>
Wed, 20 Apr 2005 19:36:41 +0000 (12:36 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Wed, 20 Apr 2005 19:36:41 +0000 (12:36 -0700)
This allows us to both calculate it and verify it faster.

cache.h
read-cache.c

diff --git a/cache.h b/cache.h
index dd91a718088999faa41781583e942e11dd38d392..eab355da5d2f6595053f28f0cca61181ac314ee9 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -28,7 +28,6 @@ struct cache_header {
        unsigned int hdr_signature;
        unsigned int hdr_version;
        unsigned int hdr_entries;
-       unsigned char sha1[20];
 };
 
 /*
index c3beb6748c9983161895e0669591ba2dc37ce250..d1cc1e8c787da8ab7e44d5869a408b66fb4f0ef1 100644 (file)
@@ -161,14 +161,13 @@ static int verify_hdr(struct cache_header *hdr, unsigned long size)
 
        if (hdr->hdr_signature != htonl(CACHE_SIGNATURE))
                return error("bad signature");
-       if (hdr->hdr_version != htonl(1))
-               return error("bad version");
+       if (hdr->hdr_version != htonl(2))
+               return error("bad index version");
        SHA1_Init(&c);
-       SHA1_Update(&c, hdr, offsetof(struct cache_header, sha1));
-       SHA1_Update(&c, hdr+1, size - sizeof(*hdr));
+       SHA1_Update(&c, hdr, size - 20);
        SHA1_Final(sha1, &c);
-       if (memcmp(sha1, hdr->sha1, 20))
-               return error("bad header sha1");
+       if (memcmp(sha1, (void *)hdr + size - 20, 20))
+               return error("bad index file sha1 signature");
        return 0;
 }
 
@@ -198,7 +197,7 @@ int read_cache(void)
        if (!fstat(fd, &st)) {
                size = st.st_size;
                errno = EINVAL;
-               if (size >= sizeof(struct cache_header))
+               if (size >= sizeof(struct cache_header) + 20)
                        map = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
        }
        close(fd);
@@ -231,7 +230,7 @@ unmap:
 static char write_buffer[WRITE_BUFFER_SIZE];
 static unsigned long write_buffer_len;
 
-static int ce_write(int fd, void *data, unsigned int len)
+static int ce_write(SHA_CTX *context, int fd, void *data, unsigned int len)
 {
        while (len) {
                unsigned int buffered = write_buffer_len;
@@ -241,6 +240,7 @@ static int ce_write(int fd, void *data, unsigned int len)
                memcpy(write_buffer + buffered, data, partial);
                buffered += partial;
                if (buffered == WRITE_BUFFER_SIZE) {
+                       SHA1_Update(context, write_buffer, WRITE_BUFFER_SIZE);
                        if (write(fd, write_buffer, WRITE_BUFFER_SIZE) != WRITE_BUFFER_SIZE)
                                return -1;
                        buffered = 0;
@@ -252,14 +252,20 @@ static int ce_write(int fd, void *data, unsigned int len)
        return 0;
 }
 
-static int ce_flush(int fd)
+static int ce_flush(SHA_CTX *context, int fd)
 {
        unsigned int left = write_buffer_len;
+
        if (left) {
                write_buffer_len = 0;
-               if (write(fd, write_buffer, left) != left)
-                       return -1;
+               SHA1_Update(context, write_buffer, left);
        }
+
+       /* Append the SHA1 signature at the end */
+       SHA1_Final(write_buffer + left, context);
+       left += 20;
+       if (write(fd, write_buffer, left) != left)
+               return -1;
        return 0;
 }
 
@@ -270,25 +276,17 @@ int write_cache(int newfd, struct cache_entry **cache, int entries)
        int i;
 
        hdr.hdr_signature = htonl(CACHE_SIGNATURE);
-       hdr.hdr_version = htonl(1);
+       hdr.hdr_version = htonl(2);
        hdr.hdr_entries = htonl(entries);
 
        SHA1_Init(&c);
-       SHA1_Update(&c, &hdr, offsetof(struct cache_header, sha1));
-       for (i = 0; i < entries; i++) {
-               struct cache_entry *ce = cache[i];
-               int size = ce_size(ce);
-               SHA1_Update(&c, ce, size);
-       }
-       SHA1_Final(hdr.sha1, &c);
-
-       if (ce_write(newfd, &hdr, sizeof(hdr)) < 0)
+       if (ce_write(&c, newfd, &hdr, sizeof(hdr)) < 0)
                return -1;
 
        for (i = 0; i < entries; i++) {
                struct cache_entry *ce = cache[i];
-               if (ce_write(newfd, ce, ce_size(ce)) < 0)
+               if (ce_write(&c, newfd, ce, ce_size(ce)) < 0)
                        return -1;
        }
-       return ce_flush(newfd);
+       return ce_flush(&c, newfd);
 }