diff --git a/reftable/blocksource.c b/reftable/blocksource.c index 573c81287f..7f7441f751 100644 --- a/reftable/blocksource.c +++ b/reftable/blocksource.c @@ -93,13 +93,12 @@ void block_source_from_buf(struct reftable_block_source *bs, } struct file_block_source { - uint64_t size; - unsigned char *data; + struct reftable_mmap mmap; }; static uint64_t file_size(void *b) { - return ((struct file_block_source *)b)->size; + return ((struct file_block_source *)b)->mmap.size; } static void file_release_data(void *b REFTABLE_UNUSED, struct reftable_block_data *dest REFTABLE_UNUSED) @@ -109,7 +108,7 @@ static void file_release_data(void *b REFTABLE_UNUSED, struct reftable_block_dat static void file_close(void *v) { struct file_block_source *b = v; - munmap(b->data, b->size); + reftable_munmap(&b->mmap); reftable_free(b); } @@ -117,8 +116,8 @@ static ssize_t file_read_data(void *v, struct reftable_block_data *dest, uint64_ uint32_t size) { struct file_block_source *b = v; - assert(off + size <= b->size); - dest->data = b->data + off; + assert(off + size <= b->mmap.size); + dest->data = (unsigned char *) b->mmap.data + off; dest->len = size; return size; } @@ -156,13 +155,9 @@ int reftable_block_source_from_file(struct reftable_block_source *bs, goto out; } - p->size = st.st_size; - p->data = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); - if (p->data == MAP_FAILED) { - err = REFTABLE_IO_ERROR; - p->data = NULL; + err = reftable_mmap(&p->mmap, fd, st.st_size); + if (err < 0) goto out; - } assert(!bs->ops); bs->ops = &file_vtable; diff --git a/reftable/system.c b/reftable/system.c index cd76e56be8..9063641f30 100644 --- a/reftable/system.c +++ b/reftable/system.c @@ -143,3 +143,23 @@ uint64_t reftable_time_ms(void) { return getnanotime() / 1000000; } + +int reftable_mmap(struct reftable_mmap *out, int fd, size_t len) +{ + void *data = xmmap_gently(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0); + if (data == MAP_FAILED) + return REFTABLE_IO_ERROR; + + out->data = data; + out->size = len; + + return 0; +} + +int reftable_munmap(struct reftable_mmap *mmap) +{ + if (munmap(mmap->data, mmap->size) < 0) + return REFTABLE_IO_ERROR; + memset(mmap, 0, sizeof(*mmap)); + return 0; +} diff --git a/reftable/system.h b/reftable/system.h index 071bfa3d58..c0e2cbe0ff 100644 --- a/reftable/system.h +++ b/reftable/system.h @@ -114,4 +114,22 @@ int flock_commit(struct reftable_flock *l); /* Report the time in milliseconds. */ uint64_t reftable_time_ms(void); +struct reftable_mmap { + void *data; + size_t size; + void *priv; +}; + +/* + * Map the file into memory. Returns 0 on success, a reftable error code on + * error. + */ +int reftable_mmap(struct reftable_mmap *out, int fd, size_t len); + +/* + * Unmap the file from memory. Returns 0 on success, a reftable error code on + * error. + */ +int reftable_munmap(struct reftable_mmap *mmap); + #endif