Ver código fonte

HDFS-7677. DistributedFileSystem#truncate should resolve symlinks. (yliu)

yliu 10 anos atrás
pai
commit
d483ba25d7

+ 2 - 0
hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt

@@ -514,6 +514,8 @@ Release 2.7.0 - UNRELEASED
     HDFS-7566. Remove obsolete entries from hdfs-default.xml (Ray Chiang
     via aw)
 
+    HDFS-7677. DistributedFileSystem#truncate should resolve symlinks. (yliu)
+
 Release 2.6.1 - UNRELEASED
 
   INCOMPATIBLE CHANGES

+ 13 - 1
hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DistributedFileSystem.java

@@ -630,7 +630,19 @@ public class DistributedFileSystem extends FileSystem {
   @Override
   public boolean truncate(Path f, final long newLength) throws IOException {
     statistics.incrementWriteOps(1);
-    return dfs.truncate(getPathName(f), newLength);
+    Path absF = fixRelativePart(f);
+    return new FileSystemLinkResolver<Boolean>() {
+      @Override
+      public Boolean doCall(final Path p)
+          throws IOException, UnresolvedLinkException {
+        return dfs.truncate(getPathName(p), newLength);
+      }
+      @Override
+      public Boolean next(final FileSystem fs, final Path p)
+          throws IOException {
+        return fs.truncate(p, newLength);
+      }
+    }.resolve(this, absF);
   }
 
   @Override

+ 30 - 0
hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestFileTruncate.java

@@ -759,6 +759,36 @@ public class TestFileTruncate {
     }
   }
 
+  @Test
+  public void testTruncate4Symlink() throws IOException {
+    final int fileLength = 3 * BLOCK_SIZE;
+
+    final Path parent = new Path("/test");
+    fs.mkdirs(parent);
+    final byte[] contents = AppendTestUtil.initBuffer(fileLength);
+    final Path file = new Path(parent, "testTruncate4Symlink");
+    writeContents(contents, fileLength, file);
+
+    final Path link = new Path(parent, "link");
+    fs.createSymlink(file, link, false);
+
+    final int newLength = fileLength/3;
+    boolean isReady = fs.truncate(link, newLength);
+
+    assertTrue("Recovery is not expected.", isReady);
+
+    FileStatus fileStatus = fs.getFileStatus(file);
+    assertThat(fileStatus.getLen(), is((long) newLength));
+
+    ContentSummary cs = fs.getContentSummary(parent);
+    assertEquals("Bad disk space usage",
+        cs.getSpaceConsumed(), newLength * REPLICATION);
+    // validate the file content
+    checkFullFile(file, newLength, contents);
+
+    fs.delete(parent, true);
+  }
+
   static void writeContents(byte[] contents, int fileLength, Path p)
       throws IOException {
     FSDataOutputStream out = fs.create(p, true, BLOCK_SIZE, REPLICATION,