diff options
author | 2020-02-19 13:45:29 +0000 | |
---|---|---|
committer | 2020-03-02 10:18:19 +0000 | |
commit | 568f17a08a58a6c144e92e2152bbf0146eb741c2 (patch) | |
tree | 2ed17fdd171307ec573a65e3c316d06777caa336 /jni/node.cpp | |
parent | db73a986ddf433fb4751949146ebfaf259bd3cad (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.cpp | 10 |
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; } } |