Line data Source code
1 : // Copyright 2020 The LevelDB-Go and Pebble Authors. All rights reserved. Use 2 : // of this source code is governed by a BSD-style license that can be found in 3 : // the LICENSE file. 4 : 5 : //go:build linux 6 : // +build linux 7 : 8 : package vfs 9 : 10 : import "golang.org/x/sys/unix" 11 : 12 0 : func (defaultFS) GetDiskUsage(path string) (DiskUsage, error) { 13 0 : stat := unix.Statfs_t{} 14 0 : if err := unix.Statfs(path, &stat); err != nil { 15 0 : return DiskUsage{}, err 16 0 : } 17 : 18 : // We use stat.Frsize here rather than stat.Bsize because on 19 : // Linux Bavail and Bfree are in Frsize units. 20 : // 21 : // On most filesystems Frsize and Bsize will be set to the 22 : // same value, but on some filesystems bsize returns the 23 : // "optimal transfer block size"[1] which may be different 24 : // (typically larger) than the actual block size. 25 : // 26 : // This confusion is cleared up in the statvfs[2] libc function, 27 : // but the statfs system call used above varies across 28 : // platforms. 29 : // 30 : // Frsize is used by GNU coreutils and other libraries, so 31 : // this also helps ensure that we get the same results as one 32 : // would get if they ran `df` on the given path. 33 : // 34 : // [1] https://man7.org/linux/man-pages/man2/statfs.2.html 35 : // [2] https://man7.org/linux/man-pages/man3/statvfs.3.html 36 0 : freeBytes := uint64(stat.Frsize) * uint64(stat.Bfree) 37 0 : availBytes := uint64(stat.Frsize) * uint64(stat.Bavail) 38 0 : totalBytes := uint64(stat.Frsize) * uint64(stat.Blocks) 39 0 : return DiskUsage{ 40 0 : AvailBytes: availBytes, 41 0 : TotalBytes: totalBytes, 42 0 : UsedBytes: totalBytes - freeBytes, 43 0 : }, nil 44 : }