@ -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
| AccessDenied Exception | SecurityException e ) {
supportsUnixNLink = false ;
| FileSystem Exception | SecurityException e ) {
CAN_HARD_LINK . put ( store , Boolean . FALSE ) ;
return token ( true , link ) ;
}
}