Skip to content

Commit 806d84b

Browse files
HADOOP-17105. S3AFS - Do not attempt to resolve symlinks in globStatus (#2113)
Contributed by Jimmy Zuber.
1 parent b9fa5e0 commit 806d84b

File tree

2 files changed

+50
-4
lines changed

2 files changed

+50
-4
lines changed

hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/S3AFileSystem.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3980,6 +3980,8 @@ public boolean isMagicCommitPath(Path path) {
39803980

39813981
/**
39823982
* Increments the statistic {@link Statistic#INVOCATION_GLOB_STATUS}.
3983+
* Override superclass so as to disable symlink resolution as symlinks
3984+
* are not supported by S3A.
39833985
* {@inheritDoc}
39843986
*/
39853987
@Override
@@ -3988,9 +3990,9 @@ public FileStatus[] globStatus(Path pathPattern) throws IOException {
39883990
}
39893991

39903992
/**
3991-
* Override superclass so as to disable symlink resolution and so avoid
3992-
* some calls to the FS which may have problems when the store is being
3993-
* inconsistent.
3993+
* Increments the statistic {@link Statistic#INVOCATION_GLOB_STATUS}.
3994+
* Override superclass so as to disable symlink resolution as symlinks
3995+
* are not supported by S3A.
39943996
* {@inheritDoc}
39953997
*/
39963998
@Override
@@ -4002,7 +4004,7 @@ public FileStatus[] globStatus(
40024004
return Globber.createGlobber(this)
40034005
.withPathPattern(pathPattern)
40044006
.withPathFiltern(filter)
4005-
.withResolveSymlinks(true)
4007+
.withResolveSymlinks(false)
40064008
.build()
40074009
.glob();
40084010
}

hadoop-tools/hadoop-aws/src/test/java/org/apache/hadoop/fs/s3a/ITestS3AFileOperationCost.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,4 +574,48 @@ public void testCreateCost() throws Throwable {
574574
}
575575

576576
}
577+
578+
@Test
579+
public void testCostOfGlobStatus() throws Throwable {
580+
describe("Test globStatus has expected cost");
581+
S3AFileSystem fs = getFileSystem();
582+
assume("Unguarded FS only", !fs.hasMetadataStore());
583+
584+
Path basePath = path("testCostOfGlobStatus/nextFolder/");
585+
586+
// create a bunch of files
587+
int filesToCreate = 10;
588+
for (int i = 0; i < filesToCreate; i++) {
589+
try (FSDataOutputStream out = fs.create(basePath.suffix("/" + i))) {
590+
verifyOperationCount(1, 1);
591+
}
592+
}
593+
594+
fs.globStatus(basePath.suffix("/*"));
595+
// 2 head + 1 list from getFileStatus on path,
596+
// plus 1 list to match the glob pattern
597+
verifyOperationCount(2, 2);
598+
}
599+
600+
@Test
601+
public void testCostOfGlobStatusNoSymlinkResolution() throws Throwable {
602+
describe("Test globStatus does not attempt to resolve symlinks");
603+
S3AFileSystem fs = getFileSystem();
604+
assume("Unguarded FS only", !fs.hasMetadataStore());
605+
606+
Path basePath = path("testCostOfGlobStatusNoSymlinkResolution/f/");
607+
608+
// create a single file, globStatus returning a single file on a pattern
609+
// triggers attempts at symlinks resolution if configured
610+
String fileName = "/notASymlinkDOntResolveMeLikeOne";
611+
try (FSDataOutputStream out = fs.create(basePath.suffix(fileName))) {
612+
verifyOperationCount(1, 1);
613+
}
614+
615+
fs.globStatus(basePath.suffix("/*"));
616+
// unguarded: 2 head + 1 list from getFileStatus on path,
617+
// plus 1 list to match the glob pattern
618+
// no additional operations from symlink resolution
619+
verifyOperationCount(2, 2);
620+
}
577621
}

0 commit comments

Comments
 (0)