Skip to content

Commit 4c81b03

Browse files
torvaldsgitster
authored andcommitted
Make pack creation always fsync() the result
This means that we can depend on packs always being stable on disk, simplifying a lot of the object serialization worries. And unlike loose objects, serializing pack creation IO isn't going to be a performance killer. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent d2b3691 commit 4c81b03

File tree

8 files changed

+24
-6
lines changed

8 files changed

+24
-6
lines changed

builtin-pack-objects.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -515,10 +515,12 @@ static void write_pack_file(void)
515515
* If so, rewrite it like in fast-import
516516
*/
517517
if (pack_to_stdout || nr_written == nr_remaining) {
518-
sha1close(f, sha1, 1);
518+
unsigned flags = pack_to_stdout ? CSUM_CLOSE : CSUM_FSYNC;
519+
sha1close(f, sha1, flags);
519520
} else {
520521
int fd = sha1close(f, NULL, 0);
521522
fixup_pack_header_footer(fd, sha1, pack_tmp_name, nr_written);
523+
fsync_or_die(fd, pack_tmp_name);
522524
close(fd);
523525
}
524526

cache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,7 @@ extern ssize_t write_in_full(int fd, const void *buf, size_t count);
761761
extern void write_or_die(int fd, const void *buf, size_t count);
762762
extern int write_or_whine(int fd, const void *buf, size_t count, const char *msg);
763763
extern int write_or_whine_pipe(int fd, const void *buf, size_t count, const char *msg);
764+
extern void fsync_or_die(int fd, const char *);
764765

765766
/* pager.c */
766767
extern void setup_pager(void);

csum-file.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,21 +32,24 @@ static void sha1flush(struct sha1file *f, unsigned int count)
3232
}
3333
}
3434

35-
int sha1close(struct sha1file *f, unsigned char *result, int final)
35+
int sha1close(struct sha1file *f, unsigned char *result, unsigned int flags)
3636
{
3737
int fd;
3838
unsigned offset = f->offset;
39+
3940
if (offset) {
4041
SHA1_Update(&f->ctx, f->buffer, offset);
4142
sha1flush(f, offset);
4243
f->offset = 0;
4344
}
44-
if (final) {
45+
if (flags & (CSUM_CLOSE | CSUM_FSYNC)) {
4546
/* write checksum and close fd */
4647
SHA1_Final(f->buffer, &f->ctx);
4748
if (result)
4849
hashcpy(result, f->buffer);
4950
sha1flush(f, 20);
51+
if (flags & CSUM_FSYNC)
52+
fsync_or_die(f->fd, f->name);
5053
if (close(f->fd))
5154
die("%s: sha1 file error on close (%s)",
5255
f->name, strerror(errno));

csum-file.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,13 @@ struct sha1file {
1616
unsigned char buffer[8192];
1717
};
1818

19+
/* sha1close flags */
20+
#define CSUM_CLOSE 1
21+
#define CSUM_FSYNC 2
22+
1923
extern struct sha1file *sha1fd(int fd, const char *name);
2024
extern struct sha1file *sha1fd_throughput(int fd, const char *name, struct progress *tp);
21-
extern int sha1close(struct sha1file *, unsigned char *, int);
25+
extern int sha1close(struct sha1file *, unsigned char *, unsigned int);
2226
extern int sha1write(struct sha1file *, void *, unsigned int);
2327
extern void crc32_begin(struct sha1file *);
2428
extern uint32_t crc32_end(struct sha1file *);

fast-import.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -890,7 +890,7 @@ static char *create_index(void)
890890
SHA1_Update(&ctx, (*c)->sha1, 20);
891891
}
892892
sha1write(f, pack_data->sha1, sizeof(pack_data->sha1));
893-
sha1close(f, NULL, 1);
893+
sha1close(f, NULL, CSUM_FSYNC);
894894
free(idx);
895895
SHA1_Final(pack_data->sha1, &ctx);
896896
return tmpfile;

index-pack.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,7 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
694694
if (!from_stdin) {
695695
close(input_fd);
696696
} else {
697+
fsync_or_die(output_fd, curr_pack_name);
697698
err = close(output_fd);
698699
if (err)
699700
die("error while closing pack file: %s", strerror(errno));

pack-write.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ char *write_idx_file(char *index_name, struct pack_idx_entry **objects,
139139
}
140140

141141
sha1write(f, sha1, 20);
142-
sha1close(f, NULL, 1);
142+
sha1close(f, NULL, CSUM_FSYNC);
143143
SHA1_Final(sha1, &ctx);
144144
return index_name;
145145
}

write_or_die.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,13 @@ ssize_t write_in_full(int fd, const void *buf, size_t count)
7878
return total;
7979
}
8080

81+
void fsync_or_die(int fd, const char *msg)
82+
{
83+
if (fsync(fd) < 0) {
84+
die("%s: fsync error (%s)", msg, strerror(errno));
85+
}
86+
}
87+
8188
void write_or_die(int fd, const void *buf, size_t count)
8289
{
8390
if (write_in_full(fd, buf, count) < 0) {

0 commit comments

Comments
 (0)