Skip to content

Commit 75ddaa0

Browse files
committed
HDFS-17414. [FGL] RPCs in DatanodeProtocol support fine-grained lock (#6649)
1 parent 4a70d48 commit 75ddaa0

File tree

8 files changed

+54
-32
lines changed

8 files changed

+54
-32
lines changed

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/BlockManager.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@
9797
import org.apache.hadoop.hdfs.server.namenode.INodesInPath;
9898
import org.apache.hadoop.hdfs.server.namenode.NameNode;
9999
import org.apache.hadoop.hdfs.server.namenode.Namesystem;
100+
import org.apache.hadoop.hdfs.server.namenode.fgl.FSNamesystemLockMode;
100101
import org.apache.hadoop.hdfs.server.namenode.ha.HAContext;
101102
import org.apache.hadoop.hdfs.server.namenode.metrics.NameNodeMetrics;
102103
import org.apache.hadoop.hdfs.server.namenode.sps.StoragePolicySatisfyManager;
@@ -1900,7 +1901,7 @@ private Block getBlockOnStorage(BlockInfo storedBlock,
19001901
*/
19011902
public void findAndMarkBlockAsCorrupt(final ExtendedBlock blk,
19021903
final DatanodeInfo dn, String storageID, String reason) throws IOException {
1903-
assert namesystem.hasWriteLock();
1904+
assert namesystem.hasWriteLock(FSNamesystemLockMode.BM);
19041905
final Block reportedBlock = blk.getLocalBlock();
19051906
final BlockInfo storedBlock = getStoredBlock(reportedBlock);
19061907
if (storedBlock == null) {
@@ -2715,7 +2716,7 @@ void processPendingReconstructions() {
27152716
}
27162717

27172718
public long requestBlockReportLeaseId(DatanodeRegistration nodeReg) {
2718-
assert namesystem.hasReadLock();
2719+
assert namesystem.hasReadLock(FSNamesystemLockMode.BM);
27192720
DatanodeDescriptor node = null;
27202721
try {
27212722
node = datanodeManager.getDatanode(nodeReg);
@@ -2737,7 +2738,6 @@ public long requestBlockReportLeaseId(DatanodeRegistration nodeReg) {
27372738

27382739
public void registerDatanode(DatanodeRegistration nodeReg)
27392740
throws IOException {
2740-
assert namesystem.hasWriteLock();
27412741
datanodeManager.registerDatanode(nodeReg);
27422742
bmSafeMode.checkSafeMode();
27432743
}
@@ -3004,7 +3004,7 @@ void removeDNLeaseIfNeeded(DatanodeDescriptor node) {
30043004

30053005
public void removeBRLeaseIfNeeded(final DatanodeID nodeID,
30063006
final BlockReportContext context) throws IOException {
3007-
namesystem.writeLock();
3007+
namesystem.writeLock(FSNamesystemLockMode.BM);
30083008
DatanodeDescriptor node;
30093009
try {
30103010
node = datanodeManager.getDatanode(nodeID);
@@ -3022,7 +3022,7 @@ public void removeBRLeaseIfNeeded(final DatanodeID nodeID,
30223022
}
30233023
}
30243024
} finally {
3025-
namesystem.writeUnlock("removeBRLeaseIfNeeded");
3025+
namesystem.writeUnlock(FSNamesystemLockMode.BM, "removeBRLeaseIfNeeded");
30263026
}
30273027
}
30283028

@@ -3214,7 +3214,7 @@ public void markBlockReplicasAsCorrupt(Block oldBlock,
32143214
BlockInfo block,
32153215
long oldGenerationStamp, long oldNumBytes,
32163216
DatanodeStorageInfo[] newStorages) throws IOException {
3217-
assert namesystem.hasWriteLock();
3217+
assert namesystem.hasWriteLock(FSNamesystemLockMode.BM);
32183218
BlockToMarkCorrupt b = null;
32193219
if (block.getGenerationStamp() != oldGenerationStamp) {
32203220
b = new BlockToMarkCorrupt(oldBlock, block, oldGenerationStamp,
@@ -4433,7 +4433,7 @@ private void removeStoredBlock(DatanodeStorageInfo storageInfo, Block block,
44334433
*/
44344434
public void removeStoredBlock(BlockInfo storedBlock, DatanodeDescriptor node) {
44354435
blockLog.debug("BLOCK* removeStoredBlock: {} from {}", storedBlock, node);
4436-
assert (namesystem.hasWriteLock());
4436+
assert (namesystem.hasWriteLock(FSNamesystemLockMode.BM));
44374437
{
44384438
if (storedBlock == null || !blocksMap.removeNode(storedBlock, node)) {
44394439
blockLog.debug("BLOCK* removeStoredBlock: {} has already been removed from node {}",
@@ -4948,7 +4948,7 @@ public int getTotalBlocks() {
49484948
}
49494949

49504950
public void removeBlock(BlockInfo block) {
4951-
assert namesystem.hasWriteLock();
4951+
assert namesystem.hasWriteLock(FSNamesystemLockMode.BM);
49524952
// No need to ACK blocks that are being removed entirely
49534953
// from the namespace, since the removal of the associated
49544954
// file already removes them from the block map below.
@@ -4991,7 +4991,7 @@ public void updateLastBlock(BlockInfo lastBlock, ExtendedBlock newBlock) {
49914991
/** updates a block in needed reconstruction queue. */
49924992
private void updateNeededReconstructions(final BlockInfo block,
49934993
final int curReplicasDelta, int expectedReplicasDelta) {
4994-
namesystem.writeLock();
4994+
namesystem.writeLock(FSNamesystemLockMode.BM);
49954995
try {
49964996
if (!isPopulatingReplQueues() || !block.isComplete()) {
49974997
return;
@@ -5010,7 +5010,7 @@ private void updateNeededReconstructions(final BlockInfo block,
50105010
repl.outOfServiceReplicas(), oldExpectedReplicas);
50115011
}
50125012
} finally {
5013-
namesystem.writeUnlock("updateNeededReconstructions");
5013+
namesystem.writeUnlock(FSNamesystemLockMode.BM, "updateNeededReconstructions");
50145014
}
50155015
}
50165016

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/DatanodeManager.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
import org.apache.commons.lang3.StringUtils;
2424
import org.apache.hadoop.classification.VisibleForTesting;
25+
import org.apache.hadoop.hdfs.server.namenode.fgl.FSNamesystemLockMode;
2526
import org.apache.hadoop.util.Preconditions;
2627

2728
import org.apache.hadoop.thirdparty.com.google.common.collect.ImmutableList;
@@ -863,7 +864,7 @@ private void removeDatanode(DatanodeDescriptor nodeInfo) {
863864
*/
864865
private void removeDatanode(DatanodeDescriptor nodeInfo,
865866
boolean removeBlocksFromBlocksMap) {
866-
assert namesystem.hasWriteLock();
867+
assert namesystem.hasWriteLock(FSNamesystemLockMode.BM);
867868
heartbeatManager.removeDatanode(nodeInfo);
868869
if (removeBlocksFromBlocksMap) {
869870
blockManager.removeBlocksAssociatedTo(nodeInfo);
@@ -882,7 +883,7 @@ private void removeDatanode(DatanodeDescriptor nodeInfo,
882883
*/
883884
public void removeDatanode(final DatanodeID node)
884885
throws UnregisteredNodeException {
885-
namesystem.writeLock();
886+
namesystem.writeLock(FSNamesystemLockMode.BM);
886887
try {
887888
final DatanodeDescriptor descriptor = getDatanode(node);
888889
if (descriptor != null) {
@@ -892,7 +893,7 @@ public void removeDatanode(final DatanodeID node)
892893
+ node + " does not exist");
893894
}
894895
} finally {
895-
namesystem.writeUnlock("removeDatanode");
896+
namesystem.writeUnlock(FSNamesystemLockMode.BM, "removeDatanode");
896897
}
897898
}
898899

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/ProvidedStorageMap.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import org.apache.hadoop.hdfs.server.common.blockaliasmap.BlockAliasMap;
4646
import org.apache.hadoop.hdfs.server.common.blockaliasmap.impl.TextFileRegionAliasMap;
4747
import org.apache.hadoop.hdfs.server.common.BlockAlias;
48+
import org.apache.hadoop.hdfs.server.namenode.fgl.FSNamesystemLockMode;
4849
import org.apache.hadoop.hdfs.server.protocol.DatanodeStorage;
4950
import org.apache.hadoop.hdfs.server.protocol.DatanodeStorage.State;
5051
import org.apache.hadoop.hdfs.util.RwLock;
@@ -173,7 +174,7 @@ public LocatedBlockBuilder newLocatedBlocks(int maxValue) {
173174

174175
public void removeDatanode(DatanodeDescriptor dnToRemove) {
175176
if (providedEnabled) {
176-
assert lock.hasWriteLock() : "Not holding write lock";
177+
assert lock.hasWriteLock(FSNamesystemLockMode.BM) : "Not holding write lock";
177178
providedDescriptor.remove(dnToRemove);
178179
// if all datanodes fail, set the block report count to 0
179180
if (providedDescriptor.activeProvidedDatanodes() == 0) {

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

Lines changed: 2 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.fgl.FSNamesystemLockMode;
2021
import org.apache.hadoop.util.Preconditions;
2122
import org.apache.hadoop.HadoopIllegalArgumentException;
2223
import org.apache.hadoop.fs.XAttrSetFlag;
@@ -104,7 +105,7 @@ static boolean unprotectedRemoveBlock(
104105
*/
105106
static void persistBlocks(
106107
FSDirectory fsd, String path, INodeFile file, boolean logRetryCache) {
107-
assert fsd.getFSNamesystem().hasWriteLock();
108+
assert fsd.getFSNamesystem().hasWriteLock(FSNamesystemLockMode.FS);
108109
Preconditions.checkArgument(file.isUnderConstruction());
109110
fsd.getEditLog().logUpdateBlocks(path, file, logRetryCache);
110111
if(NameNode.stateChangeLog.isDebugEnabled()) {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1106,7 +1106,7 @@ static void unprotectedUpdateCount(INodesInPath inodesInPath,
11061106
*/
11071107
public void updateSpaceForCompleteBlock(BlockInfo completeBlk,
11081108
INodesInPath inodes) throws IOException {
1109-
assert namesystem.hasWriteLock();
1109+
assert namesystem.hasWriteLock(FSNamesystemLockMode.GLOBAL);
11101110
INodesInPath iip = inodes != null ? inodes :
11111111
INodesInPath.fromINode(namesystem.getBlockCollection(completeBlk));
11121112
INodeFile fileINode = iip.getLastINode().asFile();

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

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1900,11 +1900,11 @@ public void cpUnlock() {
19001900

19011901

19021902
NamespaceInfo getNamespaceInfo() {
1903-
readLock();
1903+
readLock(FSNamesystemLockMode.FS);
19041904
try {
19051905
return unprotectedGetNamespaceInfo();
19061906
} finally {
1907-
readUnlock("getNamespaceInfo");
1907+
readUnlock(FSNamesystemLockMode.FS, "getNamespaceInfo");
19081908
}
19091909
}
19101910

@@ -3919,7 +3919,7 @@ Lease reassignLeaseInternal(Lease lease, String newHolder, INodeFile pendingFile
39193919
void commitOrCompleteLastBlock(
39203920
final INodeFile fileINode, final INodesInPath iip,
39213921
final Block commitBlock) throws IOException {
3922-
assert hasWriteLock();
3922+
assert hasWriteLock(FSNamesystemLockMode.GLOBAL);
39233923
Preconditions.checkArgument(fileINode.isUnderConstruction());
39243924
blockManager.commitOrCompleteLastBlock(fileINode, commitBlock, iip);
39253925
}
@@ -3941,7 +3941,7 @@ void addCommittedBlocksToPending(final INodeFile pendingFile) {
39413941

39423942
void finalizeINodeFileUnderConstruction(String src, INodeFile pendingFile,
39433943
int latestSnapshot, boolean allowCommittedBlock) throws IOException {
3944-
assert hasWriteLock();
3944+
assert hasWriteLock(FSNamesystemLockMode.GLOBAL);
39453945

39463946
FileUnderConstructionFeature uc = pendingFile.getFileUnderConstructionFeature();
39473947
if (uc == null) {
@@ -4010,7 +4010,8 @@ INodeFile getBlockCollection(BlockInfo b) {
40104010

40114011
@Override
40124012
public INodeFile getBlockCollection(long id) {
4013-
assert hasReadLock() : "Accessing INode id = " + id + " without read lock";
4013+
assert hasReadLock(FSNamesystemLockMode.FS)
4014+
: "Accessing INode id = " + id + " without read lock";
40144015
INode inode = getFSDirectory().getInode(id);
40154016
return inode == null ? null : inode.asFile();
40164017
}
@@ -4028,7 +4029,7 @@ void commitBlockSynchronization(ExtendedBlock oldBlock,
40284029
+ ")");
40294030
checkOperation(OperationCategory.WRITE);
40304031
final String src;
4031-
writeLock();
4032+
writeLock(FSNamesystemLockMode.GLOBAL);
40324033
boolean copyTruncate = false;
40334034
BlockInfo truncatedBlock = null;
40344035
try {
@@ -4163,7 +4164,7 @@ void commitBlockSynchronization(ExtendedBlock oldBlock,
41634164
}
41644165
blockManager.successfulBlockRecovery(storedBlock);
41654166
} finally {
4166-
writeUnlock("commitBlockSynchronization");
4167+
writeUnlock(FSNamesystemLockMode.GLOBAL, "commitBlockSynchronization");
41674168
}
41684169
getEditLog().logSync();
41694170
if (closeFile) {
@@ -4424,11 +4425,11 @@ BatchedDirectoryListing getBatchedListing(String[] srcs, byte[] startAfter,
44244425
* @see org.apache.hadoop.hdfs.server.datanode.DataNode
44254426
*/
44264427
void registerDatanode(DatanodeRegistration nodeReg) throws IOException {
4427-
writeLock();
4428+
writeLock(FSNamesystemLockMode.BM);
44284429
try {
44294430
blockManager.registerDatanode(nodeReg);
44304431
} finally {
4431-
writeUnlock("registerDatanode");
4432+
writeUnlock(FSNamesystemLockMode.BM, "registerDatanode");
44324433
}
44334434
}
44344435

@@ -4461,7 +4462,7 @@ HeartbeatResponse handleHeartbeat(DatanodeRegistration nodeReg,
44614462
@Nonnull SlowPeerReports slowPeers,
44624463
@Nonnull SlowDiskReports slowDisks)
44634464
throws IOException {
4464-
readLock();
4465+
readLock(FSNamesystemLockMode.BM);
44654466
try {
44664467
//get datanode commands
44674468
DatanodeCommand[] cmds = blockManager.getDatanodeManager().handleHeartbeat(
@@ -4484,7 +4485,7 @@ nodeReg, reports, getBlockPoolId(), cacheCapacity, cacheUsed,
44844485
return new HeartbeatResponse(cmds, haState, rollingUpgradeInfo,
44854486
blockReportLeaseId, isSlownode);
44864487
} finally {
4487-
readUnlock("handleHeartbeat");
4488+
readUnlock(FSNamesystemLockMode.BM, "handleHeartbeat");
44884489
}
44894490
}
44904491

@@ -4546,7 +4547,7 @@ void checkAvailableResources() {
45464547
* @param file
45474548
*/
45484549
private void closeFile(String path, INodeFile file) {
4549-
assert hasWriteLock();
4550+
assert hasWriteLock(FSNamesystemLockMode.FS);
45504551
// file is closed
45514552
getEditLog().logCloseFile(path, file);
45524553
NameNode.stateChangeLog.debug("closeFile: {} with {} blocks is persisted to the file system",
@@ -5904,7 +5905,7 @@ private long nextBlockId(BlockType blockType) throws IOException {
59045905
}
59055906

59065907
boolean isFileDeleted(INodeFile file) {
5907-
assert hasReadLock();
5908+
assert hasReadLock(FSNamesystemLockMode.FS);
59085909
// Not in the inodeMap or in the snapshot but marked deleted.
59095910
if (dir.getInode(file.getId()) == null) {
59105911
return true;
@@ -5982,7 +5983,7 @@ private INodeFile checkUCBlock(ExtendedBlock block,
59825983
*/
59835984
void reportBadBlocks(LocatedBlock[] blocks) throws IOException {
59845985
checkOperation(OperationCategory.WRITE);
5985-
writeLock();
5986+
writeLock(FSNamesystemLockMode.BM);
59865987
try {
59875988
checkOperation(OperationCategory.WRITE);
59885989
for (int i = 0; i < blocks.length; i++) {
@@ -5998,7 +5999,7 @@ void reportBadBlocks(LocatedBlock[] blocks) throws IOException {
59985999
}
59996000
}
60006001
} finally {
6001-
writeUnlock("reportBadBlocks");
6002+
writeUnlock(FSNamesystemLockMode.BM, "reportBadBlocks");
60026003
}
60036004
}
60046005

hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/blockmanagement/TestBlockManager.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.apache.hadoop.fs.FileStatus;
2222
import org.apache.hadoop.fs.FileUtil;
2323
import org.apache.hadoop.hdfs.server.datanode.DataNodeFaultInjector;
24+
import org.apache.hadoop.hdfs.server.namenode.fgl.FSNamesystemLockMode;
2425
import org.apache.hadoop.thirdparty.com.google.common.base.Joiner;
2526
import org.apache.hadoop.thirdparty.com.google.common.collect.ImmutableList;
2627
import org.apache.hadoop.thirdparty.com.google.common.collect.LinkedListMultimap;
@@ -166,6 +167,10 @@ public void setupMockCluster() throws IOException {
166167
fsn = Mockito.mock(FSNamesystem.class);
167168
Mockito.doReturn(true).when(fsn).hasWriteLock();
168169
Mockito.doReturn(true).when(fsn).hasReadLock();
170+
Mockito.doReturn(true).when(fsn).hasWriteLock(FSNamesystemLockMode.GLOBAL);
171+
Mockito.doReturn(true).when(fsn).hasReadLock(FSNamesystemLockMode.GLOBAL);
172+
Mockito.doReturn(true).when(fsn).hasWriteLock(FSNamesystemLockMode.BM);
173+
Mockito.doReturn(true).when(fsn).hasReadLock(FSNamesystemLockMode.BM);
169174
Mockito.doReturn(true).when(fsn).isRunning();
170175
//Make shouldPopulaeReplQueues return true
171176
HAContext haContext = Mockito.mock(HAContext.class);

0 commit comments

Comments
 (0)