From 958af856f8428a96d0f99dc55f1f0f1e32effcb4 Mon Sep 17 00:00:00 2001 From: Quinten <67589015+QuintenQVD0@users.noreply.github.com> Date: Thu, 22 Jan 2026 16:28:57 +0100 Subject: [PATCH] Implement hard link detection in directory size calculation Added logic to detect and handle hard links to avoid size duplication. --- server/filesystem/disk_space.go | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/server/filesystem/disk_space.go b/server/filesystem/disk_space.go index 48243800..0a343b65 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" @@ -163,7 +165,9 @@ func (fs *Filesystem) DirectorySize(root string) (int64, error) { if err != nil { 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,9 +184,17 @@ 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/pelican-dev/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 })