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.
maint
Linus Torvalds 2005-04-20 12:36:41 -07:00
parent 4990aadc4c
commit ca9be05421
2 changed files with 21 additions and 24 deletions

View File

@ -28,7 +28,6 @@ struct cache_header {
unsigned int hdr_signature; unsigned int hdr_signature;
unsigned int hdr_version; unsigned int hdr_version;
unsigned int hdr_entries; unsigned int hdr_entries;
unsigned char sha1[20];
}; };


/* /*

View File

@ -161,14 +161,13 @@ static int verify_hdr(struct cache_header *hdr, unsigned long size)


if (hdr->hdr_signature != htonl(CACHE_SIGNATURE)) if (hdr->hdr_signature != htonl(CACHE_SIGNATURE))
return error("bad signature"); return error("bad signature");
if (hdr->hdr_version != htonl(1)) if (hdr->hdr_version != htonl(2))
return error("bad version"); return error("bad index version");
SHA1_Init(&c); SHA1_Init(&c);
SHA1_Update(&c, hdr, offsetof(struct cache_header, sha1)); SHA1_Update(&c, hdr, size - 20);
SHA1_Update(&c, hdr+1, size - sizeof(*hdr));
SHA1_Final(sha1, &c); SHA1_Final(sha1, &c);
if (memcmp(sha1, hdr->sha1, 20)) if (memcmp(sha1, (void *)hdr + size - 20, 20))
return error("bad header sha1"); return error("bad index file sha1 signature");
return 0; return 0;
} }


@ -198,7 +197,7 @@ int read_cache(void)
if (!fstat(fd, &st)) { if (!fstat(fd, &st)) {
size = st.st_size; size = st.st_size;
errno = EINVAL; 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); map = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
} }
close(fd); close(fd);
@ -231,7 +230,7 @@ unmap:
static char write_buffer[WRITE_BUFFER_SIZE]; static char write_buffer[WRITE_BUFFER_SIZE];
static unsigned long write_buffer_len; 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) { while (len) {
unsigned int buffered = write_buffer_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); memcpy(write_buffer + buffered, data, partial);
buffered += partial; buffered += partial;
if (buffered == WRITE_BUFFER_SIZE) { if (buffered == WRITE_BUFFER_SIZE) {
SHA1_Update(context, write_buffer, WRITE_BUFFER_SIZE);
if (write(fd, write_buffer, WRITE_BUFFER_SIZE) != WRITE_BUFFER_SIZE) if (write(fd, write_buffer, WRITE_BUFFER_SIZE) != WRITE_BUFFER_SIZE)
return -1; return -1;
buffered = 0; buffered = 0;
@ -252,14 +252,20 @@ static int ce_write(int fd, void *data, unsigned int len)
return 0; return 0;
} }


static int ce_flush(int fd) static int ce_flush(SHA_CTX *context, int fd)
{ {
unsigned int left = write_buffer_len; unsigned int left = write_buffer_len;

if (left) { if (left) {
write_buffer_len = 0; write_buffer_len = 0;
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) if (write(fd, write_buffer, left) != left)
return -1; return -1;
}
return 0; return 0;
} }


@ -270,25 +276,17 @@ int write_cache(int newfd, struct cache_entry **cache, int entries)
int i; int i;


hdr.hdr_signature = htonl(CACHE_SIGNATURE); hdr.hdr_signature = htonl(CACHE_SIGNATURE);
hdr.hdr_version = htonl(1); hdr.hdr_version = htonl(2);
hdr.hdr_entries = htonl(entries); hdr.hdr_entries = htonl(entries);


SHA1_Init(&c); SHA1_Init(&c);
SHA1_Update(&c, &hdr, offsetof(struct cache_header, sha1)); if (ce_write(&c, newfd, &hdr, sizeof(hdr)) < 0)
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)
return -1; return -1;


for (i = 0; i < entries; i++) { for (i = 0; i < entries; i++) {
struct cache_entry *ce = cache[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 -1;
} }
return ce_flush(newfd); return ce_flush(&c, newfd);
} }