8387309: GetXSpace test fails on ReFS and removable Windows volumes

Reviewed-by: jpai
This commit is contained in:
Ashay Rane 2026-07-28 02:03:35 +00:00 committed by Jaikiran Pai
parent 410a952239
commit 44ef3188ad
2 changed files with 22 additions and 93 deletions

View File

@ -53,8 +53,6 @@ public class GetXSpace {
System.loadLibrary("GetXSpace");
}
private static final Pattern DF_PATTERN = Pattern.compile("([^\\s]+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+\\d+%\\s+([^\\s].*)\n");
private static int fail = 0;
private static int pass = 0;
private static Throwable first;
@ -105,12 +103,8 @@ public class GetXSpace {
Space(String name) throws IOException {
this.name = name;
long[] sizes = new long[4];
if (Platform.isWindows() && isCDDrive(name)) {
getCDDriveSpace(name, sizes);
} else {
if (getSpace(name, sizes))
System.err.println("WARNING: total space is estimated");
}
if (getSpace(name, sizes))
System.err.println("WARNING: total space is estimated");
this.size = sizes[0];
this.total = sizes[1];
this.free = sizes[2];
@ -178,8 +172,7 @@ public class GetXSpace {
out.format("%s (%d):%n", s.name(), s.size());
String fmt = " %-4s total = %12d free = %12d usable = %12d%n";
String method = Platform.isWindows() && isCDDrive(s.name()) ? "getCDDriveSpace" : "getSpace";
out.format(fmt, method, s.total(), s.free(), s.available());
out.format(fmt, "getSpace", s.total(), s.free(), s.available());
out.format(fmt, "getXSpace", ts, fs, us);
// If the file system can dynamically change size, this check will fail.
@ -331,7 +324,6 @@ public class GetXSpace {
out.println("--- Testing volumes");
// Find all of the partitions on the machine and verify that the sizes
// returned by File::getXSpace are equivalent to those from getSpace
// or getCDDriveSpace
ArrayList<String> l;
try {
l = paths();
@ -417,8 +409,6 @@ public class GetXSpace {
private static native boolean getSpace0(String root, long[] space)
throws IOException;
private static native boolean isCDDrive(String root);
private static boolean getSpace(String root, long[] space)
throws IOException {
try {
@ -430,38 +420,4 @@ public class GetXSpace {
throw e;
}
}
private static void getCDDriveSpace(String root, long[] sizes)
throws IOException {
String[] cmd = new String[] {"df", "-k", "-P", root};
Process p = Runtime.getRuntime().exec(cmd);
StringBuilder sb = new StringBuilder();
try (BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
String s;
int i = 0;
while ((s = in.readLine()) != null) {
// skip header
if (i++ == 0) continue;
sb.append(s).append("\n");
}
}
out.println(sb);
Matcher m = DF_PATTERN.matcher(sb);
int j = 0;
while (j < sb.length()) {
if (m.find(j)) {
sizes[0] = Long.parseLong(m.group(2)) * 1024;
sizes[1] = Long.parseLong(m.group(3)) * 1024;
sizes[2] = sizes[0] - sizes[1];
sizes[3] = Long.parseLong(m.group(4)) * 1024;
j = m.end();
} else {
throw new RuntimeException("unrecognized df output format: "
+ "charAt(" + j + ") = '"
+ sb.charAt(j) + "'");
}
}
}
}

View File

@ -44,7 +44,7 @@ extern "C" {
#ifdef WINDOWS
jboolean initialized = JNI_FALSE;
BOOL(WINAPI * pfnGetDiskSpaceInformation)(LPCWSTR, LPVOID) = NULL;
HRESULT(WINAPI * pfnGetDiskSpaceInformation)(LPCWSTR, LPVOID) = NULL;
#endif
//
@ -82,29 +82,28 @@ Java_GetXSpace_getSpace0
if (pfnGetDiskSpaceInformation != NULL) {
// use GetDiskSpaceInformationW
DISK_SPACE_INFORMATION diskSpaceInfo;
BOOL hres = pfnGetDiskSpaceInformation(path, &diskSpaceInfo);
(*env)->ReleaseStringChars(env, root, strchars);
HRESULT hres = pfnGetDiskSpaceInformation(path, &diskSpaceInfo);
if (FAILED(hres)) {
JNU_ThrowByNameWithLastError(env, "java/io/IOException",
"GetDiskSpaceInformationW");
return totalSpaceIsEstimated;
totalSpaceIsEstimated = JNI_TRUE;
} else {
(*env)->ReleaseStringChars(env, root, strchars);
ULONGLONG bytesPerAllocationUnit =
diskSpaceInfo.SectorsPerAllocationUnit*diskSpaceInfo.BytesPerSector;
array[0] = (jlong)(diskSpaceInfo.ActualTotalAllocationUnits*
bytesPerAllocationUnit);
array[1] = (jlong)(diskSpaceInfo.CallerTotalAllocationUnits*
bytesPerAllocationUnit);
array[2] = (jlong)(diskSpaceInfo.ActualAvailableAllocationUnits*
bytesPerAllocationUnit);
array[3] = (jlong)(diskSpaceInfo.CallerAvailableAllocationUnits*
bytesPerAllocationUnit);
}
ULONGLONG bytesPerAllocationUnit =
diskSpaceInfo.SectorsPerAllocationUnit*diskSpaceInfo.BytesPerSector;
array[0] = (jlong)(diskSpaceInfo.ActualTotalAllocationUnits*
bytesPerAllocationUnit);
array[1] = (jlong)(diskSpaceInfo.CallerTotalAllocationUnits*
bytesPerAllocationUnit);
array[2] = (jlong)(diskSpaceInfo.ActualAvailableAllocationUnits*
bytesPerAllocationUnit);
array[3] = (jlong)(diskSpaceInfo.CallerAvailableAllocationUnits*
bytesPerAllocationUnit);
} else {
totalSpaceIsEstimated = JNI_TRUE;
}
// if GetDiskSpaceInformationW is unavailable ("The specified
// procedure could not be found"), fall back to GetDiskFreeSpaceExW
if (totalSpaceIsEstimated == JNI_TRUE) {
// fall back to GetDiskFreeSpaceExW
ULARGE_INTEGER freeBytesAvailable;
ULARGE_INTEGER totalNumberOfBytes;
ULARGE_INTEGER totalNumberOfFreeBytes;
@ -112,7 +111,7 @@ Java_GetXSpace_getSpace0
BOOL hres = GetDiskFreeSpaceExW(path, &freeBytesAvailable,
&totalNumberOfBytes, &totalNumberOfFreeBytes);
(*env)->ReleaseStringChars(env, root, strchars);
if (FAILED(hres)) {
if (!hres) {
JNU_ThrowByNameWithLastError(env, "java/io/IOException",
"GetDiskFreeSpaceExW");
return totalSpaceIsEstimated;
@ -159,32 +158,6 @@ Java_GetXSpace_getSpace0
return totalSpaceIsEstimated;
}
JNIEXPORT jboolean JNICALL
Java_GetXSpace_isCDDrive
(JNIEnv *env, jclass cls, jstring root)
{
#ifdef WINDOWS
const jchar* strchars = (*env)->GetStringChars(env, root, NULL);
if (strchars == NULL) {
JNU_ThrowByNameWithLastError(env, "java/lang/RuntimeException",
"GetStringChars");
return JNI_FALSE;
}
LPCWSTR path = (LPCWSTR)strchars;
UINT driveType = GetDriveTypeW(path);
(*env)->ReleaseStringChars(env, root, strchars);
if (driveType != DRIVE_CDROM) {
return JNI_FALSE;
}
return JNI_TRUE;
#else
return JNI_FALSE;
#endif
}
#ifdef __cplusplus
}
#endif