From 1ad5fb8f767d55edb96ed2d3f750a4356e8e8586 Mon Sep 17 00:00:00 2001 From: Bala FA Date: Mon, 4 Jul 2016 11:04:45 +0530 Subject: [PATCH] posix: checkDiskFree() also checks free inodes. (#2086) Previously checkDiskFree() checks for free available space. This patch enables checkDiskFree() also checks for free inodes in linux and free clusters in windows. Fixes #2075 --- pkg/disk/disk.go | 2 ++ pkg/disk/disk_test.go | 2 ++ pkg/disk/stat_nix.go | 2 ++ pkg/disk/stat_windows.go | 28 ++++++++++++++++++++++++++++ posix.go | 5 +++-- 5 files changed, 37 insertions(+), 2 deletions(-) diff --git a/pkg/disk/disk.go b/pkg/disk/disk.go index b95c95fbc..4eae7c211 100644 --- a/pkg/disk/disk.go +++ b/pkg/disk/disk.go @@ -23,5 +23,7 @@ package disk type Info struct { Total int64 Free int64 + Files int64 + Ffree int64 FSType string } diff --git a/pkg/disk/disk_test.go b/pkg/disk/disk_test.go index f7e0fb024..58858a4ff 100644 --- a/pkg/disk/disk_test.go +++ b/pkg/disk/disk_test.go @@ -41,5 +41,7 @@ func (s *MySuite) TestFree(c *C) { c.Assert(err, IsNil) c.Assert(di.Total, Not(Equals), 0) c.Assert(di.Free, Not(Equals), 0) + c.Assert(di.Files, Not(Equals), 0) + c.Assert(di.Ffree, Not(Equals), 0) c.Assert(di.FSType, Not(Equals), "UNKNOWN") } diff --git a/pkg/disk/stat_nix.go b/pkg/disk/stat_nix.go index c8e48d2b7..fcff64be4 100644 --- a/pkg/disk/stat_nix.go +++ b/pkg/disk/stat_nix.go @@ -32,6 +32,8 @@ func GetInfo(path string) (info Info, err error) { info = Info{} info.Total = int64(s.Bsize) * int64(s.Blocks) info.Free = int64(s.Bsize) * int64(s.Bfree) + info.Files = int64(s.Files) + info.Ffree = int64(s.Ffree) info.FSType, err = getFSType(path) if err != nil { return Info{}, err diff --git a/pkg/disk/stat_windows.go b/pkg/disk/stat_windows.go index 81c4ffe9d..6054350f6 100644 --- a/pkg/disk/stat_windows.go +++ b/pkg/disk/stat_windows.go @@ -60,5 +60,33 @@ func GetInfo(path string) (info Info, err error) { info.Total = int64(lpTotalNumberOfBytes) info.Free = int64(lpFreeBytesAvailable) info.FSType = getFSType(path) + + // https://msdn.microsoft.com/en-us/library/windows/desktop/aa364935(v=vs.85).aspx + // Retrieves information about the specified disk, including the amount of free space on the disk. + GetDiskFreeSpace := dll.MustFindProc("GetDiskFreeSpaceW") + + // Return values of GetDiskFreeSpace() + lpSectorsPerCluster := uint32(0) + lpBytesPerSector := uint32(0) + lpNumberOfFreeClusters := uint32(0) + lpTotalNumberOfClusters := uint32(0) + + // Extract values safely + // BOOL WINAPI GetDiskFreeSpace( + // _In_ LPCTSTR lpRootPathName, + // _Out_ LPDWORD lpSectorsPerCluster, + // _Out_ LPDWORD lpBytesPerSector, + // _Out_ LPDWORD lpNumberOfFreeClusters, + // _Out_ LPDWORD lpTotalNumberOfClusters + // ); + _, _, _ = GetDiskFreeSpace.Call(uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(path))), + uintptr(unsafe.Pointer(&lpSectorsPerCluster)), + uintptr(unsafe.Pointer(&lpBytesPerSector)), + uintptr(unsafe.Pointer(&lpNumberOfFreeClusters)), + uintptr(unsafe.Pointer(&lpTotalNumberOfClusters))) + + info.Files = int64(lpTotalNumberOfClusters) + info.Ffree = int64(lpNumberOfFreeClusters) + return info, nil } diff --git a/posix.go b/posix.go index 1a8b1ed32..68a3b5aa9 100644 --- a/posix.go +++ b/posix.go @@ -133,7 +133,7 @@ func getDiskInfo(diskPath string) (di disk.Info, err error) { return di, err } -// checkDiskFree verifies if disk path has sufficient minimum free disk space. +// checkDiskFree verifies if disk path has sufficient minimum free disk space and files. func checkDiskFree(diskPath string, minFreeDisk int64) (err error) { di, err := getDiskInfo(diskPath) if err != nil { @@ -143,7 +143,8 @@ func checkDiskFree(diskPath string, minFreeDisk int64) (err error) { // Remove 5% from total space for cumulative disk // space used for journalling, inodes etc. availableDiskSpace := (float64(di.Free) / (float64(di.Total) - (0.05 * float64(di.Total)))) * 100 - if int64(availableDiskSpace) <= minFreeDisk { + availableFiles := (float64(di.Ffree) / (float64(di.Files) - (0.05 * float64(di.Files)))) * 100 + if int64(availableDiskSpace) <= minFreeDisk || int64(availableFiles) <= minFreeDisk { return errDiskFull }