Skip to content

Commit 618e009

Browse files
Sahil Takiarjojochuang
authored andcommitted
HDFS-14111. hdfsOpenFile on HDFS causes unnecessary IO from file offset 0. Contributed by Sahil Takiar.
Signed-off-by: Wei-Chiu Chuang <[email protected]>
1 parent 6192c1f commit 618e009

File tree

5 files changed

+30
-12
lines changed

5 files changed

+30
-12
lines changed

hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/CryptoInputStream.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,7 @@ public boolean hasCapability(String capability) {
740740
case StreamCapabilities.READAHEAD:
741741
case StreamCapabilities.DROPBEHIND:
742742
case StreamCapabilities.UNBUFFER:
743+
case StreamCapabilities.READBYTEBUFFER:
743744
return true;
744745
default:
745746
return false;

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ public interface StreamCapabilities {
5959
*/
6060
String UNBUFFER = "in:unbuffer";
6161

62+
/**
63+
* Stream read(ByteBuffer) capability implemented by
64+
* {@link ByteBufferReadable#read(java.nio.ByteBuffer)}.
65+
*/
66+
String READBYTEBUFFER = "in:readbytebuffer";
67+
6268
/**
6369
* Capabilities that a stream can support and be queried for.
6470
*/

hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/DFSInputStream.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1779,6 +1779,7 @@ public boolean hasCapability(String capability) {
17791779
case StreamCapabilities.READAHEAD:
17801780
case StreamCapabilities.DROPBEHIND:
17811781
case StreamCapabilities.UNBUFFER:
1782+
case StreamCapabilities.READBYTEBUFFER:
17821783
return true;
17831784
default:
17841785
return false;

hadoop-hdfs-project/hadoop-hdfs-native-client/src/main/native/libhdfs/hdfs.c

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,7 +1013,7 @@ static hdfsFile hdfsOpenFileImpl(hdfsFS fs, const char *path, int flags,
10131013
return f{is|os};
10141014
*/
10151015
int accmode = flags & O_ACCMODE;
1016-
jstring jStrBufferSize = NULL, jStrReplication = NULL;
1016+
jstring jStrBufferSize = NULL, jStrReplication = NULL, jCapabilityString = NULL;
10171017
jobject jConfiguration = NULL, jPath = NULL, jFile = NULL;
10181018
jobject jFS = (jobject)fs;
10191019
jthrowable jthr;
@@ -1171,16 +1171,22 @@ static hdfsFile hdfsOpenFileImpl(hdfsFS fs, const char *path, int flags,
11711171
file->flags = 0;
11721172

11731173
if ((flags & O_WRONLY) == 0) {
1174-
// Try a test read to see if we can do direct reads
1175-
char buf;
1176-
if (readDirect(fs, file, &buf, 0) == 0) {
1177-
// Success - 0-byte read should return 0
1174+
// Check the StreamCapabilities of jFile to see if we can do direct reads
1175+
jthr = newJavaStr(env, "in:readbytebuffer", &jCapabilityString);
1176+
if (jthr) {
1177+
ret = printExceptionAndFree(env, jthr, PRINT_EXC_ALL,
1178+
"hdfsOpenFile(%s): newJavaStr", path);
1179+
goto done;
1180+
}
1181+
jthr = invokeMethod(env, &jVal, INSTANCE, jFile, HADOOP_ISTRM,
1182+
"hasCapability", "(Ljava/lang/String;)Z", jCapabilityString);
1183+
if (jthr) {
1184+
ret = printExceptionAndFree(env, jthr, PRINT_EXC_ALL,
1185+
"hdfsOpenFile(%s): FSDataInputStream#hasCapability", path);
1186+
goto done;
1187+
}
1188+
if (jVal.z) {
11781189
file->flags |= HDFS_FILE_SUPPORTS_DIRECT_READ;
1179-
} else if (errno != ENOTSUP) {
1180-
// Unexpected error. Clear it, don't set the direct flag.
1181-
fprintf(stderr,
1182-
"hdfsOpenFile(%s): WARN: Unexpected error %d when testing "
1183-
"for direct read compatibility\n", path, errno);
11841190
}
11851191
}
11861192
ret = 0;
@@ -1190,7 +1196,8 @@ static hdfsFile hdfsOpenFileImpl(hdfsFS fs, const char *path, int flags,
11901196
destroyLocalReference(env, jStrReplication);
11911197
destroyLocalReference(env, jConfiguration);
11921198
destroyLocalReference(env, jPath);
1193-
destroyLocalReference(env, jFile);
1199+
destroyLocalReference(env, jFile);
1200+
destroyLocalReference(env, jCapabilityString);
11941201
if (ret) {
11951202
if (file) {
11961203
if (file->file) {

hadoop-hdfs-project/hadoop-hdfs-native-client/src/main/native/libhdfspp/tests/hdfs_ext_test.cc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,10 @@ TEST_F(HdfsExtTest, TestReadStats) {
503503
hdfsFileFreeReadStatistics(stats);
504504

505505
EXPECT_EQ(0, hdfsCloseFile(fs, file));
506-
EXPECT_EQ(0, errno);
506+
// Since libhdfs is not guaranteed to set errno to 0 on successful
507+
// operations, we disable this check for now, see HDFS-14325 for a
508+
// long term solution to this problem
509+
// EXPECT_EQ(0, errno);
507510
}
508511

509512
//Testing working directory

0 commit comments

Comments
 (0)