-
Bug
-
Resolution: Fixed
-
P4
-
1.4.2, 5.0
-
b07
-
x86, sparc
-
linux, solaris_7, solaris_9
-
Not verified
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-2178802 | 6u18 | Alan Bateman | P4 | Resolved | Fixed | b01 |
FULL PRODUCT VERSION :
java version "1.5.0_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_01-b08)
Java HotSpot(TM) Client VM (build 1.5.0_01-b08, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Linux SageTVMediaCenter 2.6.11 #4 Thu Mar 17 00:22:15 GMT 2005 i686 VIA Nehemiah CentaurHauls GNU/Linux
A DESCRIPTION OF THE PROBLEM :
When using java.nio.channels.FileChannel.transferTo(long offset, long length, WritableByteChannel ch) with an offset greater than 2^32 the data that's actually transferred is not the correct data. It ends up doing a modulus with 2^32 and only transferring data from within the first 2GB of the file.
This happens because in the JNI code for this on Linux it's using the sendfile() Linux API call. This call is not compliant with 64-bit offsets.
From FileChannelImpl.c:
JNIEXPORT jlong JNICALL
Java_sun_nio_ch_FileChannelImpl_transferTo0(JNIEnv *env, jobject this,
jint srcFD,
jlong position, jlong count,
jint dstFD)
{
#ifdef __linux__
off_t offset = (off_t)position;
jlong n = sendfile(dstFD, srcFD, &offset, (size_t)count);
if (n < 0) {
jlong max = (jlong)java_lang_Integer_MAX_VALUE;
if (count > max) {
n = sendfile(dstFD, srcFD, &offset, (size_t)max);
if (n >= 0) {
return n;
}
}
if ((errno == EINVAL) && ((ssize_t)count >= 0))
return IOS_UNSUPPORTED_CASE;
JNU_ThrowIOExceptionWithLastError(env, "Transfer failed");
}
return n;
#endif
...
REPRODUCIBILITY :
This bug can be reproduced always.
CUSTOMER SUBMITTED WORKAROUND :
Don't use transferTo when transferring data that lies beyond the 2GB boundary.
###@###.### 2005-04-11 10:25:03 GMT
java version "1.5.0_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_01-b08)
Java HotSpot(TM) Client VM (build 1.5.0_01-b08, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Linux SageTVMediaCenter 2.6.11 #4 Thu Mar 17 00:22:15 GMT 2005 i686 VIA Nehemiah CentaurHauls GNU/Linux
A DESCRIPTION OF THE PROBLEM :
When using java.nio.channels.FileChannel.transferTo(long offset, long length, WritableByteChannel ch) with an offset greater than 2^32 the data that's actually transferred is not the correct data. It ends up doing a modulus with 2^32 and only transferring data from within the first 2GB of the file.
This happens because in the JNI code for this on Linux it's using the sendfile() Linux API call. This call is not compliant with 64-bit offsets.
From FileChannelImpl.c:
JNIEXPORT jlong JNICALL
Java_sun_nio_ch_FileChannelImpl_transferTo0(JNIEnv *env, jobject this,
jint srcFD,
jlong position, jlong count,
jint dstFD)
{
#ifdef __linux__
off_t offset = (off_t)position;
jlong n = sendfile(dstFD, srcFD, &offset, (size_t)count);
if (n < 0) {
jlong max = (jlong)java_lang_Integer_MAX_VALUE;
if (count > max) {
n = sendfile(dstFD, srcFD, &offset, (size_t)max);
if (n >= 0) {
return n;
}
}
if ((errno == EINVAL) && ((ssize_t)count >= 0))
return IOS_UNSUPPORTED_CASE;
JNU_ThrowIOExceptionWithLastError(env, "Transfer failed");
}
return n;
#endif
...
REPRODUCIBILITY :
This bug can be reproduced always.
CUSTOMER SUBMITTED WORKAROUND :
Don't use transferTo when transferring data that lies beyond the 2GB boundary.
###@###.### 2005-04-11 10:25:03 GMT
- backported by
-
JDK-2178802 (fc) FileChannel.transferTo on Linux fails when going beyond 2GB boundary
-
- Resolved
-
- duplicates
-
JDK-4770025 (fc) FileChannel.transferTo() for files greater than 2^31-1 bytes (lnx)
-
- Closed
-
-
JDK-4963924 java.nio sendfile needs to handle large offsets on Linux
-
- Closed
-