lizardfs/0001-mount-Fix-direntry-cac...

66 lines
2.3 KiB
Diff

From 6b648fe7680610b23aeb890af6f8113b517953f5 Mon Sep 17 00:00:00 2001
From: Piotr Sarna <sarna@skytechnology.pl>
Date: Tue, 16 May 2017 13:41:15 +0200
Subject: [PATCH] mount: Fix direntry cache bug for repeated paths
This commit fixes a bug which caused direntry cache to crash
if two different nodes with same parent and name appear simultaneously
in cache.
Closes #551
Change-Id: I0279c5ea492ccb7b4d4df7e83f01e69ee8c3d954
---
src/mount/direntry_cache.h | 7 +++++++
src/mount/direntry_cache_unittest.cc | 12 ++++++++++++
2 files changed, 19 insertions(+)
diff --git a/src/mount/direntry_cache.h b/src/mount/direntry_cache.h
index 1c27a14..69a21c4 100644
--- a/src/mount/direntry_cache.h
+++ b/src/mount/direntry_cache.h
@@ -343,13 +343,20 @@ public:
IndexCompare());
std::size_t current_index = first_index;
for (const DirectoryEntry &de : container) {
+ auto lookup_it = find(ctx, parent_inode, de.name);
if (it == index_set_.end() ||
std::make_tuple(parent_inode, ctx.uid, ctx.gid) !=
std::make_tuple(it->parent_inode, it->uid, it->gid) ||
it->index != current_index) {
+ if (lookup_it != lookup_end()) {
+ erase(std::addressof(*lookup_it));
+ }
it = addEntry(ctx, parent_inode, de.inode, current_index, de.name,
de.attributes, timestamp);
} else {
+ if (lookup_it != lookup_end() && it != index_set_.iterator_to(*lookup_it)) {
+ erase(std::addressof(*lookup_it));
+ }
overwriteEntry(*it, de, timestamp);
}
++it;
diff --git a/src/mount/direntry_cache_unittest.cc b/src/mount/direntry_cache_unittest.cc
index 279488f..1199dc2 100644
--- a/src/mount/direntry_cache_unittest.cc
+++ b/src/mount/direntry_cache_unittest.cc
@@ -83,3 +83,15 @@ TEST(DirEntryCache, Basic) {
by_inode_it++;
ASSERT_EQ(by_inode_it, cache.inode_end());
}
+
+TEST(DirEntryCache, Repetitions) {
+ DirEntryCache cache(5000000);
+
+ Attributes dummy_attributes;
+ dummy_attributes.fill(0);
+ auto current_time = cache.updateTime();
+
+ cache.insertSubsequent(LizardClient::Context(0, 0, 0, 0), 9, 0, std::vector<DirectoryEntry>{{7, "a1", dummy_attributes}}, current_time);
+ cache.insertSubsequent(LizardClient::Context(0, 0, 0, 0), 9, 1, std::vector<DirectoryEntry>{{7, "a1", dummy_attributes}}, current_time);
+ cache.removeOldest(5);
+}
--
2.9.3