Skip to content

Commit 2d98fd7

Browse files
committed
HADOOP-18662. ListFiles with recursive fails with FNF.
1 parent aff840c commit 2d98fd7

File tree

2 files changed

+37
-2
lines changed

2 files changed

+37
-2
lines changed

hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileSystem.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2413,8 +2413,13 @@ private void handleFileStat(LocatedFileStatus stat) throws IOException {
24132413
if (stat.isFile()) { // file
24142414
curFile = stat;
24152415
} else if (recursive) { // directory
2416-
itors.push(curItor);
2417-
curItor = listLocatedStatus(stat.getPath());
2416+
try {
2417+
RemoteIterator<LocatedFileStatus> newDirItor = listLocatedStatus(stat.getPath());
2418+
itors.push(curItor);
2419+
curItor = newDirItor;
2420+
} catch (FileNotFoundException ignored) {
2421+
LOGGER.debug("Directory {} deleted while attempting to recusive listing", stat.getPath());
2422+
}
24182423
}
24192424
}
24202425

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import static org.mockito.ArgumentMatchers.eq;
3232
import static org.mockito.Mockito.inOrder;
3333
import static org.mockito.Mockito.mock;
34+
import static org.mockito.Mockito.spy;
3435

3536
import java.io.File;
3637
import java.io.FileNotFoundException;
@@ -123,9 +124,11 @@
123124
import org.apache.hadoop.util.DataChecksum;
124125
import org.apache.hadoop.util.Time;
125126
import org.apache.hadoop.util.concurrent.HadoopExecutors;
127+
import org.apache.hadoop.util.functional.RemoteIterators;
126128
import org.junit.Assert;
127129
import org.junit.Test;
128130
import org.mockito.InOrder;
131+
import org.mockito.Mockito;
129132
import org.slf4j.Logger;
130133
import org.slf4j.LoggerFactory;
131134
import org.slf4j.event.Level;
@@ -1557,6 +1560,33 @@ public void testListFiles() throws IOException {
15571560
}
15581561
}
15591562

1563+
@Test
1564+
public void testListFilesRecursive() throws IOException {
1565+
Configuration conf = getTestConfiguration();
1566+
1567+
try (MiniDFSCluster cluster = new MiniDFSCluster.Builder(conf).build();) {
1568+
DistributedFileSystem fs = cluster.getFileSystem();
1569+
1570+
// Create some directories and files.
1571+
Path dir = new Path("/dir");
1572+
Path subDir1 = fs.makeQualified(new Path(dir, "subDir1"));
1573+
Path subDir2 = fs.makeQualified(new Path(dir, "subDir2"));
1574+
1575+
fs.mkdirs(subDir1);
1576+
fs.mkdirs(subDir2);
1577+
fs.create(new Path(dir, "foo1")).close();
1578+
fs.create(new Path(dir, "foo2")).close();
1579+
fs.create(new Path(subDir1, "foo3")).close();
1580+
fs.create(new Path(subDir2, "foo4")).close();
1581+
1582+
// Mock the filesystem, and throw FNF when listing is triggered for the subdirectory.
1583+
FileSystem mockFs = spy(fs);
1584+
Mockito.doThrow(new FileNotFoundException("")).when(mockFs).listLocatedStatus(eq(subDir1));
1585+
List<LocatedFileStatus> str = RemoteIterators.toList(mockFs.listFiles(dir, true));
1586+
Assert.assertEquals(str.toString(), 3, str.size());
1587+
}
1588+
}
1589+
15601590
@Test
15611591
public void testListStatusOfSnapshotDirs() throws IOException {
15621592
MiniDFSCluster cluster = new MiniDFSCluster.Builder(getTestConfiguration())

0 commit comments

Comments
 (0)