]> source.dussan.org Git - jgit.git/commitdiff
LockFile: Retry lock creation if parent dirs were removed 25/1199825/2
authorKaushik Lingarkar <quic_kaushikl@quicinc.com>
Tue, 20 Aug 2024 22:50:20 +0000 (15:50 -0700)
committerKaushik Lingarkar <quic_kaushikl@quicinc.com>
Wed, 21 Aug 2024 20:04:04 +0000 (20:04 +0000)
In the small window between creation of the lock file's parent dirs and
the lock file itself, the parent dirs may be cleaned by an external
process packing refs in the repository. When this scenario occurs, retry
creating the lock file (along with its parent dirs).

Change-Id: Id7ec60c3f7f373b59f1dc8de6b8fa6df6bdf2570
Signed-off-by: Kaushik Lingarkar <quic_kaushikl@quicinc.com>
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LockFile.java

index a2d8bd01405aa3d31dc79aaa6deab7ffb04c2afd..1983541e4aa9d4d571b7b33ada5743440b696760 100644 (file)
@@ -24,6 +24,7 @@ import java.nio.ByteBuffer;
 import java.nio.channels.Channels;
 import java.nio.channels.FileChannel;
 import java.nio.file.Files;
+import java.nio.file.NoSuchFileException;
 import java.nio.file.StandardCopyOption;
 import java.nio.file.attribute.FileTime;
 import java.text.MessageFormat;
@@ -141,9 +142,8 @@ public class LockFile {
                        throw new IllegalStateException(
                                        MessageFormat.format(JGitText.get().lockAlreadyHeld, ref));
                }
-               FileUtils.mkdirs(lck.getParentFile(), true);
                try {
-                       token = FS.DETECTED.createNewFileAtomic(lck);
+                       token = createLockFileWithRetry();
                } catch (IOException e) {
                        LOG.error(JGitText.get().failedCreateLockFile, lck, e);
                        throw e;
@@ -160,6 +160,19 @@ public class LockFile {
                return obtainedLock;
        }
 
+       private FS.LockToken createLockFileWithRetry() throws IOException {
+               try {
+                       return createLockFile();
+               } catch (NoSuchFileException e) {
+                       return createLockFile();
+               }
+       }
+
+       private FS.LockToken createLockFile() throws IOException {
+               FileUtils.mkdirs(lck.getParentFile(), true);
+               return FS.DETECTED.createNewFileAtomic(lck);
+       }
+
        /**
         * Try to establish the lock for appending.
         *