Make it much safer: we write to a temporary file, and then link that
temporary file to the final destination. This avoids all the nasty
races if several people write the same object at the same time.
It should also result in nicer on-disk layout, since it means that
objects all get created in the same subdirectory. That makes a lot
of block allocation algorithms happier, since the objects will now
be allocated from the same zone.
@ -128,9 +128,6 @@ extern int index_fd(unsigned char *sha1, int fd, struct stat *st);
@@ -128,9 +128,6 @@ extern int index_fd(unsigned char *sha1, int fd, struct stat *st);
/* Return a statically allocated filename matching the sha1 signature */
@ -284,8 +284,9 @@ int write_sha1_file(char *buf, unsigned long len, const char *type, unsigned cha
@@ -284,8 +284,9 @@ int write_sha1_file(char *buf, unsigned long len, const char *type, unsigned cha
unsigned char sha1[20];
SHA_CTX c;
char *filename;
static char tmpfile[PATH_MAX];
char hdr[50];
int fd, hdrlen;
int fd, hdrlen, ret;
/* Generate the header */
hdrlen = sprintf(hdr, "%s %lu", type, len)+1;
@ -300,18 +301,28 @@ int write_sha1_file(char *buf, unsigned long len, const char *type, unsigned cha
@@ -300,18 +301,28 @@ int write_sha1_file(char *buf, unsigned long len, const char *type, unsigned cha
@ -338,54 +349,21 @@ int write_sha1_file(char *buf, unsigned long len, const char *type, unsigned cha
@@ -338,54 +349,21 @@ int write_sha1_file(char *buf, unsigned long len, const char *type, unsigned cha
if (write(fd, compressed, size) != size)
die("unable to write file");
fchmod(fd, 0444);
close(fd);
return 0;
}
static inline int collision_check(char *filename, void *buf, unsigned int size)
{
#ifdef COLLISION_CHECK
void *map;
int fd = open(filename, O_RDONLY);
struct stat st;
int cmp;
/* Unreadable object, or object went away? Strange. */