Fix for "Cluster size not supported"

Rein Klazes wijn at wanadoo.nl
Sat Jan 1 09:47:00 CST 2005


Hallo, 

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-01 13:21:24.000000000 +0100
@@ -1302,8 +1302,11 @@ NTSTATUS WINAPI NtQueryVolumeInformation
         else
         {
             FILE_FS_SIZE_INFORMATION *info = buffer;
-            struct statvfs stvfs;
-
+#ifndef HAVE_FSTATFS
+            struct statvfs stfs;
+#else
+            struct statfs stfs;
+#endif
             if (fstat( fd, &st ) < 0)
             {
                 io->u.Status = FILE_GetNtStatus();
@@ -1314,13 +1317,20 @@ NTSTATUS WINAPI NtQueryVolumeInformation
                 io->u.Status = STATUS_INVALID_DEVICE_REQUEST;
                 break;
             }
-            if (fstatvfs( fd, &stvfs ) < 0) io->u.Status = FILE_GetNtStatus();
+#ifndef 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