Skip to content

Commit

Permalink
fix pread()'s short read in index-pack
Browse files Browse the repository at this point in the history
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 <nico@cam.org>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
  • Loading branch information
Nicolas Pitre authored and Shawn O. Pearce committed Oct 10, 2008
1 parent 44c33a5 commit 838cd34
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 6 deletions.
18 changes: 12 additions & 6 deletions csum-file.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include "progress.h"
#include "csum-file.h"

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

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

int sha1close(struct sha1file *f, unsigned char *result, unsigned int flags)
void sha1flush(struct sha1file *f)
{
int fd;
unsigned offset = f->offset;

if (offset) {
SHA1_Update(&f->ctx, f->buffer, offset);
sha1flush(f, offset);
flush(f, offset);
f->offset = 0;
}
}

int sha1close(struct sha1file *f, unsigned char *result, unsigned int flags)
{
int fd;

sha1flush(f);
SHA1_Final(f->buffer, &f->ctx);
if (result)
hashcpy(result, f->buffer);
if (flags & (CSUM_CLOSE | CSUM_FSYNC)) {
/* write checksum and close fd */
sha1flush(f, 20);
flush(f, 20);
if (flags & CSUM_FSYNC)
fsync_or_die(f->fd, f->name);
if (close(f->fd))
Expand Down Expand Up @@ -76,7 +82,7 @@ int sha1write(struct sha1file *f, void *buf, unsigned int count)
left -= nr;
if (!left) {
SHA1_Update(&f->ctx, f->buffer, offset);
sha1flush(f, offset);
flush(f, offset);
offset = 0;
}
f->offset = offset;
Expand Down
1 change: 1 addition & 0 deletions csum-file.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ extern struct sha1file *sha1fd(int fd, const char *name);
extern struct sha1file *sha1fd_throughput(int fd, const char *name, struct progress *tp);
extern int sha1close(struct sha1file *, unsigned char *, unsigned int);
extern int sha1write(struct sha1file *, void *, unsigned int);
extern void sha1flush(struct sha1file *f);
extern void crc32_begin(struct sha1file *);
extern uint32_t crc32_end(struct sha1file *);

Expand Down
1 change: 1 addition & 0 deletions index-pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,7 @@ static struct object_entry *append_obj_to_pack(struct sha1file *f,
obj[1].idx.offset = obj[0].idx.offset + n;
obj[1].idx.offset += write_compressed(f, buf, size);
obj[0].idx.crc32 = crc32_end(f);
sha1flush(f);
hashcpy(obj->idx.sha1, sha1);
return obj;
}
Expand Down

0 comments on commit 838cd34

Please sign in to comment.