Skip to content

Commit 43153e8

Browse files
authored
HDFS-16428. Source path with storagePolicy cause wrong typeConsumed while rename (#3898). Contributed by lei w.
Signed-off-by: Ayush Saxena <[email protected]> Signed-off-by: He Xiaoqiao <[email protected]>
1 parent d699389 commit 43153e8

File tree

4 files changed

+59
-2
lines changed

4 files changed

+59
-2
lines changed

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,12 @@ private static void verifyQuotaForRename(FSDirectory fsd, INodesInPath src,
8181
// Assume dstParent existence check done by callers.
8282
INode dstParent = dst.getINode(-2);
8383
// Use the destination parent's storage policy for quota delta verify.
84+
final boolean isSrcSetSp = src.getLastINode().isSetStoragePolicy();
85+
final byte storagePolicyID = isSrcSetSp ?
86+
src.getLastINode().getLocalStoragePolicyID() :
87+
dstParent.getStoragePolicyID();
8488
final QuotaCounts delta = src.getLastINode()
85-
.computeQuotaUsage(bsps, dstParent.getStoragePolicyID(), false,
89+
.computeQuotaUsage(bsps, storagePolicyID, false,
8690
Snapshot.CURRENT_STATE_ID);
8791

8892
// Reduce the required quota by dst that is being removed

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1372,9 +1372,13 @@ public INodesInPath addLastINode(INodesInPath existing, INode inode,
13721372
// always verify inode name
13731373
verifyINodeName(inode.getLocalNameBytes());
13741374

1375+
final boolean isSrcSetSp = inode.isSetStoragePolicy();
1376+
final byte storagePolicyID = isSrcSetSp ?
1377+
inode.getLocalStoragePolicyID() :
1378+
parent.getStoragePolicyID();
13751379
final QuotaCounts counts = inode
13761380
.computeQuotaUsage(getBlockStoragePolicySuite(),
1377-
parent.getStoragePolicyID(), false, Snapshot.CURRENT_STATE_ID);
1381+
storagePolicyID, false, Snapshot.CURRENT_STATE_ID);
13781382
updateCount(existing, pos, counts, checkQuota);
13791383

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

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,16 @@ public boolean isFile() {
339339
return false;
340340
}
341341

342+
/**
343+
* Check if this inode itself has a storage policy set.
344+
*/
345+
public boolean isSetStoragePolicy() {
346+
if (isSymlink()) {
347+
return false;
348+
}
349+
return getLocalStoragePolicyID() != HdfsConstants.BLOCK_STORAGE_POLICY_ID_UNSPECIFIED;
350+
}
351+
342352
/** Cast this inode to an {@link INodeFile}. */
343353
public INodeFile asFile() {
344354
throw new IllegalStateException("Current inode is not a file: "

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

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import org.apache.hadoop.fs.Path;
4545
import org.apache.hadoop.fs.QuotaUsage;
4646
import org.apache.hadoop.fs.StorageType;
47+
import org.apache.hadoop.fs.permission.FsPermission;
4748
import org.apache.hadoop.hdfs.client.impl.LeaseRenewer;
4849
import org.apache.hadoop.hdfs.protocol.DSQuotaExceededException;
4950
import org.apache.hadoop.hdfs.protocol.HdfsConstants;
@@ -958,6 +959,44 @@ public void testQuotaByStorageType() throws Exception {
958959
6 * fileSpace);
959960
}
960961

962+
@Test
963+
public void testRenameInodeWithStorageType() throws IOException {
964+
final int size = 64;
965+
final short repl = 1;
966+
final Path foo = new Path("/foo");
967+
final Path bs1 = new Path(foo, "bs1");
968+
final Path wow = new Path(bs1, "wow");
969+
final Path bs2 = new Path(foo, "bs2");
970+
final Path wow2 = new Path(bs2, "wow2");
971+
final Path wow3 = new Path(bs2, "wow3");
972+
973+
dfs.mkdirs(bs1, FsPermission.getDirDefault());
974+
dfs.mkdirs(bs2, FsPermission.getDirDefault());
975+
dfs.setQuota(bs1, 1000, 434217728);
976+
dfs.setQuota(bs2, 1000, 434217728);
977+
// file wow3 without storage policy
978+
DFSTestUtil.createFile(dfs, wow3, size, repl, 0);
979+
980+
dfs.setStoragePolicy(bs2, HdfsConstants.ONESSD_STORAGE_POLICY_NAME);
981+
982+
DFSTestUtil.createFile(dfs, wow, size, repl, 0);
983+
DFSTestUtil.createFile(dfs, wow2, size, repl, 0);
984+
assertTrue("Without storage policy, typeConsumed should be 0.",
985+
dfs.getQuotaUsage(bs1).getTypeConsumed(StorageType.SSD) == 0);
986+
assertTrue("With storage policy, typeConsumed should not be 0.",
987+
dfs.getQuotaUsage(bs2).getTypeConsumed(StorageType.SSD) != 0);
988+
// wow3 without storage policy , rename will not change typeConsumed
989+
dfs.rename(wow3, bs1);
990+
assertTrue("Rename src without storagePolicy, dst typeConsumed should not be changed.",
991+
dfs.getQuotaUsage(bs2).getTypeConsumed(StorageType.SSD) == 0);
992+
993+
long srcTypeQuota = dfs.getQuotaUsage(bs2).getTypeQuota(StorageType.SSD);
994+
dfs.rename(bs2, bs1);
995+
long dstTypeQuota = dfs.getQuotaUsage(bs1).getTypeConsumed(StorageType.SSD);
996+
assertTrue("Rename with storage policy, typeConsumed should not be 0.",
997+
dstTypeQuota != srcTypeQuota);
998+
}
999+
9611000
private static void checkContentSummary(final ContentSummary expected,
9621001
final ContentSummary computed) {
9631002
assertEquals(expected.toString(), computed.toString());

0 commit comments

Comments
 (0)