39 lines
897 B
Go
Executable File
39 lines
897 B
Go
Executable File
package diskspace
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"math"
|
|
"syscall"
|
|
)
|
|
|
|
var ErrInsufficientSpace = errors.New("not enough free disk space")
|
|
|
|
func Available(path string) (int64, error) {
|
|
var stats syscall.Statfs_t
|
|
if err := syscall.Statfs(path, &stats); err != nil {
|
|
return 0, err
|
|
}
|
|
available := stats.Bavail * uint64(stats.Bsize)
|
|
if available > math.MaxInt64 {
|
|
return math.MaxInt64, nil
|
|
}
|
|
return int64(available), nil
|
|
}
|
|
|
|
func EnsureFree(path string, requiredBytes, reservedBytes int64) error {
|
|
available, err := Available(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if available-reservedBytes < requiredBytes {
|
|
return fmt.Errorf("%w: %.1f GiB needed, %.1f GiB usable after keeping %.1f GiB free",
|
|
ErrInsufficientSpace, toGiB(requiredBytes), toGiB(available-reservedBytes), toGiB(reservedBytes))
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func toGiB(bytes int64) float64 {
|
|
return float64(bytes) / float64(1<<30)
|
|
}
|