summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimo Weingärtner <timo@tiwe.de>2011-11-28 01:11:16 +0100
committerTimo Weingärtner <timo@tiwe.de>2011-11-30 14:30:29 +0100
commit7349d7a5f4c305f5ba350858cc810ab79ca81bb4 (patch)
tree90a1c8258a331f15d02527892a4922cd62b2a333
parentf52b13a15df60b02e10f88b656192a2db5077706 (diff)
downloadhadori-7349d7a5f4c305f5ba350858cc810ab79ca81bb4.tar.gz
forget/dont't memorize inode in to_link if st_nlink == 1
Might have caused data loss if inode number is reallocted to a file inside the tree(s) being scanned. Also saves a little bit of memory.
-rw-r--r--TODO2
-rw-r--r--hadori.C5
2 files changed, 4 insertions, 3 deletions
diff --git a/TODO b/TODO
index 792be23..7019419 100644
--- a/TODO
+++ b/TODO
@@ -1,7 +1,5 @@
TODO/possible optimizations
===========================
-* forget inode in to_link if link count is 1 before linking (might cause data
- loss if inode is reallocted to a file inside the tree(s) being scanned)
* more debug output when attributes mismatch in handle_file()
* perhaps use hash_map, hash_multimap for better performance?
diff --git a/hadori.C b/hadori.C
index fcdebd4..4ac0684 100644
--- a/hadori.C
+++ b/hadori.C
@@ -56,6 +56,8 @@ void handle_file(std::string const & path, struct stat const & s) {
inode const & target = kept.find(to_link[s.st_ino])->second;
debug << "another link to inode " << s.st_ino << " that we merge with " << target << std::endl;
do_link(target, path);
+ if (s.st_nlink == 1)
+ to_link.erase(s.st_ino);
return;
}
inode f(path, s);
@@ -78,7 +80,8 @@ void handle_file(std::string const & path, struct stat const & s) {
if (!compare(candidate, f))
continue;
verbose << "linking " << candidate << " to " << path << std::endl;
- to_link.insert(std::make_pair(s.st_ino, it->second));
+ if (s.st_nlink > 1)
+ to_link.insert(std::make_pair(s.st_ino, it->second));
if (not config.count("dry-run"))
do_link(candidate, path);
return;