github.com/kaydxh/golang@v0.0.131/go/syscall/disk.go (about) 1 /* 2 *Copyright (c) 2022, kaydxh 3 * 4 *Permission is hereby granted, free of charge, to any person obtaining a copy 5 *of this software and associated documentation files (the "Software"), to deal 6 *in the Software without restriction, including without limitation the rights 7 *to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 *copies of the Software, and to permit persons to whom the Software is 9 *furnished to do so, subject to the following conditions: 10 * 11 *The above copyright notice and this permission notice shall be included in all 12 *copies or substantial portions of the Software. 13 * 14 *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 *IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 *FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 *AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 *LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 *OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 *SOFTWARE. 21 */ 22 package syscall 23 24 import ( 25 "syscall" 26 27 filesystem_ "github.com/kaydxh/golang/go/filesystem" 28 ) 29 30 type DiskUsage struct { 31 stat *syscall.Statfs_t 32 } 33 34 func NewDiskUsage(path string) (*DiskUsage, error) { 35 var stat syscall.Statfs_t 36 mount, err := filesystem_.FindMount(path) 37 if err != nil { 38 return nil, err 39 } 40 41 err = syscall.Statfs(mount.Path, &stat) 42 if err != nil { 43 return nil, err 44 } 45 46 return &DiskUsage{&stat}, nil 47 } 48 49 // Free returns total free bytes on file system 50 func (du *DiskUsage) Free() uint64 { 51 return du.stat.Bfree * uint64(du.stat.Bsize) 52 } 53 54 // Avail returns total avail bytes on file system 55 func (du *DiskUsage) Avail() uint64 { 56 return du.stat.Bavail * uint64(du.stat.Bsize) 57 } 58 59 // Size returns total size of the file system 60 func (du *DiskUsage) Size() uint64 { 61 return uint64(du.stat.Blocks) * uint64(du.stat.Bsize) 62 } 63 64 // Size returns total used bytes on the file system 65 func (du *DiskUsage) Used() uint64 { 66 return du.Size() - du.Free() 67 } 68 69 // Usage returns percentage of used on the file system 70 /* 71 https://github.com/coreutils/coreutils/blob/master/src/df.c#:~:text=pct%20%3D%20u100%20/%20nonroot_total%20%2B%20(u100%20%25%20nonroot_total%20!%3D%200)%3B 72 By default, ext2/3/4 filesystems reserve 5% of the space to be useable only by root. This is to avoid a normal user completely filling the disk which would 73 then cause system components to fail whenever they next needed to write to the disk 74 */ 75 func (du *DiskUsage) Usage() float32 { 76 var deta float32 77 u100 := du.Used() * 100 78 nonrootTotal := du.Used() + du.Avail() 79 if u100%nonrootTotal != 0 { 80 deta = 1.0 81 } 82 return float32(u100)/float32(nonrootTotal) + deta 83 }