From 1d8b383682c477f9a884a98ae6d30450d2fba43a Mon Sep 17 00:00:00 2001 From: EpicPlayerA10 <62206933+EpicPlayerA10@users.noreply.github.com> Date: Sat, 29 Jun 2024 20:56:51 +0200 Subject: [PATCH] fix: only count hard-links once when calculating filesystem usage (#181) --- server/filesystem/disk_space.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/server/filesystem/disk_space.go b/server/filesystem/disk_space.go index eb8247a..f8760f3 100644 --- a/server/filesystem/disk_space.go +++ b/server/filesystem/disk_space.go @@ -1,6 +1,8 @@ package filesystem import ( + "golang.org/x/sys/unix" + "slices" "sync" "sync/atomic" "time" @@ -164,6 +166,8 @@ func (fs *Filesystem) DirectorySize(root string) (int64, error) { return 0, err } + var hardLinks []uint64 + var size atomic.Int64 err = fs.unixFS.WalkDirat(dirfd, name, func(dirfd int, name, _ string, d ufs.DirEntry, err error) error { if err != nil { @@ -180,8 +184,16 @@ func (fs *Filesystem) DirectorySize(root string) (int64, error) { return errors.Wrap(err, "lstatat err") } - // TODO: detect if info is a hard-link and de-duplicate it. - // ref; https://github.com/pterodactyl/wings/pull/181/files + var sysFileInfo = info.Sys().(*unix.Stat_t) + if sysFileInfo.Nlink > 1 { + // Hard links have the same inode number + if slices.Contains(hardLinks, sysFileInfo.Ino) { + // Don't add hard links size twice + return nil + } else { + hardLinks = append(hardLinks, sysFileInfo.Ino) + } + } size.Add(info.Size()) return nil