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;
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;
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;
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);
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) {
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$
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);
}
}