diff options
Diffstat (limited to 'winsup/cygwin/syscalls.cc')
-rw-r--r-- | winsup/cygwin/syscalls.cc | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 33eef64d3..0538ffa8a 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -42,6 +42,7 @@ details. */ #include <setjmp.h> #include <winnls.h> #include <wininet.h> +#include <winioctl.h> #include <lmcons.h> /* for UNLEN */ #include <rpc.h> @@ -1841,6 +1842,27 @@ statvfs (const char *fname, struct statvfs *sfs) availc = availb.QuadPart / (spc*bps); totalc = totalb.QuadPart / (spc*bps); freec = freeb.QuadPart / (spc*bps); + if (freec > availc) + { + /* Quotas active. We can't trust totalc. */ + HANDLE hdl = CreateFile (full_path.get_win32 (), READ_CONTROL, + wincap.shared (), &sec_none_nih, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, NULL); + if (hdl == INVALID_HANDLE_VALUE) + debug_printf ("CreateFile (%s) failed, %E", full_path.get_win32 ()); + else + { + NTFS_VOLUME_DATA_BUFFER nvdb; + DWORD bytes; + if (!DeviceIoControl (hdl, FSCTL_GET_NTFS_VOLUME_DATA, NULL, + 0, &nvdb, sizeof nvdb, &bytes, NULL)) + debug_printf ("DeviceIoControl (%s) failed, %E", full_path.get_win32 ()); + else + totalc = nvdb.TotalClusters.QuadPart; + CloseHandle (hdl); + } + } } else availc = freec; |