From 3afd4cbe89eb79c12465077a2f55949a800f32ae Mon Sep 17 00:00:00 2001 From: Inigo Goiri Date: Wed, 4 Mar 2020 10:13:23 -0800 Subject: [PATCH] HDFS-14977. Quota Usage and Content summary are not same in Truncate with Snapshot. Contributed by hemanthboyina. --- .../snapshot/FileWithSnapshotFeature.java | 13 +++++-- .../server/namenode/TestFileTruncate.java | 36 +++++++++++++++++++ 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/snapshot/FileWithSnapshotFeature.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/snapshot/FileWithSnapshotFeature.java index cf69962404..7fa7ce7416 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/snapshot/FileWithSnapshotFeature.java +++ b/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; +import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import org.apache.hadoop.classification.InterfaceAudience; @@ -154,9 +156,14 @@ public void updateQuotaAndCollectBlocks(INode.ReclaimContext reclaimContext, QuotaCounts oldCounts; if (removed.snapshotINode != null) { oldCounts = new QuotaCounts.Builder().build(); - BlockInfo[] blocks = file.getBlocks() == null ? new - BlockInfo[0] : file.getBlocks(); - for (BlockInfo b: blocks) { + List allBlocks = new ArrayList(); + 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(); long blockSize = b.isComplete() ? b.getNumBytes() : file .getPreferredBlockSize(); diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestFileTruncate.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestFileTruncate.java index a1197fb9f9..ed0f074286 100755 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestFileTruncate.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestFileTruncate.java @@ -1283,4 +1283,40 @@ private void truncateAndRestartDN(Path p, int dn, int newLength) 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()); + } }