瀏覽代碼

HDFS-14977. Quota Usage and Content summary are not same in Truncate with Snapshot. Contributed by hemanthboyina.

Inigo Goiri 5 年之前
父節點
當前提交
3afd4cbe89

+ 10 - 3
hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/snapshot/FileWithSnapshotFeature.java

@@ -17,6 +17,8 @@
  */
  */
 package org.apache.hadoop.hdfs.server.namenode.snapshot;
 package org.apache.hadoop.hdfs.server.namenode.snapshot;
 
 
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.List;
 
 
 import org.apache.hadoop.classification.InterfaceAudience;
 import org.apache.hadoop.classification.InterfaceAudience;
@@ -154,9 +156,14 @@ public class FileWithSnapshotFeature implements INode.Feature {
     QuotaCounts oldCounts;
     QuotaCounts oldCounts;
     if (removed.snapshotINode != null) {
     if (removed.snapshotINode != null) {
       oldCounts = new QuotaCounts.Builder().build();
       oldCounts = new QuotaCounts.Builder().build();
-      BlockInfo[] blocks = file.getBlocks() == null ? new
-          BlockInfo[0] : file.getBlocks();
-      for (BlockInfo b: blocks) {
+      List<BlockInfo> allBlocks = new ArrayList<BlockInfo>();
+      if (file.getBlocks() != null) {
+        allBlocks.addAll(Arrays.asList(file.getBlocks()));
+      }
+      if (removed.getBlocks() != null) {
+        allBlocks.addAll(Arrays.asList(removed.getBlocks()));
+      }
+      for (BlockInfo b: allBlocks) {
         short replication = b.getReplication();
         short replication = b.getReplication();
         long blockSize = b.isComplete() ? b.getNumBytes() : file
         long blockSize = b.isComplete() ? b.getNumBytes() : file
             .getPreferredBlockSize();
             .getPreferredBlockSize();

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

@@ -1283,4 +1283,40 @@ public class TestFileTruncate {
       cluster.waitActive();
       cluster.waitActive();
     }
     }
   }
   }
+
+  /**
+   * QuotaUsage in Truncate with Snapshot.
+   */
+  @Test
+  public void testQuotaOnTruncateWithSnapshot() throws Exception {
+    Path root = new Path("/");
+    Path dirPath = new Path(root, "dir");
+    assertTrue(fs.mkdirs(dirPath));
+    Path filePath = new Path(dirPath, "file");
+    DFSTestUtil.createFile(fs, filePath, 10, (short) 3, 0);
+
+    // verify quotausage and content summary after creating snapshot
+    fs.allowSnapshot(dirPath);
+    fs.createSnapshot(dirPath, "s1");
+    assertEquals(fs.getContentSummary(root).getSpaceConsumed(),
+        fs.getQuotaUsage(root).getSpaceConsumed());
+
+    // truncating the file size to 5bytes
+    boolean blockrecovery = fs.truncate(filePath, 5);
+    if (!blockrecovery) {
+      checkBlockRecovery(filePath, fs, 300, 100L);
+    }
+
+    // verify quotausage and content summary after truncating file which exists
+    // in snapshot
+    assertEquals(fs.getContentSummary(root).getSpaceConsumed(),
+        fs.getQuotaUsage(root).getSpaceConsumed());
+
+    // verify quotausage and content summary after deleting snapshot
+    // now the quota of the file shouldn't present in quotausage and content
+    // summary
+    fs.deleteSnapshot(dirPath, "s1");
+    assertEquals(fs.getContentSummary(root).getSpaceConsumed(),
+        fs.getQuotaUsage(root).getSpaceConsumed());
+  }
 }
 }