aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit/src/org
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.jgit/src/org')
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java33
1 files changed, 24 insertions, 9 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java
index 716711e067..588855b1f8 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java
@@ -48,7 +48,8 @@ import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.nio.charset.Charset;
-import java.nio.file.AccessDeniedException;
+import java.nio.file.FileStore;
+import java.nio.file.FileSystemException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -57,9 +58,11 @@ import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
import org.eclipse.jgit.annotations.Nullable;
import org.eclipse.jgit.api.errors.JGitInternalException;
@@ -84,7 +87,7 @@ public class FS_POSIX extends FS {
private static final int DEFAULT_UMASK = 0022;
private volatile int umask = -1;
- private volatile boolean supportsUnixNLink = true;
+ private static final Map<FileStore, Boolean> CAN_HARD_LINK = new ConcurrentHashMap<>();
private volatile AtomicFileCreation supportsAtomicCreateNewFile = AtomicFileCreation.UNDEFINED;
@@ -388,12 +391,18 @@ public class FS_POSIX extends FS {
if (!lock.createNewFile()) {
return false;
}
- if (supportsAtomicCreateNewFile() || !supportsUnixNLink) {
+ if (supportsAtomicCreateNewFile()) {
return true;
}
Path lockPath = lock.toPath();
Path link = null;
+ FileStore store = Files.getFileStore(lockPath);
try {
+ Boolean canLink = CAN_HARD_LINK.computeIfAbsent(store,
+ s -> Boolean.TRUE);
+ if (canLink == Boolean.FALSE) {
+ return true;
+ }
link = Files.createLink(
Paths.get(lock.getAbsolutePath() + ".lnk"), //$NON-NLS-1$
lockPath);
@@ -405,11 +414,11 @@ public class FS_POSIX extends FS {
nlink));
return false;
} else if (nlink < 2) {
- supportsUnixNLink = false;
+ CAN_HARD_LINK.put(store, Boolean.FALSE);
}
return true;
} catch (UnsupportedOperationException | IllegalArgumentException e) {
- supportsUnixNLink = false;
+ CAN_HARD_LINK.put(store, Boolean.FALSE);
return true;
} finally {
if (link != null) {
@@ -448,12 +457,18 @@ public class FS_POSIX extends FS {
if (!file.createNewFile()) {
return token(false, null);
}
- if (supportsAtomicCreateNewFile() || !supportsUnixNLink) {
+ if (supportsAtomicCreateNewFile()) {
return token(true, null);
}
Path link = null;
Path path = file.toPath();
+ FileStore store = Files.getFileStore(path);
try {
+ Boolean canLink = CAN_HARD_LINK.computeIfAbsent(store,
+ s -> Boolean.TRUE);
+ if (canLink == Boolean.FALSE) {
+ return token(true, null);
+ }
link = Files.createLink(Paths.get(uniqueLinkPath(file)), path);
Integer nlink = (Integer) (Files.getAttribute(path,
"unix:nlink")); //$NON-NLS-1$
@@ -462,12 +477,12 @@ public class FS_POSIX extends FS {
JGitText.get().failedAtomicFileCreation, path, nlink));
return token(false, link);
} else if (nlink.intValue() < 2) {
- supportsUnixNLink = false;
+ CAN_HARD_LINK.put(store, Boolean.FALSE);
}
return token(true, link);
} catch (UnsupportedOperationException | IllegalArgumentException
- | AccessDeniedException | SecurityException e) {
- supportsUnixNLink = false;
+ | FileSystemException | SecurityException e) {
+ CAN_HARD_LINK.put(store, Boolean.FALSE);
return token(true, link);
}
}