Skip to content

Commit 6e20c4d

Browse files
authored
Implement hard link detection in directory size calculation (#163)
Added logic to detect and handle hard links to avoid size duplication.
1 parent eb6db92 commit 6e20c4d

1 file changed

Lines changed: 16 additions & 4 deletions

File tree

server/filesystem/disk_space.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package filesystem
22

33
import (
4+
"golang.org/x/sys/unix"
5+
"slices"
46
"sync"
57
"sync/atomic"
68
"time"
@@ -163,7 +165,9 @@ func (fs *Filesystem) DirectorySize(root string) (int64, error) {
163165
if err != nil {
164166
return 0, err
165167
}
166-
168+
169+
var hardLinks []uint64
170+
167171
var size atomic.Int64
168172
err = fs.unixFS.WalkDirat(dirfd, name, func(dirfd int, name, _ string, d ufs.DirEntry, err error) error {
169173
if err != nil {
@@ -180,9 +184,17 @@ func (fs *Filesystem) DirectorySize(root string) (int64, error) {
180184
return errors.Wrap(err, "lstatat err")
181185
}
182186

183-
// TODO: detect if info is a hard-link and de-duplicate it.
184-
// ref; https://github.com/pelican-dev/wings/pull/181/files
185-
187+
var sysFileInfo = info.Sys().(*unix.Stat_t)
188+
if sysFileInfo.Nlink > 1 {
189+
// Hard links have the same inode number
190+
if slices.Contains(hardLinks, sysFileInfo.Ino) {
191+
// Don't add hard links size twice
192+
return nil
193+
} else {
194+
hardLinks = append(hardLinks, sysFileInfo.Ino)
195+
}
196+
}
197+
186198
size.Add(info.Size())
187199
return nil
188200
})

0 commit comments

Comments
 (0)