Skip to content

Commit b673546

Browse files
authored
Merge pull request libgit2#6039 from lhchavez/avoid-mmap-in-git-indexer-append
indexer: Avoid one `mmap(2)`/`munmap(2)` pair per `git_indexer_append` call
2 parents 4f24a93 + c65eb24 commit b673546

File tree

1 file changed

+37
-3
lines changed

1 file changed

+37
-3
lines changed

src/indexer.c

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -601,9 +601,10 @@ static void hash_partially(git_indexer *idx, const uint8_t *data, size_t size)
601601
idx->inbuf_len += size - to_expell;
602602
}
603603

604+
#if defined(NO_MMAP) || !defined(GIT_WIN32)
605+
604606
static int write_at(git_indexer *idx, const void *data, off64_t offset, size_t size)
605607
{
606-
#ifdef NO_MMAP
607608
size_t remaining_size = size;
608609
const char *ptr = (const char *)data;
609610

@@ -619,7 +620,31 @@ static int write_at(git_indexer *idx, const void *data, off64_t offset, size_t s
619620
offset += nb;
620621
remaining_size -= nb;
621622
}
623+
624+
return 0;
625+
}
626+
627+
static int append_to_pack(git_indexer *idx, const void *data, size_t size)
628+
{
629+
if (write_at(idx, data, idx->pack->mwf.size, size) < 0) {
630+
git_error_set(GIT_ERROR_OS, "cannot extend packfile '%s'", idx->pack->pack_name);
631+
return -1;
632+
}
633+
634+
return 0;
635+
}
636+
622637
#else
638+
639+
/*
640+
* Windows may keep different views to a networked file for the mmap- and
641+
* open-accessed versions of a file, so any writes done through
642+
* `write(2)`/`pwrite(2)` may not be reflected on the data that `mmap(2)` is
643+
* able to read.
644+
*/
645+
646+
static int write_at(git_indexer *idx, const void *data, off64_t offset, size_t size)
647+
{
623648
git_file fd = idx->pack->mwf.fd;
624649
size_t mmap_alignment;
625650
size_t page_offset;
@@ -644,7 +669,6 @@ static int write_at(git_indexer *idx, const void *data, off64_t offset, size_t s
644669
map_data = (unsigned char *)map.data;
645670
memcpy(map_data + page_offset, data, size);
646671
p_munmap(&map);
647-
#endif
648672

649673
return 0;
650674
}
@@ -680,6 +704,8 @@ static int append_to_pack(git_indexer *idx, const void *data, size_t size)
680704
return write_at(idx, data, idx->pack->mwf.size, size);
681705
}
682706

707+
#endif
708+
683709
static int read_stream_object(git_indexer *idx, git_indexer_progress *stats)
684710
{
685711
git_packfile_stream *stream = &idx->stream;
@@ -1279,11 +1305,19 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats)
12791305
if (git_mwindow_free_all(&idx->pack->mwf) < 0)
12801306
goto on_error;
12811307

1282-
/* Truncate file to undo rounding up to next page_size in append_to_pack */
1308+
#if !defined(NO_MMAP) && defined(GIT_WIN32)
1309+
/*
1310+
* Some non-Windows remote filesystems fail when truncating files if the
1311+
* file permissions change after opening the file (done by p_mkstemp).
1312+
*
1313+
* Truncation is only needed when mmap is used to undo rounding up to next
1314+
* page_size in append_to_pack.
1315+
*/
12831316
if (p_ftruncate(idx->pack->mwf.fd, idx->pack->mwf.size) < 0) {
12841317
git_error_set(GIT_ERROR_OS, "failed to truncate pack file '%s'", idx->pack->pack_name);
12851318
return -1;
12861319
}
1320+
#endif
12871321

12881322
if (idx->do_fsync && p_fsync(idx->pack->mwf.fd) < 0) {
12891323
git_error_set(GIT_ERROR_OS, "failed to fsync packfile");

0 commit comments

Comments
 (0)