Skip to content

Commit 838cd34

Browse files
Nicolas Pitrespearce
authored andcommitted
fix pread()'s short read in index-pack
Since v1.6.0.2~13^2~ the completion of a thin pack uses sha1write() for its ability to compute a SHA1 on the written data. This also provides data buffering which, along with commit 92392b4, will confuse pread() whenever an appended object is 1) freed due to memory pressure because of the depth-first delta processing, and 2) needed again because it has many delta children, and 3) its data is still buffered by sha1write(). Let's fix the issue by simply forcing cached data out when such an object is written so it can be pread()'d at leisure. Signed-off-by: Nicolas Pitre <[email protected]> Signed-off-by: Shawn O. Pearce <[email protected]>
1 parent 44c33a5 commit 838cd34

File tree

3 files changed

+14
-6
lines changed

3 files changed

+14
-6
lines changed

csum-file.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#include "progress.h"
1212
#include "csum-file.h"
1313

14-
static void sha1flush(struct sha1file *f, unsigned int count)
14+
static void flush(struct sha1file *f, unsigned int count)
1515
{
1616
void *buf = f->buffer;
1717

@@ -32,22 +32,28 @@ static void sha1flush(struct sha1file *f, unsigned int count)
3232
}
3333
}
3434

35-
int sha1close(struct sha1file *f, unsigned char *result, unsigned int flags)
35+
void sha1flush(struct sha1file *f)
3636
{
37-
int fd;
3837
unsigned offset = f->offset;
3938

4039
if (offset) {
4140
SHA1_Update(&f->ctx, f->buffer, offset);
42-
sha1flush(f, offset);
41+
flush(f, offset);
4342
f->offset = 0;
4443
}
44+
}
45+
46+
int sha1close(struct sha1file *f, unsigned char *result, unsigned int flags)
47+
{
48+
int fd;
49+
50+
sha1flush(f);
4551
SHA1_Final(f->buffer, &f->ctx);
4652
if (result)
4753
hashcpy(result, f->buffer);
4854
if (flags & (CSUM_CLOSE | CSUM_FSYNC)) {
4955
/* write checksum and close fd */
50-
sha1flush(f, 20);
56+
flush(f, 20);
5157
if (flags & CSUM_FSYNC)
5258
fsync_or_die(f->fd, f->name);
5359
if (close(f->fd))
@@ -76,7 +82,7 @@ int sha1write(struct sha1file *f, void *buf, unsigned int count)
7682
left -= nr;
7783
if (!left) {
7884
SHA1_Update(&f->ctx, f->buffer, offset);
79-
sha1flush(f, offset);
85+
flush(f, offset);
8086
offset = 0;
8187
}
8288
f->offset = offset;

csum-file.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ extern struct sha1file *sha1fd(int fd, const char *name);
2424
extern struct sha1file *sha1fd_throughput(int fd, const char *name, struct progress *tp);
2525
extern int sha1close(struct sha1file *, unsigned char *, unsigned int);
2626
extern int sha1write(struct sha1file *, void *, unsigned int);
27+
extern void sha1flush(struct sha1file *f);
2728
extern void crc32_begin(struct sha1file *);
2829
extern uint32_t crc32_end(struct sha1file *);
2930

index-pack.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,7 @@ static struct object_entry *append_obj_to_pack(struct sha1file *f,
707707
obj[1].idx.offset = obj[0].idx.offset + n;
708708
obj[1].idx.offset += write_compressed(f, buf, size);
709709
obj[0].idx.crc32 = crc32_end(f);
710+
sha1flush(f);
710711
hashcpy(obj->idx.sha1, sha1);
711712
return obj;
712713
}

0 commit comments

Comments
 (0)