Fix for "Cluster size not supported" - resend
Rein Klazes
wijn at wanadoo.nl
Sun Jan 2 09:03:27 CST 2005
Hallo,
This time with the intended patch.
A number of users have reported (on the users list or directly to me)
this error from common programs like dcom98 and msi-installer.
It turns out that fstatvfs() is not quite reliable. Here are the most
important fields returned on a Debian Sarge system on a ext3 formatted
partition of about 15GB:
fstatvfs is available
f_bsize 4096
f_frsize 1104460315
f_blocks 3b0e00
f_bfree 2f5d6c
f_bavail 2c5d79
The problem is obvious, f_frsize is complete rubbish.
Another problem shows with some file systems that return f_frsize
different from f_bsize. Here on an nfs mounted drive of about 9.5 GB:
f_bsize 8192
f_frsize 512
f_blocks 119a60
Totals size of the file system should be f_blocks * f_frsize, but that
gives a value 16 times too small. In this case f_blocks (as f_bfree,
f_bavail) are the number of f_bsize blocks, wrong. This is a quite
up-to-date system, Debian unstable with 2.6.10 kernel.
Attached is the simplest solution, fall back to fstatfs() on Linux
systems. It is btw also what 'df' does.
Changelog:
dlls/ntdll : file.c
On Linux, use fstatfs instead of fstatvfs. It is too buggy.
Rein.
-------------- next part --------------
--- wine/dlls/ntdll/file.c 2004-12-02 09:23:47.000000000 +0100
+++ mywine/dlls/ntdll/file.c 2005-01-02 15:55:40.000000000 +0100
@@ -1302,8 +1302,12 @@ NTSTATUS WINAPI NtQueryVolumeInformation
else
{
FILE_FS_SIZE_INFORMATION *info = buffer;
- struct statvfs stvfs;
-
+ /* Linux's fstatvfs is buggy */
+#if !defined(linux) || !defined(HAVE_FSTATFS)
+ struct statvfs stfs;
+#else
+ struct statfs stfs;
+#endif
if (fstat( fd, &st ) < 0)
{
io->u.Status = FILE_GetNtStatus();
@@ -1314,13 +1318,20 @@ NTSTATUS WINAPI NtQueryVolumeInformation
io->u.Status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
- if (fstatvfs( fd, &stvfs ) < 0) io->u.Status = FILE_GetNtStatus();
+#if !defined(linux) || !defined(HAVE_FSTATFS)
+ if (fstatvfs( fd, &stfs ) < 0) io->u.Status = FILE_GetNtStatus();
else
{
- info->TotalAllocationUnits.QuadPart = stvfs.f_blocks;
- info->AvailableAllocationUnits.QuadPart = stvfs.f_bavail;
+ info->BytesPerSector = stfs.f_frsize;
+#else
+ if (fstatfs( fd, &stfs ) < 0) io->u.Status = FILE_GetNtStatus();
+ else
+ {
+ info->BytesPerSector = stfs.f_bsize;
+#endif
+ info->TotalAllocationUnits.QuadPart = stfs.f_blocks;
+ info->AvailableAllocationUnits.QuadPart = stfs.f_bavail;
info->SectorsPerAllocationUnit = 1;
- info->BytesPerSector = stvfs.f_frsize;
io->Information = sizeof(*info);
io->u.Status = STATUS_SUCCESS;
}
More information about the wine-patches
mailing list