Skip to content

Commit

Permalink
HDFS-16428. Source path setted storagePolicy will cause wrong typeCon…
Browse files Browse the repository at this point in the history
…sumed in rename operation
  • Loading branch information
wanglei authored and wanglei committed Jan 20, 2022
1 parent d886282 commit 93d18d5
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,12 @@ private static void verifyQuotaForRename(FSDirectory fsd, INodesInPath src,
// Assume dstParent existence check done by callers.
INode dstParent = dst.getINode(-2);
// Use the destination parent's storage policy for quota delta verify.
final boolean isSrcSetSp = src.getLastINode().isSetStoragePolicy();
final byte storagePolicyID = isSrcSetSp ?
src.getLastINode().getLocalStoragePolicyID() :
dstParent.getStoragePolicyID();
final QuotaCounts delta = src.getLastINode()
.computeQuotaUsage(bsps, dstParent.getStoragePolicyID(), false,
.computeQuotaUsage(bsps, storagePolicyID, false,
Snapshot.CURRENT_STATE_ID);

// Reduce the required quota by dst that is being removed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1372,9 +1372,13 @@ public INodesInPath addLastINode(INodesInPath existing, INode inode,
// always verify inode name
verifyINodeName(inode.getLocalNameBytes());

final boolean isSrcSetSp = inode.isSetStoragePolicy();
final byte storagePolicyID = isSrcSetSp ?
inode.getLocalStoragePolicyID() :
parent.getStoragePolicyID();
final QuotaCounts counts = inode
.computeQuotaUsage(getBlockStoragePolicySuite(),
parent.getStoragePolicyID(), false, Snapshot.CURRENT_STATE_ID);
storagePolicyID, false, Snapshot.CURRENT_STATE_ID);
updateCount(existing, pos, counts, checkQuota);

boolean isRename = (inode.getParent() != null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,16 @@ public boolean isFile() {
return false;
}

/**
* Check whether this inode itself set storage policy
*/
public boolean isSetStoragePolicy() {
if (isSymlink()) {
return false;
}
return getLocalStoragePolicyID() != HdfsConstants.BLOCK_STORAGE_POLICY_ID_UNSPECIFIED;
}

/** Cast this inode to an {@link INodeFile}. */
public INodeFile asFile() {
throw new IllegalStateException("Current inode is not a file: "
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.QuotaUsage;
import org.apache.hadoop.fs.StorageType;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.hdfs.client.impl.LeaseRenewer;
import org.apache.hadoop.hdfs.protocol.DSQuotaExceededException;
import org.apache.hadoop.hdfs.protocol.HdfsConstants;
Expand Down Expand Up @@ -958,6 +959,44 @@ public void testQuotaByStorageType() throws Exception {
6 * fileSpace);
}

@Test
public void testRenameInodeWithStorageType() throws IOException {
final int size = 64;
final short repl = 1;
final Path foo = new Path("/foo");
final Path bs1 = new Path(foo, "bs1");
final Path wow = new Path(bs1, "wow");
final Path bs2 = new Path(foo, "bs2");
final Path wow2 = new Path(bs2, "wow2");
final Path wow3 = new Path(bs2, "wow3");

dfs.mkdirs(bs1, FsPermission.getDirDefault());
dfs.mkdirs(bs2, FsPermission.getDirDefault());
dfs.setQuota(bs1, 1000, 434217728);
dfs.setQuota(bs2, 1000, 434217728);
// file wow3 without storage policy
DFSTestUtil.createFile(dfs, wow3, size, repl, 0);

dfs.setStoragePolicy(bs2, HdfsConstants.ONESSD_STORAGE_POLICY_NAME);

DFSTestUtil.createFile(dfs, wow, size, repl, 0);
DFSTestUtil.createFile(dfs, wow2, size, repl, 0);
assertTrue("Without storage policy, typeConsumed should be 0.",
dfs.getQuotaUsage(bs1).getTypeConsumed(StorageType.SSD) == 0);
assertTrue("With storage policy, typeConsumed should not be 0.",
dfs.getQuotaUsage(bs2).getTypeConsumed(StorageType.SSD) != 0);
// wow3 without storage policy , rename will not change typeConsumed
dfs.rename(wow3, bs1);
assertTrue("Rename src without storagePolicy, dst typeConsumed should not be changed.",
dfs.getQuotaUsage(bs2).getTypeConsumed(StorageType.SSD) == 0);

long srcTypeQuota = dfs.getQuotaUsage(bs2).getTypeQuota(StorageType.SSD);
dfs.rename(bs2, bs1);
long dstTypeQuota = dfs.getQuotaUsage(bs1).getTypeConsumed(StorageType.SSD);
assertTrue("Rename with storage policy, typeConsumed should not be 0.",
dstTypeQuota != srcTypeQuota);
}

private static void checkContentSummary(final ContentSummary expected,
final ContentSummary computed) {
assertEquals(expected.toString(), computed.toString());
Expand Down

0 comments on commit 93d18d5

Please sign in to comment.