Skip to content

Commit 3c11716

Browse files
committed
HDFS-14633. The StorageType quota and consume in QuotaFeature is not handled for rename. Contributed by Jinglun.
1 parent 91b01a1 commit 3c11716

File tree

3 files changed

+59
-2
lines changed

3 files changed

+59
-2
lines changed

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirRenameOp.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,12 @@ private static void verifyQuotaForRename(FSDirectory fsd, INodesInPath src,
7676
while(src.getINode(i) == dst.getINode(i)) { i++; }
7777
// src[i - 1] is the last common ancestor.
7878
BlockStoragePolicySuite bsps = fsd.getBlockStoragePolicySuite();
79-
final QuotaCounts delta = src.getLastINode().computeQuotaUsage(bsps);
79+
// Assume dstParent existence check done by callers.
80+
INode dstParent = dst.getINode(-2);
81+
// Use the destination parent's storage policy for quota delta verify.
82+
final QuotaCounts delta = src.getLastINode()
83+
.computeQuotaUsage(bsps, dstParent.getStoragePolicyID(), false,
84+
Snapshot.CURRENT_STATE_ID);
8085

8186
// Reduce the required quota by dst that is being removed
8287
final INode dstINode = dst.getLastINode();

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirectory.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
*/
1818
package org.apache.hadoop.hdfs.server.namenode;
1919

20+
import org.apache.hadoop.hdfs.server.namenode.snapshot.Snapshot;
2021
import org.apache.hadoop.util.StringUtils;
2122

2223
import com.google.common.annotations.VisibleForTesting;
@@ -1296,7 +1297,9 @@ public INodesInPath addLastINode(INodesInPath existing, INode inode,
12961297
// always verify inode name
12971298
verifyINodeName(inode.getLocalNameBytes());
12981299

1299-
final QuotaCounts counts = inode.computeQuotaUsage(getBlockStoragePolicySuite());
1300+
final QuotaCounts counts = inode
1301+
.computeQuotaUsage(getBlockStoragePolicySuite(),
1302+
parent.getStoragePolicyID(), false, Snapshot.CURRENT_STATE_ID);
13001303
updateCount(existing, pos, counts, checkQuota);
13011304

13021305
boolean isRename = (inode.getParent() != null);

hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestQuota.java

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1578,6 +1578,44 @@ public void testClrQuotaOnRoot() throws Exception {
15781578
assertEquals(orignalQuota, dfs.getQuotaUsage(new Path("/")).getQuota());
15791579
}
15801580

1581+
@Test
1582+
public void testRename() throws Exception {
1583+
int fileLen = 1024;
1584+
short replication = 3;
1585+
1586+
final Path parent = new Path(PathUtils.getTestDir(getClass()).getPath(),
1587+
GenericTestUtils.getMethodName());
1588+
assertTrue(dfs.mkdirs(parent));
1589+
1590+
final Path srcDir = new Path(parent, "src-dir");
1591+
Path file = new Path(srcDir, "file1");
1592+
DFSTestUtil.createFile(dfs, file, fileLen, replication, 0);
1593+
dfs.setStoragePolicy(srcDir, HdfsConstants.HOT_STORAGE_POLICY_NAME);
1594+
1595+
final Path dstDir = new Path(parent, "dst-dir");
1596+
assertTrue(dfs.mkdirs(dstDir));
1597+
dfs.setStoragePolicy(dstDir, HdfsConstants.ALLSSD_STORAGE_POLICY_NAME);
1598+
1599+
dfs.setQuota(srcDir, 100000, 100000);
1600+
dfs.setQuota(dstDir, 100000, 100000);
1601+
1602+
Path dstFile = new Path(dstDir, "file1");
1603+
// Test quota check of rename. Expect a QuotaExceedException.
1604+
dfs.setQuotaByStorageType(dstDir, StorageType.SSD, 10);
1605+
try {
1606+
dfs.rename(file, dstFile);
1607+
fail("Expect QuotaExceedException.");
1608+
} catch (QuotaExceededException qe) {
1609+
}
1610+
1611+
// Set enough quota, expect a successful rename.
1612+
dfs.setQuotaByStorageType(dstDir, StorageType.SSD, fileLen * replication);
1613+
dfs.rename(file, dstFile);
1614+
// Verify the storage type usage is properly updated on source and dst.
1615+
checkQuotaAndCount(dfs, srcDir);
1616+
checkQuotaAndCount(dfs, dstDir);
1617+
}
1618+
15811619
@Test
15821620
public void testSpaceQuotaExceptionOnAppend() throws Exception {
15831621
GenericTestUtils.setLogLevel(DFSOutputStream.LOG, Level.TRACE);
@@ -1648,4 +1686,15 @@ private static void scanIntoList(
16481686
}
16491687
scanner.close();
16501688
}
1689+
1690+
// quota and count should match.
1691+
private void checkQuotaAndCount(DistributedFileSystem fs, Path path)
1692+
throws IOException {
1693+
QuotaUsage qu = fs.getQuotaUsage(path);
1694+
ContentSummary cs = fs.getContentSummary(path);
1695+
for (StorageType st : StorageType.values()) {
1696+
// it will fail here, because the quota and consume is not handled right.
1697+
assertEquals(qu.getTypeConsumed(st), cs.getTypeConsumed(st));
1698+
}
1699+
}
16511700
}

0 commit comments

Comments
 (0)