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
This commit is contained in:
Bala FA 2016-07-04 11:04:45 +05:30 committed by Harshavardhana
parent 52b55afce0
commit 1ad5fb8f76
5 changed files with 37 additions and 2 deletions

View File

@ -23,5 +23,7 @@ package disk
type Info struct { type Info struct {
Total int64 Total int64
Free int64 Free int64
Files int64
Ffree int64
FSType string FSType string
} }

View File

@ -41,5 +41,7 @@ func (s *MySuite) TestFree(c *C) {
c.Assert(err, IsNil) c.Assert(err, IsNil)
c.Assert(di.Total, Not(Equals), 0) c.Assert(di.Total, Not(Equals), 0)
c.Assert(di.Free, 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") c.Assert(di.FSType, Not(Equals), "UNKNOWN")
} }

View File

@ -32,6 +32,8 @@ func GetInfo(path string) (info Info, err error) {
info = Info{} info = Info{}
info.Total = int64(s.Bsize) * int64(s.Blocks) info.Total = int64(s.Bsize) * int64(s.Blocks)
info.Free = int64(s.Bsize) * int64(s.Bfree) info.Free = int64(s.Bsize) * int64(s.Bfree)
info.Files = int64(s.Files)
info.Ffree = int64(s.Ffree)
info.FSType, err = getFSType(path) info.FSType, err = getFSType(path)
if err != nil { if err != nil {
return Info{}, err return Info{}, err

View File

@ -60,5 +60,33 @@ func GetInfo(path string) (info Info, err error) {
info.Total = int64(lpTotalNumberOfBytes) info.Total = int64(lpTotalNumberOfBytes)
info.Free = int64(lpFreeBytesAvailable) info.Free = int64(lpFreeBytesAvailable)
info.FSType = getFSType(path) 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 return info, nil
} }

View File

@ -133,7 +133,7 @@ func getDiskInfo(diskPath string) (di disk.Info, err error) {
return di, err 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) { func checkDiskFree(diskPath string, minFreeDisk int64) (err error) {
di, err := getDiskInfo(diskPath) di, err := getDiskInfo(diskPath)
if err != nil { if err != nil {
@ -143,7 +143,8 @@ func checkDiskFree(diskPath string, minFreeDisk int64) (err error) {
// Remove 5% from total space for cumulative disk // Remove 5% from total space for cumulative disk
// space used for journalling, inodes etc. // space used for journalling, inodes etc.
availableDiskSpace := (float64(di.Free) / (float64(di.Total) - (0.05 * float64(di.Total)))) * 100 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 return errDiskFull
} }