commit - f63dc90df113ce7a79e0b477d5cbea9b61b5a460
commit + 2e5a6faddc98266ead5e12a17ceefe689cf9192e
blob - 1d8212ee1d7b2dff406fc259b64350befec9ebca
blob + 7a614213a52014c1c45ce8749b9340e9c1ad8d26
--- lib/got_lib_inflate.h
+++ lib/got_lib_inflate.h
FILE *);
const struct got_error *got_inflate_to_mem_fd(uint8_t **, size_t *, size_t *,
uint32_t *, size_t, int);
-const struct got_error *got_inflate_to_mem_mmap(uint8_t **, size_t *, uint8_t *,
- size_t, size_t);
+const struct got_error *got_inflate_to_mem_mmap(uint8_t **, size_t *, size_t *,
+ uint32_t *, uint8_t *, size_t, size_t);
const struct got_error *got_inflate_to_file(size_t *, FILE *, FILE *);
const struct got_error *got_inflate_to_file_fd(size_t *, int, FILE *);
const struct got_error *got_inflate_to_fd(size_t *, FILE *, int);
blob - e1e7cd506205b1d5951f680a97acc6c747d2fa59
blob + e94e2239ba047d0bcd52d285db28e19f3db75458
--- lib/inflate.c
+++ lib/inflate.c
}
const struct got_error *
-got_inflate_to_mem_mmap(uint8_t **outbuf, size_t *outlen, uint8_t *map,
- size_t offset, size_t len)
+got_inflate_to_mem_mmap(uint8_t **outbuf, size_t *outlen,
+ size_t *consumed_total, uint32_t *input_crc, uint8_t *map, size_t offset,
+ size_t len)
{
const struct got_error *err;
size_t avail, consumed;
void *newbuf;
int nbuf = 1;
- *outbuf = malloc(GOT_INFLATE_BUFSIZE);
- if (*outbuf == NULL)
- return got_error_from_errno("malloc");
- err = got_inflate_init(&zb, *outbuf, GOT_INFLATE_BUFSIZE, NULL);
- if (err) {
- free(*outbuf);
- *outbuf = NULL;
- return err;
+ if (outbuf) {
+ *outbuf = malloc(GOT_INFLATE_BUFSIZE);
+ if (*outbuf == NULL)
+ return got_error_from_errno("malloc");
+ err = got_inflate_init(&zb, *outbuf, GOT_INFLATE_BUFSIZE,
+ input_crc);
+ if (err) {
+ free(*outbuf);
+ *outbuf = NULL;
+ return err;
+ }
+ } else {
+ err = got_inflate_init(&zb, NULL, GOT_INFLATE_BUFSIZE,
+ input_crc);
}
*outlen = 0;
-
+ if (consumed_total)
+ *consumed_total = 0;
do {
err = got_inflate_read_mmap(&zb, map, offset, len, &avail,
&consumed);
if (err)
goto done;
offset += consumed;
+ if (consumed_total)
+ *consumed_total += consumed;
len -= consumed;
*outlen += avail;
if (len == 0)
break;
if (zb.flags & GOT_INFLATE_F_HAVE_MORE) {
+ if (outbuf == NULL)
+ continue;
newbuf = reallocarray(*outbuf, ++nbuf,
GOT_INFLATE_BUFSIZE);
if (newbuf == NULL) {
blob - e5817bcdb4d07c0921e5917a0ca6502ae3d96c55
blob + 8375932b1a549d1b7a8bd3d63a7da71b3c051bd5
--- lib/pack.c
+++ lib/pack.c
if (pack->map) {
if (delta_data_offset >= pack->filesize)
return got_error(GOT_ERR_PACK_OFFSET);
- err = got_inflate_to_mem_mmap(delta_buf, delta_len, pack->map,
- delta_data_offset, pack->filesize - delta_data_offset);
+ err = got_inflate_to_mem_mmap(delta_buf, delta_len,
+ NULL, NULL, pack->map, delta_data_offset,
+ pack->filesize - delta_data_offset);
} else {
if (lseek(pack->fd, delta_data_offset, SEEK_SET) == -1)
return got_error_from_errno("lseek");
if (pack->map) {
mapoff = (size_t)delta_data_offset;
err = got_inflate_to_mem_mmap(&base_buf,
- &base_bufsz, pack->map, mapoff,
+ &base_bufsz, NULL, NULL,
+ pack->map, mapoff,
pack->filesize - mapoff);
} else
err = got_inflate_to_mem_fd(&base_buf,
if (pack->map) {
size_t mapoff = (size_t)delta_data_offset;
err = got_inflate_to_mem_mmap(&base_buf,
- &base_bufsz, pack->map, mapoff,
- pack->filesize - mapoff);
+ &base_bufsz, NULL, NULL, pack->map,
+ mapoff, pack->filesize - mapoff);
} else {
if (lseek(pack->fd, delta_data_offset, SEEK_SET)
== -1) {
return got_error(GOT_ERR_PACK_OFFSET);
if (pack->map) {
size_t mapoff = (size_t)obj->pack_offset;
- err = got_inflate_to_mem_mmap(buf, len, pack->map,
- mapoff, pack->filesize - mapoff);
+ err = got_inflate_to_mem_mmap(buf, len, NULL, NULL,
+ pack->map, mapoff, pack->filesize - mapoff);
} else {
if (lseek(pack->fd, obj->pack_offset, SEEK_SET) == -1)
return got_error_from_errno("lseek");
blob - 53e4b08d5ce99323c387425fc8a84c9d714f547e
blob + 05e55c20f5d2a0e9c7ddd22c6d4921640d54aadc
--- libexec/got-index-pack/got-index-pack.c
+++ libexec/got-index-pack/got-index-pack.c
#include <sys/time.h>
#include <sys/types.h>
#include <sys/uio.h>
+#include <sys/mman.h>
#include <stdint.h>
#include <errno.h>
char *header;
size_t headerlen;
const char *obj_label;
+ size_t mapoff = obj->off;
err = got_pack_parse_object_type_and_size(&obj->type, &obj->size,
&obj->tslen, pack, obj->off);
if (err)
return err;
- /* XXX Seek back and get the CRC of on-disk type+size bytes. */
- if (lseek(pack->fd, obj->off, SEEK_SET) == -1)
- return got_error_from_errno("lseek");
- err = read_crc(&obj->crc, pack->fd, obj->tslen);
- if (err)
- return err;
+ if (pack->map) {
+ obj->crc = crc32(obj->crc, pack->map + mapoff, obj->tslen);
+ mapoff += obj->tslen;
+ } else {
+ /* XXX Seek back and get the CRC of on-disk type+size bytes. */
+ if (lseek(pack->fd, obj->off, SEEK_SET) == -1)
+ return got_error_from_errno("lseek");
+ err = read_crc(&obj->crc, pack->fd, obj->tslen);
+ if (err)
+ return err;
+ }
switch (obj->type) {
case GOT_OBJ_TYPE_BLOB:
case GOT_OBJ_TYPE_TREE:
case GOT_OBJ_TYPE_TAG:
/* XXX TODO reading large objects into memory is bad! */
- err = got_inflate_to_mem_fd(&data, &datalen, &obj->len,
- &obj->crc, obj->size, pack->fd);
+ if (pack->map) {
+ err = got_inflate_to_mem_mmap(&data, &datalen,
+ &obj->len, &obj->crc, pack->map, mapoff,
+ pack->filesize - mapoff);
+ } else {
+ err = got_inflate_to_mem_fd(&data, &datalen,
+ &obj->len, &obj->crc, obj->size, pack->fd);
+ }
if (err)
break;
SHA1Init(&ctx);
break;
case GOT_OBJ_TYPE_REF_DELTA:
memset(obj->id.sha1, 0xff, SHA1_DIGEST_LENGTH);
- n = read(pack->fd, obj->delta.ref.ref_id.sha1,
- SHA1_DIGEST_LENGTH);
- if (n == -1) {
- err = got_error_from_errno("read");
- break;
- }
- if (n < sizeof(obj->id)) {
- err = got_error(GOT_ERR_BAD_PACKFILE);
- break;
+ if (pack->map) {
+ if (mapoff + SHA1_DIGEST_LENGTH >= pack->filesize) {
+ err = got_error(GOT_ERR_BAD_PACKFILE);
+ break;
+ }
+ memcpy(obj->delta.ref.ref_id.sha1, pack->map + mapoff,
+ SHA1_DIGEST_LENGTH);
+ obj->crc = crc32(obj->crc, pack->map + mapoff,
+ SHA1_DIGEST_LENGTH);
+ mapoff += SHA1_DIGEST_LENGTH;
+ err = got_inflate_to_mem_mmap(NULL, &datalen,
+ &obj->len, &obj->crc, pack->map, mapoff,
+ pack->filesize - mapoff);
+ if (err)
+ break;
+ } else {
+ n = read(pack->fd, obj->delta.ref.ref_id.sha1,
+ SHA1_DIGEST_LENGTH);
+ if (n == -1) {
+ err = got_error_from_errno("read");
+ break;
+ }
+ if (n < sizeof(obj->id)) {
+ err = got_error(GOT_ERR_BAD_PACKFILE);
+ break;
+ }
+ obj->crc = crc32(obj->crc, obj->delta.ref.ref_id.sha1,
+ SHA1_DIGEST_LENGTH);
+ err = got_inflate_to_mem_fd(NULL, &datalen, &obj->len,
+ &obj->crc, obj->size, pack->fd);
+ if (err)
+ break;
}
- obj->crc = crc32(obj->crc, obj->delta.ref.ref_id.sha1,
- SHA1_DIGEST_LENGTH);
- err = got_inflate_to_mem_fd(NULL, &datalen, &obj->len,
- &obj->crc, obj->size, pack->fd);
- if (err)
- break;
obj->len += SHA1_DIGEST_LENGTH;
break;
case GOT_OBJ_TYPE_OFFSET_DELTA:
if (err)
break;
- /* XXX Seek back and get the CRC of on-disk offset bytes. */
- if (lseek(pack->fd, obj->off + obj->tslen, SEEK_SET) == -1) {
- err = got_error_from_errno("lseek");
- break;
- }
- err = read_crc(&obj->crc, pack->fd,
- obj->delta.ofs.base_offsetlen);
- if (err)
- break;
+ if (pack->map) {
+ obj->crc = crc32(obj->crc, pack->map + mapoff,
+ obj->delta.ofs.base_offsetlen);
+ mapoff += obj->delta.ofs.base_offsetlen;
+ err = got_inflate_to_mem_mmap(NULL, &datalen,
+ &obj->len, &obj->crc, pack->map, mapoff,
+ pack->filesize - mapoff);
+ if (err)
+ break;
+ } else {
+ /*
+ * XXX Seek back and get the CRC of on-disk
+ * offset bytes.
+ */
+ if (lseek(pack->fd, obj->off + obj->tslen, SEEK_SET)
+ == -1) {
+ err = got_error_from_errno("lseek");
+ break;
+ }
+ err = read_crc(&obj->crc, pack->fd,
+ obj->delta.ofs.base_offsetlen);
+ if (err)
+ break;
- err = got_inflate_to_mem_fd(NULL, &datalen, &obj->len,
- &obj->crc, obj->size, pack->fd);
- if (err)
- break;
+ err = got_inflate_to_mem_fd(NULL, &datalen, &obj->len,
+ &obj->crc, obj->size, pack->fd);
+ if (err)
+ break;
+ }
obj->len += obj->delta.ofs.base_offsetlen;
break;
default:
uint8_t packidx_hash[SHA1_DIGEST_LENGTH];
ssize_t r, w;
int pass, have_ref_deltas = 0;
+ size_t mapoff = 0;
/* Check pack file header. */
- r = read(pack->fd, &hdr, sizeof(hdr));
- if (r == -1)
- return got_error_from_errno("read");
- if (r < sizeof(hdr))
- return got_error_msg(GOT_ERR_BAD_PACKFILE,
- "short packfile header");
+ if (pack->map) {
+ if (pack->filesize < sizeof(hdr))
+ return got_error_msg(GOT_ERR_BAD_PACKFILE,
+ "short packfile header");
+ memcpy(&hdr, pack->map, sizeof(hdr));
+ mapoff += sizeof(hdr);
+ } else {
+ r = read(pack->fd, &hdr, sizeof(hdr));
+ if (r == -1)
+ return got_error_from_errno("read");
+ if (r < sizeof(hdr))
+ return got_error_msg(GOT_ERR_BAD_PACKFILE,
+ "short packfile header");
+ }
if (hdr.signature != htobe32(GOT_PACKFILE_SIGNATURE))
return got_error_msg(GOT_ERR_BAD_PACKFILE,
obj->crc = crc32(0L, NULL, 0);
/* Store offset to type+size information for this object. */
- obj->off = lseek(pack->fd, 0, SEEK_CUR);
- if (obj->off == -1) {
- err = got_error_from_errno("lseek");
- goto done;
+ if (pack->map) {
+ obj->off = mapoff;
+ } else {
+ obj->off = lseek(pack->fd, 0, SEEK_CUR);
+ if (obj->off == -1) {
+ err = got_error_from_errno("lseek");
+ goto done;
+ }
}
err = read_packed_object(pack, obj);
if (err)
goto done;
- if (lseek(pack->fd, obj->off + obj->tslen + obj->len,
- SEEK_SET) == -1) {
- err = got_error_from_errno("lseek");
- goto done;
+ if (pack->map) {
+ mapoff += obj->tslen + obj->len;
+ } else {
+ if (lseek(pack->fd, obj->off + obj->tslen + obj->len,
+ SEEK_SET) == -1) {
+ err = got_error_from_errno("lseek");
+ goto done;
+ }
}
if (obj->type == GOT_OBJ_TYPE_BLOB ||
if (obj->valid)
continue;
- if (lseek(pack->fd, obj->off + obj->tslen, SEEK_SET)
+ if (pack->map == NULL &&
+ lseek(pack->fd, obj->off + obj->tslen, SEEK_SET)
== -1) {
- err = got_error_from_errno("lseek");
- goto done;
+ err = got_error_from_errno("lseek");
+ goto done;
}
err = resolve_deltified_object(pack, &packidx, obj);
goto done;
}
+#ifndef GOT_PACK_NO_MMAP
+ pack.map = mmap(NULL, pack.filesize, PROT_READ, MAP_PRIVATE,
+ pack.fd, 0);
+ if (pack.map == MAP_FAILED)
+ pack.map = NULL; /* fall back to read(2) */
+#endif
err = index_pack(&pack, idxfd, pack_hash, &ibuf);
done:
close_err = got_pack_close(&pack);