Recalculate free minimum disk space (#2788)

* Fix calculating free space disk by using blocks available for unprivileged user

* Use fixed minimal free disk space instead of percentage
master
Anis Elleuch 8 years ago committed by Harshavardhana
parent 70d52bbc4c
commit 9417614a8e
  1. 30
      cmd/posix.go
  2. 2
      pkg/disk/stat_nix.go

@ -33,7 +33,8 @@ import (
) )
const ( const (
fsMinSpacePercent = 5 fsMinFreeSpace = 1024 * 1024 * 1024
fsMinFreeInodesPercent = 5
maxAllowedIOError = 5 maxAllowedIOError = 5
) )
@ -41,7 +42,8 @@ const (
type posix struct { type posix struct {
ioErrCount int32 // ref: https://golang.org/pkg/sync/atomic/#pkg-note-BUG ioErrCount int32 // ref: https://golang.org/pkg/sync/atomic/#pkg-note-BUG
diskPath string diskPath string
minFreeDisk int64 minFreeSpace int64
minFreeInodes int64
} }
var errFaultyDisk = errors.New("Faulty disk") var errFaultyDisk = errors.New("Faulty disk")
@ -101,7 +103,8 @@ func newPosix(diskPath string) (StorageAPI, error) {
} }
fs := &posix{ fs := &posix{
diskPath: diskPath, diskPath: diskPath,
minFreeDisk: fsMinSpacePercent, // Minimum 5% disk should be free. minFreeSpace: fsMinFreeSpace,
minFreeInodes: fsMinFreeInodesPercent,
} }
st, err := os.Stat(preparePath(diskPath)) st, err := os.Stat(preparePath(diskPath))
if err != nil { if err != nil {
@ -132,16 +135,15 @@ func getDiskInfo(diskPath string) (di disk.Info, err error) {
} }
// checkDiskFree verifies if disk path has sufficient minimum free disk space and files. // checkDiskFree verifies if disk path has sufficient minimum free disk space and files.
func checkDiskFree(diskPath string, minFreeDisk int64) (err error) { func (s posix) checkDiskFree() (err error) {
di, err := getDiskInfo(diskPath) di, err := getDiskInfo(s.diskPath)
if err != nil { if err != nil {
return err return err
} }
// Remove 5% from total space for cumulative disk // Remove 5% from free space for cumulative disk space used for journalling, inodes etc.
// space used for journalling, inodes etc. availableDiskSpace := float64(di.Free) * 0.95
availableDiskSpace := (float64(di.Free) / (float64(di.Total) - (0.05 * float64(di.Total)))) * 100 if int64(availableDiskSpace) <= s.minFreeSpace {
if int64(availableDiskSpace) <= minFreeDisk {
return errDiskFull return errDiskFull
} }
@ -150,8 +152,8 @@ func checkDiskFree(diskPath string, minFreeDisk int64) (err error) {
// Allow for the available disk to be separately validate and we will validate inodes only if // Allow for the available disk to be separately validate and we will validate inodes only if
// total inodes are provided by the underlying filesystem. // total inodes are provided by the underlying filesystem.
if di.Files != 0 { if di.Files != 0 {
availableFiles := (float64(di.Ffree) / (float64(di.Files) - (0.05 * float64(di.Files)))) * 100 availableFiles := 100 * float64(di.Ffree) / float64(di.Files)
if int64(availableFiles) <= minFreeDisk { if int64(availableFiles) <= s.minFreeInodes {
return errDiskFull return errDiskFull
} }
} }
@ -191,7 +193,7 @@ func (s *posix) MakeVol(volume string) (err error) {
} }
// Validate if disk is free. // Validate if disk is free.
if err = checkDiskFree(s.diskPath, s.minFreeDisk); err != nil { if err = s.checkDiskFree(); err != nil {
return err return err
} }
@ -539,7 +541,7 @@ func (s *posix) AppendFile(volume, path string, buf []byte) (err error) {
} }
// Validate if disk is free. // Validate if disk is free.
if err = checkDiskFree(s.diskPath, s.minFreeDisk); err != nil { if err = s.checkDiskFree(); err != nil {
return err return err
} }
@ -744,7 +746,7 @@ func (s *posix) RenameFile(srcVolume, srcPath, dstVolume, dstPath string) (err e
} }
// Validate if disk is free. // Validate if disk is free.
if err = checkDiskFree(s.diskPath, s.minFreeDisk); err != nil { if err = s.checkDiskFree(); err != nil {
return err return err
} }

@ -31,7 +31,7 @@ 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.Bavail)
info.Files = int64(s.Files) info.Files = int64(s.Files)
info.Ffree = int64(s.Ffree) info.Ffree = int64(s.Ffree)
info.FSType, err = getFSType(path) info.FSType, err = getFSType(path)

Loading…
Cancel
Save