From: Linus Torvalds Date: Wed, 20 Apr 2005 19:36:41 +0000 (-0700) Subject: Make the sha1 of the index file go at the very end of the file. X-Git-Tag: v0.99~796 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=ca9be05421ff3b641182ab4063c7c3ac834750b5;p=git.git Make the sha1 of the index file go at the very end of the file. This allows us to both calculate it and verify it faster. --- diff --git a/cache.h b/cache.h index dd91a7180..eab355da5 100644 --- 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]; }; /* diff --git a/read-cache.c b/read-cache.c index c3beb6748..d1cc1e8c7 100644 --- a/read-cache.c +++ b/read-cache.c @@ -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); }