From 73752bdd5989ff5a75b041f52cb3b6db4991689b Mon Sep 17 00:00:00 2001 From: Sean Grider Date: Mon, 16 Sep 2024 14:28:39 -0400 Subject: [PATCH] Track inodes and use them for hard link comparisons on linux --- VDF.Core/FileEntry.cs | 10 ++++++++++ VDF.Core/ScanEngine.cs | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/VDF.Core/FileEntry.cs b/VDF.Core/FileEntry.cs index ba4de82f..64811ee9 100644 --- a/VDF.Core/FileEntry.cs +++ b/VDF.Core/FileEntry.cs @@ -38,6 +38,14 @@ public FileEntry(FileInfo fileInfo) { DateCreated = fileInfo.CreationTimeUtc; DateModified = fileInfo.LastWriteTimeUtc; FileSize = fileInfo.Length; + if (CoreUtils.IsWindows) { + Inode = 0; + } else { + var ok = Mono.Unix.Native.Syscall.stat(_Path, out var stat); + if (ok == 0) { + Inode = stat.st_ino; + } + } } [ProtoMember(1)] @@ -65,6 +73,8 @@ public string Path { public DateTime DateModified; [ProtoMember(8)] public long FileSize; + [ProtoMember(9)] + public ulong Inode; [ProtoIgnore] internal bool invalid = true; diff --git a/VDF.Core/ScanEngine.cs b/VDF.Core/ScanEngine.cs index ec8e16e0..d930cccf 100644 --- a/VDF.Core/ScanEngine.cs +++ b/VDF.Core/ScanEngine.cs @@ -477,6 +477,16 @@ void ScanForDuplicates() { continue; } + // Shortcut for linux, if the inodes are known and they are the same + // these two files are by definition hard links of each other + // no further inspection necessary + if (Settings.ExcludeHardLinks && + entry.Inode > 0 && + entry.Inode == compItem.Inode) { + isDuplicate = false; + break; + } + flags = DuplicateFlags.None; isDuplicate = CheckIfDuplicate(entry, null, compItem, out difference);