diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/HardLink.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/HardLink.java index 1624c5d395aec..29e9e8aa17b77 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/HardLink.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/HardLink.java @@ -23,6 +23,8 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.StringReader; +import java.nio.file.FileStore; +import java.nio.file.Files; import org.apache.hadoop.io.IOUtils; import org.apache.hadoop.util.Shell; @@ -50,6 +52,10 @@ public class HardLink { private static HardLinkCommandGetter getHardLinkCommand; public final LinkStats linkStats; //not static + + private static final String FileAttributeView = "unix"; + + private static final String FileAttribute = "unix:nlink"; //initialize the command "getters" statically, so can use their //methods without instantiating the HardLink object @@ -203,6 +209,15 @@ public static void createHardLinkMult(File parentDir, String[] fileBaseNames, parentDir.toPath().resolve(name)); } } + @VisibleForTesting + static boolean supportsHardLink(File f) { + try { + FileStore store = Files.getFileStore(f.toPath()); + return store.supportsFileAttributeView(FileAttributeView); + } catch (IOException e) { + return false; + } + } /** * Retrieves the number of links to the specified file. @@ -220,6 +235,10 @@ public static int getLinkCount(File fileName) throws IOException { throw new FileNotFoundException(fileName + " not found."); } + if (supportsHardLink(fileName)) { + return (int) Files.getAttribute(fileName.toPath(), FileAttribute); + } + // construct and execute shell command String[] cmd = getHardLinkCommand.linkCount(fileName); String inpMsg = null; diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestHardLink.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestHardLink.java index b08e15ca11090..b66825f7b10a7 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestHardLink.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestHardLink.java @@ -22,6 +22,8 @@ import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; +import java.nio.file.FileStore; +import java.nio.file.Files; import java.util.Arrays; import org.apache.hadoop.test.GenericTestUtils; @@ -204,6 +206,8 @@ private String fetchFileContents(File file) char[] result = Arrays.copyOf(buf, cnt); return new String(result); } + + /** * Sanity check the simplest case of HardLink.getLinkCount() @@ -219,6 +223,16 @@ public void testGetLinkCount() throws IOException { assertEquals(1, getLinkCount(x3)); } + @Test + public void testGetLinkCountFromFileAttribute() throws IOException { + assertTrue(supportsHardLink(x1)); + assertEquals(1, getLinkCount(x1)); + assertTrue(supportsHardLink(x2)); + assertEquals(1, getLinkCount(x2)); + assertTrue(supportsHardLink(x3)); + assertEquals(1, getLinkCount(x3)); + } + /** * Test the single-file method HardLink.createHardLink(). * Also tests getLinkCount() with values greater than one.