exfat: Add missing locking around SplayTree lookup/insertion.

A lookup in a splay tree does move the looked up entry to the root of
the tree. This means the tree structure is modified on lookup alone.
Obviously the tree structure is also modified when inserting new nodes.

For both of these reasons access to the f{Node|Ino}Tree needs to be
locked on lookup and insert.

Fixes crashes when the tree is concurrently modified by multiple threads
accessing the same exfat volume.

In addition this protects the fNextId field that hands out new inode
ids.
This commit is contained in:
Michael Lotz 2014-07-26 00:21:20 +02:00
parent 3e2653e609
commit 88b722965a

View File

@ -463,6 +463,8 @@ Volume::GetIno(cluster_t cluster, uint32 offset, ino_t parent)
struct node_key key;
key.cluster = cluster;
key.offset = offset;
MutexLocker locker(fLock);
struct node* node = fNodeTree.Lookup(key);
if (node != NULL) {
TRACE("Volume::GetIno() cached cluster %" B_PRIu32 " offset %" B_PRIu32
@ -484,6 +486,7 @@ Volume::GetIno(cluster_t cluster, uint32 offset, ino_t parent)
struct node_key*
Volume::GetNode(ino_t ino, ino_t &parent)
{
MutexLocker locker(fLock);
struct node* node = fInoTree.Lookup(ino);
if (node != NULL) {
parent = node->parent;