summaryrefslogtreecommitdiff
path: root/jni/node.cpp
diff options
context:
space:
mode:
author Narayan Kamath <narayan@google.com> 2020-02-19 13:45:29 +0000
committer Zimuzo Ezeozue <zezeozue@google.com> 2020-03-02 10:18:19 +0000
commit568f17a08a58a6c144e92e2152bbf0146eb741c2 (patch)
tree2ed17fdd171307ec573a65e3c316d06777caa336 /jni/node.cpp
parentdb73a986ddf433fb4751949146ebfaf259bd3cad (diff)
FuseDaemon: Rework inode tracking.
This change contains two related fixes : (a) Clean up a couple of places where nodes were being Released but not tracked. To do this in non-brittle way, the calls to NodeCreated and NodeDeleted have been moved to the point of creation and deletion (i.e, the calls to new and delete). (b) Move node::Create+NodeCreated to the same critical section, and the same for node::Release+NodeReleased. Otherwise it's possible to hit the following race conition: T1: p1->Release() T2: p1 = node::Create() T2: NodeCreated(p1) T1: NodeDeleted(p1) T?: Lookup(p1) (c) This change also tightens up inode tracking by making sure we never insert a duplicate element into set of known inodes. This would have made this problem a little more obvious. (d) Also fix up fuse_node_test to reflect this new API, and fix a bug in node::DeleteTree that was made very obvious by this fix, given the extra work we do during deletion. Test: atest FuseDaemonHostTest Test: adb shell /data/local/fsstress-run.sh Bug: 148709965 Change-Id: I6eea19020007eb56e6111f60cc9e5a4924b592a4 (cherry picked from commit fc867dd040ddee561f97d1bf9c1552a0d79153df)
Diffstat (limited to 'jni/node.cpp')
-rw-r--r--jni/node.cpp10
1 files changed, 6 insertions, 4 deletions
diff --git a/jni/node.cpp b/jni/node.cpp
index 618777442..e17a9e88a 100644
--- a/jni/node.cpp
+++ b/jni/node.cpp
@@ -97,13 +97,15 @@ void node::DeleteTree(node* tree) {
std::lock_guard<std::recursive_mutex> guard(*tree->lock_);
if (tree) {
- for (node* child : tree->children_) {
+ // Make a copy of the list of children because calling Delete tree
+ // will modify the list of children, which will cause issues while
+ // iterating over them.
+ std::vector<node*> children(tree->children_.begin(), tree->children_.end());
+ for (node* child : children) {
DeleteTree(child);
}
- tree->children_.clear();
- LOG(DEBUG) << "DELETE node " << tree->GetName();
- tree->RemoveFromParent();
+ CHECK(tree->children_.empty());
delete tree;
}
}