]> source.dussan.org Git - jgit.git/commit
Ensure that GC#deleteOrphans respects pack lock 29/172829/8
authorMatthias Sohn <matthias.sohn@sap.com>
Wed, 25 Nov 2020 16:00:09 +0000 (17:00 +0100)
committerMatthias Sohn <matthias.sohn@sap.com>
Thu, 26 Nov 2020 00:17:47 +0000 (01:17 +0100)
commitfde7a271a4f961484ae6e8357fd64277cfc03585
tree43d95cd3b85b41f59352571fffeec2d814745454
parent256bc64f2a77997d3abacdece7148d65fbd5c4e7
Ensure that GC#deleteOrphans respects pack lock

If pack or index files are guarded by a pack lock (.keep file)
deleteOrphans() should not touch the respective files protected by the
lock file. Otherwise it may interfere with PackInserter concurrently
inserting a new pack file and its index.

The problem was caused by the following race.

All mentioned files are located in  "objects/pack/".
File endings relevant in "pack" dir:
  .pack
  .keep
  .idx
  .bitmap

When ReceivePack receives a pack file it executes the following steps:

ReceivePack.service():
  receivePackAndCheckConnectivity():
    receivePack():
      receive the pack
      parse the pack, returns packLock (.keep file)
      PackInserter.flush():
        write tmpPck file:  "insert_<random>.pack"
        write tmpIdx file:  "insert_<random>.idx"
        real pack name: "pack-<SHA1>.pack"
        real index name: "pack-<SHA1>.idx"
        atomic rename tmpPack to realPack
        atomic rename tmpIdx to tmpIdx
  execute commands
  unlock pack by removing .keep file
  trigger auto gc if enabled

When PackInserter.flush() renames the temporary pack to the final
"pack-xxx.pack" file  the temporary pack index file "insert_xxx.idx"
has no matching .pack file with the same base name for a short interval.
If deleteOrphans() ran during that interval it deduced the pack index
file was orphaned. Subsequently the missing pack index caused
MissingObjectExceptions since objects contained in the pack couldn't be
looked up anymore.

Bug: https://bugs.chromium.org/p/gerrit/issues/detail?id=13544
Change-Id: I559c81e4b1d7c487f92a751bd78b987d32c98719
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcOrphanFilesTest.java
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java