summaryrefslogtreecommitdiff
path: root/src/pack.c
Commit message (Collapse)AuthorAgeFilesLines
* pack: continue zlib while we can make progressethomson/zlibEdward Thomson2020-12-151-4/+9
| | | | | Continue the zlib stream as long as we can make progress; stop when we stop getting output _or_ when zlib stops taking input from us.
* threads: rename git_atomic to git_atomic32Edward Thomson2020-12-061-6/+6
| | | | | Clarify the `git_atomic` type and functions now that we have a 64 bit version as well (`git_atomic64`).
* Make the pack and mwindow implementations data-race-freelhchavez2020-11-281-76/+165
| | | | | | | | | | | | | | | | | | | | | | | | | This change fixes a packfile heap corruption that can happen when interacting with multiple packfiles concurrently across multiple threads. This is exacerbated by setting a lower mwindow open file limit. This change: * Renames most of the internal methods in pack.c to clearly indicate that they expect to be called with a certain lock held, making reasoning about the state of locks a bit easier. * Splits the `git_pack_file` lock in two: the one in `git_pack_file` only protects the `index_map`. The protection to `git_mwindow_file` is now in that struct. * Explicitly checks for freshness of the `git_pack_file` in `git_packfile_unpack_header`: this allows the mwindow implementation to close files whenever there is enough cache pressure, and `git_packfile_unpack_header` will reopen the packfile if needed. * After a call to `p_munmap()`, the `data` and `len` fields are poisoned with `NULL` to make use-after-frees more evident and crash rather than being open to the possibility of heap corruption. * Adds a test case to prevent this from regressing in the future. Fixes: #5591
* Make the odb race-freelhchavez2020-11-281-40/+74
| | | | | | | This change adds all the necessary locking to the odb to avoid races in the backends. Part of: #5592
* midx: Support multi-pack-index files in odb_pack.clhchavez2020-11-271-0/+6
| | | | | | | | | | | | This change adds support for reading multi-pack-index files from the packfile odb backend. This also makes git_pack_file objects open their backing failes lazily in more scenarios, since the multi-pack-index can avoid having to open them in some cases (yay!). This change also refreshes the documentation found in src/odb_pack.c to match the updated code. Part of: #5399
* pack: use GIT_ASSERTEdward Thomson2020-11-271-10/+11
|
* multipack: Introduce a parser for multi-pack-index fileslhchavez2020-10-051-5/+5
| | | | | | | This change is the first in a series to add support for git's multi-pack-index. This should speed up large repositories significantly. Part of: #5399
* pack: check pack_window_open returnEdward Thomson2020-08-051-1/+4
|
* zstream: handle Z_BUF_ERROR appropriately in get_output_chunkEdward Thomson2020-08-051-1/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Our processing loop in git_zstream_get_output_chunk does not handle `Z_BUF_ERROR` appropriately at the end of a compressed window. From the zlib manual, inflate will return: > Z_BUF_ERROR if no progress was possible or if there was not enough > room in the output buffer when Z_FINISH is used. Note that Z_BUF_ERROR > is not fatal, and inflate() can be called again with more input and > more output space to continue decompressing. In our loop, we were waiting until we got the expected size, then ensuring that we were at `Z_STREAM_END`. We are not guaranteed to be, since zlib may be in the `Z_BUF_ERROR` state where it has consumed a full window's worth of data, but it doesn't know that it's really at the end of the stream. There _could_ be more compressed data, but it doesn't _know_ that there's not until we make a subsequent call. We can change the loop to look for the end of stream instead of our expected size. This allows us to call inflate one last time when we are at the end of a window (and in the `Z_BUF_ERROR` state), allowing it to recognize the end of the stream, and move from the `Z_BUF_ERROR` state to the `Z_STREAM_END` state. If we do this, we need another exit condition: when `bytes == 0`, then no progress could be made and we should stop trying to inflate. This will be an error case, caught by the size and/or end-of-stream test.
* Re-adding the "delta offset is zero" error caselhchavez2020-04-021-0/+6
|
* Making get_delta_base() conform to the general error-handling patternlhchavez2020-04-011-20/+19
| | | | | This makes get_delta_base() return the error code as the return value and the delta base as an out-parameter.
* pack: Improve error handling for get_delta_base()lhchavez2020-04-011-7/+15
| | | | | | | | This change moves the responsibility of setting the error upon failures of get_delta_base() to get_delta_base() instead of its callers. That way, the caller chan always check if the return value is negative and mark the whole operation as an error instead of using garbage values, which can lead to crashes if the .pack files are malformed.
* sha1_lookup: inline its only function into "pack.c"Patrick Steinhardt2020-02-071-1/+21
| | | | | | | The file "sha1_lookup.c" contains a single function `sha1_position` only which is used only in the packfile implementation. As the function is comparatively small, to enable the compiler to optimize better and to remove symbol visibility, move it into "pack.c".
* pack: refactor streams to use `git_zstream`Patrick Steinhardt2020-01-091-43/+16
| | | | | | While we do have a `git_zstream` abstraction that encapsulates all the calls to zlib as well as its error handling, we do not use it in our pack file code. Refactor it to make the code a lot easier to understand.
* pack: refactor unpacking of raw objects to use `git_zstream`Patrick Steinhardt2020-01-091-41/+38
| | | | | | While we do have a zstream abstraction that encapsulates all the calls to zlib as well as its error handling, we do not use it in our pack file code. Refactor it to make the code a lot easier to understand.
* internal: use off64_t instead of git_off_tethomson/off_tEdward Thomson2019-11-251-27/+27
| | | | Prefer `off64_t` internally.
* fileops: rename to "futils.h" to match function signaturesPatrick Steinhardt2019-07-201-1/+1
| | | | | | | | | Our file utils functions all have a "futils" prefix, e.g. `git_futils_touch`. One would thus naturally guess that their definitions and implementation would live in files "futils.h" and "futils.c", respectively, but in fact they live in "fileops.h". Rename the files to match expectations.
* offmap: introduce high-level setter for key/value pairsPatrick Steinhardt2019-02-151-5/+2
| | | | | | | | | | | | Currently, there is only one caller that adds entries into an offset map, and this caller first uses `git_offmap_put` to add a key and then set the value at the returned index by using `git_offmap_set_value_at`. This is just too tighlty coupled with implementation details of the map as it exposes the index of inserted entries, which we really do not care about at all. Introduce a new function `git_offmap_set`, which takes as parameters the map, key and value and directly returns an error code. Convert the caller to make use of it instead.
* offmap: introduce high-level getter for valuesPatrick Steinhardt2019-02-151-5/+2
| | | | | | | | | | | | | | The current way of looking up an entry from a map is tightly coupled with the map implementation, as one first has to look up the index of the key and then retrieve the associated value by using the index. As a caller, you usually do not care about any indices at all, though, so this is more complicated than really necessary. Furthermore, it invites for errors to happen if the correct error checking sequence is not being followed. Introduce a new high-level function `git_offmap_get` that takes a map and a key and returns a pointer to the associated value if such a key exists. Otherwise, a `NULL` pointer is returned. Adjust all callers that can trivially be converted.
* oidmap: introduce high-level getter for valuesPatrick Steinhardt2019-02-151-4/+3
| | | | | | | | | | | | | | The current way of looking up an entry from a map is tightly coupled with the map implementation, as one first has to look up the index of the key and then retrieve the associated value by using the index. As a caller, you usually do not care about any indices at all, though, so this is more complicated than really necessary. Furthermore, it invites for errors to happen if the correct error checking sequence is not being followed. Introduce a new high-level function `git_oidmap_get` that takes a map and a key and returns a pointer to the associated value if such a key exists. Otherwise, a `NULL` pointer is returned. Adjust all callers that can trivially be converted.
* maps: use uniform lifecycle management functionsPatrick Steinhardt2019-02-151-2/+2
| | | | | | | | | | | | | | | | Currently, the lifecycle functions for maps (allocation, deallocation, resize) are not named in a uniform way and do not have a uniform function signature. Rename the functions to fix that, and stick to libgit2's naming scheme of saying `git_foo_new`. This results in the following new interface for allocation: - `int git_<t>map_new(git_<t>map **out)` to allocate a new map, returning an error code if we ran out of memory - `void git_<t>map_free(git_<t>map *map)` to free a map - `void git_<t>map_clear(git<t>map *map)` to remove all entries from a map This commit also fixes all existing callers.
* Allow bypassing check '.keep' files using libgit2 option ↵Dhruva Krishnamurthy2019-02-021-3/+8
| | | | 'GIT_OPT_IGNORE_PACK_KEEP_FILE_CHECK'
* git_error: use new names in internal APIs and usageEdward Thomson2019-01-221-24/+24
| | | | | Move to the `git_error` name in the internal API for error-related functions.
* object_type: GIT_OBJECT_BAD is now GIT_OBJECT_INVALIDEdward Thomson2019-01-171-2/+2
| | | | | | | We use the term "invalid" to refer to bad or malformed data, eg `GIT_REF_INVALID` and `GIT_EINVALIDSPEC`. Since we're changing the names of the `git_object_t`s in this release, update it to be `GIT_OBJECT_INVALID` instead of `BAD`.
* object_type: use new enumeration namesethomson/index_fixesEdward Thomson2018-12-011-26/+26
| | | | Use the new object_type enumeration names within the codebase.
* khash: remove intricate knowledge of khash typesPatrick Steinhardt2018-11-281-3/+3
| | | | | | | Instead of using the `khiter_t`, `git_strmap_iter` and `khint_t` types, simply use `size_t` instead. This decouples code from the khash stuff and makes it possible to move the khash includes into the implementation files.
* Convert usage of `git_buf_free` to new `git_buf_dispose`Patrick Steinhardt2018-06-101-3/+3
|
* pack: rename `git_packfile_stream_free`Patrick Steinhardt2018-06-101-2/+2
| | | | | | | | | | | | The function `git_packfile_stream_free` frees all state of the packfile stream without freeing the structure itself. This naming makes it hard to spot whether it will try to free the pointer itself or not, causing potential future errors. Due to this reason, we have decided to name a function freeing state without freeing the actual struture a "dispose" function. Rename `git_packfile_stream_free` to `git_packfile_stream_dispose` as a first example following this rule.
* Fix unpack double freelhchavez2017-12-231-1/+4
| | | | | | | | | | | If an element has been cached, but then the call to packfile_unpack_compressed() fails, the very next thing that happens is that its data is freed and then the element is not removed from the cache, which frees the data again. This change sets obj->data to NULL to avoid the double-free. It also stops trying to resolve deltas after two continuous failed rounds of resolution, and adds a test for this.
* Simplified overflow conditionlhchavez2017-12-151-3/+1
|
* Using unsigned insteadlhchavez2017-12-091-6/+8
|
* libFuzzer: Prevent a potential shift overflowlhchavez2017-12-081-1/+1
| | | | | | | | | The type of |base_offset| in get_delta_base() is `git_off_t`, which is a signed `long`. That means that we need to make sure that the 8 most significant bits are zero (instead of 7) to avoid an overflow when it is shifted by 7 bits. Found using libFuzzer.
* Merge pull request #4288 from pks-t/pks/include-fixupsEdward Thomson2017-08-151-2/+2
|\ | | | | Include fixups
| * Make sure to always include "common.h" firstPatrick Steinhardt2017-07-031-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Next to including several files, our "common.h" header also declares various macros which are then used throughout the project. As such, we have to make sure to always include this file first in all implementation files. Otherwise, we might encounter problems or even silent behavioural differences due to macros or defines not being defined as they should be. So in fact, our header and implementation files should make sure to always include "common.h" first. This commit does so by establishing a common include pattern. Header files inside of "src" will now always include "common.h" as its first other file, separated by a newline from all the other includes to make it stand out as special. There are two cases for the implementation files. If they do have a matching header file, they will always include this one first, leading to "common.h" being transitively included as first file. If they do not have a matching header file, they instead include "common.h" as first file themselves. This fixes the outlined problems and will become our standard practice for header and source files inside of the "src/" from now on.
* | sha1_lookup: drop sha1_entry_pos functionpeff/drop-sha1-entry-posJeff King2017-08-091-4/+0
|/ | | | | | | | | | | | | This was pulled over from git.git, and is an experiment in making binary-searching lists of sha1s faster. It was never compiled by default (nor was it used upstream by default without a special environment variable). Unfortunately, it is actually slower in practice, and upstream is planning to drop it in git/git@f1068efefe6dd3beaa89484db5e2db730b094e0b (which has some timing results). It's worth doing the same here for simplicity.
* buffer: use `git_buf_init` with lengthPatrick Steinhardt2017-06-081-2/+5
| | | | | | | | The `git_buf_init` function has an optional length parameter, which will cause the buffer to be initialized and allocated in one step. This can be used instead of static initialization with `GIT_BUF_INIT` followed by a `git_buf_grow`. This patch does so for two functions where it is applicable.
* buffer: rely on `GITERR_OOM` set by `git_buf_try_grow`Patrick Steinhardt2017-06-081-1/+0
| | | | | | | | The function `git_buf_try_grow` consistently calls `giterr_set_oom` whenever growing the buffer fails due to insufficient memory being available. So in fact, we do not have to do this ourselves when a call to any buffer-growing function has failed due to an OOM situation. But we still do so in two functions, which this patch cleans up.
* pack: fix looping over cache entriesJason Haslam2017-02-221-3/+3
| | | | | | Fixes a regression from #4092. This is a crash on 32-bit and I assume that it doesn't do the right thing on 64-bit either. MSVC emits a warning for this, but of course, it's easy to get lost among all of the similar 'possible loss of data' warnings.
* offmap: remove GIT__USE_OFFMAP macroPatrick Steinhardt2017-02-171-2/+0
|
* oidmap: remove GIT__USE_OIDMAP macroPatrick Steinhardt2017-02-171-1/+0
|
* khash: avoid using `kh_key`/`kh_val` as lvaluePatrick Steinhardt2017-02-171-1/+1
|
* khash: avoid using `kh_put` directlyPatrick Steinhardt2017-02-171-1/+1
|
* khash: avoid using `kh_del` directlyPatrick Steinhardt2017-02-171-1/+1
|
* khash: avoid using `kh_val`/`kh_value` directlyPatrick Steinhardt2017-02-171-3/+3
|
* khash: avoid using `kh_get` directlyPatrick Steinhardt2017-02-171-2/+2
|
* khash: avoid using `kh_end` directlyPatrick Steinhardt2017-02-171-2/+2
|
* khash: use `git_map_exists` where applicablePatrick Steinhardt2017-02-171-1/+1
|
* khash: avoid using `kh_foreach`/`kh_foreach_value` directlyPatrick Steinhardt2017-02-171-12/+6
|
* indexer: introduce `git_packfile_close`Edward Thomson2017-01-211-4/+13
| | | | Encapsulation!
* giterr_set: consistent error messagesEdward Thomson2016-12-291-6/+6
| | | | | | | | Error messages should be sentence fragments, and therefore: 1. Should not begin with a capital letter, 2. Should not conclude with punctuation, and 3. Should not end a sentence and begin a new one