From 2d6af8eb16894b44ccbfe42d948265bbb0d7a6ab Mon Sep 17 00:00:00 2001 From: Bartosz Kuzma Date: Sat, 20 Sep 2025 05:58:37 +0200 Subject: [PATCH 1/2] Add support for NetBSD --- filesystems_netbsd.go | 37 +++++++++++++++ mounts_netbsd.go | 105 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 142 insertions(+) create mode 100644 filesystems_netbsd.go create mode 100644 mounts_netbsd.go diff --git a/filesystems_netbsd.go b/filesystems_netbsd.go new file mode 100644 index 00000000..ce322e5f --- /dev/null +++ b/filesystems_netbsd.go @@ -0,0 +1,37 @@ +//go:build netbsd +// +build netbsd + +package main + +func isFuseFs(m Mount) bool { + //FIXME: implement + return false +} + +func isNetworkFs(m Mount) bool { + fs := []string{"nfs", "smbfs"} + + for _, v := range fs { + if m.Fstype == v { + return true + } + } + + return false +} + +func isSpecialFs(m Mount) bool { + fs := []string{"devfs", "kernfs", "procfs", "ptyfs", "tmpfs"} + + for _, v := range fs { + if m.Fstype == v { + return true + } + } + + return false +} + +func isHiddenFs(m Mount) bool { + return false +} diff --git a/mounts_netbsd.go b/mounts_netbsd.go new file mode 100644 index 00000000..ca53e634 --- /dev/null +++ b/mounts_netbsd.go @@ -0,0 +1,105 @@ +//go:build netbsd +// +build netbsd + +package main + +import ( + "unsafe" + "golang.org/x/sys/unix" +) + +func (m *Mount) Stat() unix.Statfs_t { + return m.Metadata.(unix.Statfs_t) +} + +// Use unix.Getvfsstat when CL 550476 is merged +// https://go-review.googlesource.com/c/sys/+/550476 +func Getvfsstat(buf []unix.Statvfs_t, flags int) (n int, err error) { + var ( + _p0 unsafe.Pointer + bufsize uintptr + ) + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + bufsize = unsafe.Sizeof(unix.Statvfs_t{}) * uintptr(len(buf)) + } + r0, _, e1 := unix.Syscall(unix.SYS_GETVFSSTAT, uintptr(_p0), bufsize, uintptr(flags)) + n = int(r0) + if e1 != 0 { + err = e1 + } + return +} + +func mounts() ([]Mount, []string, error) { + var ret []Mount + var warnings []string + + count, err := Getvfsstat(nil, unix.ST_WAIT) + if err != nil { + return nil, nil, err + } + + fs := make([]unix.Statvfs_t, count) + if _, err := Getvfsstat(fs, unix.ST_WAIT); err != nil { + return nil, nil, err + } + + for _, stat := range fs { + opts := "rw" + if stat.Flag&unix.MNT_RDONLY != 0 { + opts = "ro" + } + if stat.Flag&unix.MNT_SYNCHRONOUS != 0 { + opts += ",sync" + } + if stat.Flag&unix.MNT_NOEXEC != 0 { + opts += ",noexec" + } + if stat.Flag&unix.MNT_NOSUID != 0 { + opts += ",nosuid" + } + if stat.Flag&unix.MNT_NODEV != 0 { + opts += ",nodev" + } + if stat.Flag&unix.MNT_ASYNC != 0 { + opts += ",async" + } + if stat.Flag&unix.MNT_SOFTDEP != 0 { + opts += ",softdep" + } + if stat.Flag&unix.MNT_NOATIME != 0 { + opts += ",noatime" + } + + device := byteToString(stat.Mntfromname[:]) + mountPoint := byteToString(stat.Mntonname[:]) + fsType := byteToString(stat.Fstypename[:]) + + if len(device) == 0 { + continue + } + + d := Mount{ + Device: device, + Mountpoint: mountPoint, + Fstype: fsType, + Type: fsType, + Opts: opts, + Metadata: stat, + Total: (uint64(stat.Blocks) * uint64(stat.Bsize)), + Free: (uint64(stat.Bavail) * uint64(stat.Bsize)), + Used: (uint64(stat.Blocks) - uint64(stat.Bfree)) * uint64(stat.Bsize), + Inodes: stat.Files, + InodesFree: uint64(stat.Ffree), + InodesUsed: stat.Files - uint64(stat.Ffree), + Blocks: uint64(stat.Blocks), + BlockSize: uint64(stat.Bsize), + } + d.DeviceType = deviceType(d) + + ret = append(ret, d) + } + + return ret, warnings, nil +} From 47405c4c52d23672e2a0cf356cdea3d6a15630fc Mon Sep 17 00:00:00 2001 From: Bartosz Kuzma Date: Tue, 23 Dec 2025 05:11:48 +0100 Subject: [PATCH 2/2] Fix incorrect sizes reported by duf. According to sys/statvfs.h blocks, bfree, bavail are in units of frsize not bsize. --- mounts_netbsd.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/mounts_netbsd.go b/mounts_netbsd.go index ca53e634..6f55c76b 100644 --- a/mounts_netbsd.go +++ b/mounts_netbsd.go @@ -68,6 +68,9 @@ func mounts() ([]Mount, []string, error) { if stat.Flag&unix.MNT_SOFTDEP != 0 { opts += ",softdep" } + if stat.Flag&unix.MNT_LOG != 0 { + opts += ",log" + } if stat.Flag&unix.MNT_NOATIME != 0 { opts += ",noatime" } @@ -87,14 +90,14 @@ func mounts() ([]Mount, []string, error) { Type: fsType, Opts: opts, Metadata: stat, - Total: (uint64(stat.Blocks) * uint64(stat.Bsize)), - Free: (uint64(stat.Bavail) * uint64(stat.Bsize)), - Used: (uint64(stat.Blocks) - uint64(stat.Bfree)) * uint64(stat.Bsize), + Total: (uint64(stat.Blocks) * uint64(stat.Frsize)), + Free: (uint64(stat.Bavail) * uint64(stat.Frsize)), + Used: (uint64(stat.Blocks) - uint64(stat.Bfree)) * uint64(stat.Frsize), Inodes: stat.Files, InodesFree: uint64(stat.Ffree), InodesUsed: stat.Files - uint64(stat.Ffree), Blocks: uint64(stat.Blocks), - BlockSize: uint64(stat.Bsize), + BlockSize: uint64(stat.Frsize), } d.DeviceType = deviceType(d)