Skip to content

Commit 7c432ab

Browse files
committed
HDFS-17812. Reset curEntry when BlockIteratorImpl checks a new subdir
1 parent 648c0ef commit 7c432ab

File tree

3 files changed

+56
-1
lines changed

3 files changed

+56
-1
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ public long getGenerationStampAtblockIdSwitch() {
122122
}
123123

124124
@VisibleForTesting
125-
SequentialBlockIdGenerator getBlockIdGenerator() {
125+
public SequentialBlockIdGenerator getBlockIdGenerator() {
126126
return blockIdGenerator;
127127
}
128128

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/impl/FsVolumeImpl.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -891,6 +891,8 @@ public ExtendedBlock nextBlock() throws IOException {
891891
}
892892
}
893893
state.curFinalizedSubDir = getNextFinalizedSubDir();
894+
// Reset cursor so it doesn't carry over from last iteration
895+
state.curEntry = null;
894896
if (state.curFinalizedSubDir == null) {
895897
state.curFinalizedDir = getNextFinalizedDir();
896898
if (state.curFinalizedDir == null) {

hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/TestBlockScanner.java

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import static org.junit.Assert.assertEquals;
2828
import static org.junit.Assert.assertTrue;
2929
import static org.junit.Assert.assertFalse;
30+
import static org.junit.Assert.assertNotNull;
3031
import static org.junit.Assert.fail;
3132

3233
import java.io.Closeable;
@@ -48,6 +49,7 @@
4849
import org.apache.hadoop.hdfs.AppendTestUtil;
4950
import org.apache.hadoop.hdfs.MiniDFSNNTopology;
5051
import org.apache.hadoop.hdfs.protocol.ExtendedBlock;
52+
import org.apache.hadoop.hdfs.server.blockmanagement.SequentialBlockIdGenerator;
5153
import org.apache.hadoop.hdfs.server.datanode.FsDatasetTestUtils.MaterializedReplica;
5254
import org.apache.hadoop.hdfs.server.datanode.fsdataset.FsDatasetSpi;
5355
import org.apache.hadoop.hdfs.server.datanode.VolumeScanner.ScanResultHandler;
@@ -1119,6 +1121,57 @@ public Boolean get() {
11191121
}
11201122
}
11211123

1124+
@Test
1125+
public void testNextBlock() throws Exception {
1126+
DataNodeFaultInjector oldInjector = DataNodeFaultInjector.get();
1127+
try {
1128+
Configuration conf = new Configuration();
1129+
disableBlockScanner(conf);
1130+
1131+
// Need to manually delete block to trigger error
1132+
final DataNodeFaultInjector injector = new DataNodeFaultInjector() {
1133+
@Override
1134+
public void delayDeleteReplica() {
1135+
while (true) {
1136+
try {
1137+
Thread.sleep(1000);
1138+
} catch (InterruptedException e) {
1139+
throw new RuntimeException(e);
1140+
}
1141+
}
1142+
}
1143+
};
1144+
DataNodeFaultInjector.set(injector);
1145+
1146+
TestContext ctx = new TestContext(conf, 1);
1147+
SequentialBlockIdGenerator blockIdGenerator =
1148+
ctx.cluster.getNamesystem().getBlockManager().getBlockIdManager().getBlockIdGenerator();
1149+
1150+
// /subdir24/subdir4
1151+
blockIdGenerator.skipTo(1356375042);
1152+
ctx.createFiles(0, 1, 1);
1153+
// /subdir24/subdir29
1154+
blockIdGenerator.skipTo(1356381682);
1155+
ctx.createFiles(0, 1, 1);
1156+
1157+
FsVolumeSpi volume = ctx.volumes.get(0);
1158+
BlockIterator iter = volume.newBlockIterator(ctx.bpids[0], "test");
1159+
1160+
// Get the subdir29 block. It comes before the subdir4 block.
1161+
ExtendedBlock nextBlock = iter.nextBlock();
1162+
assertNotNull(nextBlock);
1163+
FinalizedReplica replica = (FinalizedReplica) ctx.datanode.getFSDataset()
1164+
.getReplica(ctx.cluster.getNamesystem().getBlockPoolId(), nextBlock.getBlockId());
1165+
replica.deleteBlockData();
1166+
replica.deleteMetadata();
1167+
1168+
// subdir29 has been cleaned up, nextBlock() will skip directly to subdir4
1169+
assertNotNull(iter.nextBlock());
1170+
} finally {
1171+
DataNodeFaultInjector.set(oldInjector);
1172+
}
1173+
}
1174+
11221175
private static class DelayVolumeScannerResponseToInterrupt extends
11231176
VolumeScannerCBInjector {
11241177
final private long delayAmountNS;

0 commit comments

Comments
 (0)