summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Martín Nieto <cmn@dwim.me>2015-06-02 10:25:22 +0200
committerCarlos Martín Nieto <cmn@dwim.me>2015-06-02 10:25:22 +0200
commitaa57231fca5897c0779d5bcfc5d9183b454792eb (patch)
tree001c1d8043545ae44d5b67742775ccd21573c955
parentbe5fda75879f7ed89c7a72adc257872d1ea13803 (diff)
downloadlibgit2-cmn/idx-fill-hole.tar.gz
indexer: use lseek to extend the packfilecmn/idx-fill-hole
We've been using `p_ftruncate()` to extend the packfile in order to mmap it and write the new data into it. This works well in the general case, but as truncation does not allocate space in the filesystem, it must do so when we write data to it. The only way the OS has to indicate a failure to allocate space is via SIGBUS which means we tried to write outside the file. This will cause everyone to crash as they don't expect to handle this signal. Switch to using `p_lseek()` and `p_write()` to extend the file in a way which tells the filesystem to allocate the space for the missing data. We can then be sure that we have space to write into.
-rw-r--r--src/indexer.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/src/indexer.c b/src/indexer.c
index e39345c71..1890b0063 100644
--- a/src/indexer.c
+++ b/src/indexer.c
@@ -478,13 +478,14 @@ static int write_at(git_indexer *idx, const void *data, git_off_t offset, size_t
static int append_to_pack(git_indexer *idx, const void *data, size_t size)
{
git_off_t current_size = idx->pack->mwf.size;
+ int fd = idx->pack->mwf.fd;
if (!size)
return 0;
- /* add the extra space we need at the end */
- if (p_ftruncate(idx->pack->mwf.fd, current_size + size) < 0) {
- giterr_set(GITERR_OS, "Failed to increase size of pack file '%s'", idx->pack->pack_name);
+ if (p_lseek(fd, current_size + size - 1, SEEK_SET) < 0 ||
+ p_write(idx->pack->mwf.fd, data, 1) < 0) {
+ giterr_set(GITERR_OS, "cannot extend packfile '%s'", idx->pack->pack_name);
return -1;
}