From 10b1d7340b7567849605e283585d6a292a53b127 Mon Sep 17 00:00:00 2001 From: zhangshuyan <81411509+zhangshuyan0@users.noreply.github.com> Date: Wed, 16 Aug 2023 20:29:19 +0800 Subject: [PATCH] HDFS-17154. EC: Fix bug in updateBlockForPipeline after failover. (#5941). Contributed by Shuyan Zhang. Reviewed-by: Haiyang Hu Signed-off-by: He Xiaoqiao --- .../hdfs/protocol/LocatedStripedBlock.java | 6 ++++- .../hdfs/server/namenode/FSNamesystem.java | 23 +++++++++++++++++-- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/protocol/LocatedStripedBlock.java b/hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/protocol/LocatedStripedBlock.java index ad67e64fb6..a683a2b53e 100644 --- a/hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/protocol/LocatedStripedBlock.java +++ b/hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/protocol/LocatedStripedBlock.java @@ -36,7 +36,7 @@ public class LocatedStripedBlock extends LocatedBlock { private static final byte[] EMPTY_INDICES = {}; private static final Token EMPTY_TOKEN = new Token<>(); - private final byte[] blockIndices; + private byte[] blockIndices; private Token[] blockTokens; @SuppressWarnings({"unchecked"}) @@ -72,6 +72,10 @@ public byte[] getBlockIndices() { return this.blockIndices; } + public void setBlockIndices(byte[] blockIndices) { + this.blockIndices = blockIndices; + } + @Override public boolean isStriped() { return true; diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java index b41120aebf..e08002a8dd 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java @@ -102,6 +102,7 @@ import org.apache.hadoop.hdfs.protocol.ECTopologyVerifierResult; import org.apache.hadoop.hdfs.protocol.HdfsConstants; import org.apache.hadoop.hdfs.protocol.HdfsLocatedFileStatus; +import org.apache.hadoop.hdfs.protocol.LocatedStripedBlock; import org.apache.hadoop.hdfs.protocol.SnapshotStatus; import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_STORAGE_POLICY_ENABLED_KEY; import static org.apache.hadoop.hdfs.server.namenode.FSDirStatAndListingOp.*; @@ -5966,8 +5967,26 @@ LocatedBlock bumpBlockGenerationStamp(ExtendedBlock block, block.setGenerationStamp(nextGenerationStamp( blockManager.isLegacyBlock(block.getLocalBlock()))); - locatedBlock = BlockManager.newLocatedBlock( - block, file.getLastBlock(), null, -1); + BlockInfo lastBlockInfo = file.getLastBlock(); + locatedBlock = BlockManager.newLocatedBlock(block, lastBlockInfo, + null, -1); + if (lastBlockInfo.isStriped() && + ((BlockInfoStriped) lastBlockInfo).getTotalBlockNum() > + ((LocatedStripedBlock) locatedBlock).getBlockIndices().length) { + // The location info in BlockUnderConstructionFeature may not be + // complete after a failover, so we just return all block tokens for a + // striped block. This will disrupt the correspondence between + // LocatedStripedBlock.blockIndices and LocatedStripedBlock.locs, + // which is not used in client side. The correspondence between + // LocatedStripedBlock.blockIndices and LocatedBlock.blockToken is + // ensured. + byte[] indices = + new byte[((BlockInfoStriped) lastBlockInfo).getTotalBlockNum()]; + for (int i = 0; i < indices.length; ++i) { + indices[i] = (byte) i; + } + ((LocatedStripedBlock) locatedBlock).setBlockIndices(indices); + } blockManager.setBlockToken(locatedBlock, BlockTokenIdentifier.AccessMode.WRITE); } finally {