Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-2188715 | 6-pool | Vikram Aroskar | P3 | Closed | Won't Fix | |
JDK-2188253 | 6u21 | Alan Bateman | P4 | Resolved | Fixed | b01 |
FULL PRODUCT VERSION :
java version "1.6.0_12"
Java(TM) SE Runtime Environment (build 1.6.0_12-b04)
Java HotSpot(TM) Server VM (build 11.2-b01, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux hws1002 2.6.9-55.ELsmp #1 SMP Wed May 2 14:28:44 EDT 2007 i686 i686 i386 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
The File.getxxxSpace() methods are using the statfs() system call rather than statfs64() to determine the space available on the file system. For larger file systems (in my case, the file system is 65 TB) these methods simply return 0. Switching to statfs64() for 32-bit Java would resolve this issue.
As you can see below, a 'df' command on the same system is doing the right thing and calling statfs64() and getting correct results rather than an overflow. 32bit Java is already using the 64bit calls for most (all?) of the other I/O-related calls so it should be doing the same thing for these calls.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the trivial Java class provided below against a really large file system. There's no exact filesystem size where this will break since it's dependent on the blocksize and other parameters reported by the filesystem. Basically you need a filesystem large enough to cause an overflow in the statfs structure.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I expected to get the available free space etc.
ACTUAL -
What I got instead was 0L.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Here's sample output along with output from df and output captured using strace showing the actual statfs calls for both java and df:
Java output:
/bigfs
freeSpace: 0
usableSpace: 0
totalSpace: 0
Java strace output (showing the relevant stat calls only):
[pid 31608] 0.000119 statfs("/bigfs", 0xf7fdfeec) = -1 EOVERFLOW (Value too large for defined data type)
[pid 31608] 0.000092 statfs("/bigfs", 0xf7fdfeec) = -1 EOVERFLOW (Value too large for defined data type)
[pid 31608] 0.000085 statfs("/bigfs", 0xf7fdfeec) = -1 EOVERFLOW (Value too large for defined data type)
df output:
Filesystem 1K-blocks Used Available Use% Mounted on
nfs2:/ifs/bigfs/
69664289472 65083653344 4580636128 94% /bigfs
df strace output (showing relevant stat calls only):
0.000109 statfs64("/bigfs", 84, {f_type="NFS_SUPER_MAGIC", f_bsize=32768, f_blocks=2177009046, f_bfree=143144879, f_bavail=143144879, f_files=102902400000, f_ffree=8476305465, f_fsid={0, 0}, f_namelen=255, f_frsize=32768}) = 0
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
File TestSpace.java:
import java.io.File;
import java.text.NumberFormat;
public class TestSpace
{
private static NumberFormat formatter = NumberFormat.getInstance();
public static void main(String[] args)
{
File file = new File(args[0]);
System.out.println(file);
System.out.println("freeSpace: " + formatter.format(file.getFreeSpace()));
System.out.println("usableSpace: " + formatter.format(file.getUsableSpace()));
System.out.println("totalSpace: " + formatter.format(file.getTotalSpace()));
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
If the machine mounting the file system is 64bit then installing the 64bit version of Java will resolve the issue. There's no known workaround for 32bit machines.
java version "1.6.0_12"
Java(TM) SE Runtime Environment (build 1.6.0_12-b04)
Java HotSpot(TM) Server VM (build 11.2-b01, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux hws1002 2.6.9-55.ELsmp #1 SMP Wed May 2 14:28:44 EDT 2007 i686 i686 i386 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
The File.getxxxSpace() methods are using the statfs() system call rather than statfs64() to determine the space available on the file system. For larger file systems (in my case, the file system is 65 TB) these methods simply return 0. Switching to statfs64() for 32-bit Java would resolve this issue.
As you can see below, a 'df' command on the same system is doing the right thing and calling statfs64() and getting correct results rather than an overflow. 32bit Java is already using the 64bit calls for most (all?) of the other I/O-related calls so it should be doing the same thing for these calls.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the trivial Java class provided below against a really large file system. There's no exact filesystem size where this will break since it's dependent on the blocksize and other parameters reported by the filesystem. Basically you need a filesystem large enough to cause an overflow in the statfs structure.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I expected to get the available free space etc.
ACTUAL -
What I got instead was 0L.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Here's sample output along with output from df and output captured using strace showing the actual statfs calls for both java and df:
Java output:
/bigfs
freeSpace: 0
usableSpace: 0
totalSpace: 0
Java strace output (showing the relevant stat calls only):
[pid 31608] 0.000119 statfs("/bigfs", 0xf7fdfeec) = -1 EOVERFLOW (Value too large for defined data type)
[pid 31608] 0.000092 statfs("/bigfs", 0xf7fdfeec) = -1 EOVERFLOW (Value too large for defined data type)
[pid 31608] 0.000085 statfs("/bigfs", 0xf7fdfeec) = -1 EOVERFLOW (Value too large for defined data type)
df output:
Filesystem 1K-blocks Used Available Use% Mounted on
nfs2:/ifs/bigfs/
69664289472 65083653344 4580636128 94% /bigfs
df strace output (showing relevant stat calls only):
0.000109 statfs64("/bigfs", 84, {f_type="NFS_SUPER_MAGIC", f_bsize=32768, f_blocks=2177009046, f_bfree=143144879, f_bavail=143144879, f_files=102902400000, f_ffree=8476305465, f_fsid={0, 0}, f_namelen=255, f_frsize=32768}) = 0
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
File TestSpace.java:
import java.io.File;
import java.text.NumberFormat;
public class TestSpace
{
private static NumberFormat formatter = NumberFormat.getInstance();
public static void main(String[] args)
{
File file = new File(args[0]);
System.out.println(file);
System.out.println("freeSpace: " + formatter.format(file.getFreeSpace()));
System.out.println("usableSpace: " + formatter.format(file.getUsableSpace()));
System.out.println("totalSpace: " + formatter.format(file.getTotalSpace()));
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
If the machine mounting the file system is 64bit then installing the 64bit version of Java will resolve the issue. There's no known workaround for 32bit machines.
- backported by
-
JDK-2188253 File.getxxxSpace() methods fail for very large file systems under 32bit Java
-
- Resolved
-
-
JDK-2188715 File.getxxxSpace() methods fail for very large file systems under 32bit Java
-
- Closed
-
- duplicates
-
JDK-6873582 java_io/File/DiskSpace fails on 32-bit Solaris
-
- Closed
-