From waddlesplash <waddlesplash@xxxxxxxxx>:
waddlesplash has uploaded this change for review. (
https://review.haiku-os.org/c/haiku/+/2362 ;)
Change subject: kernel/vfs: Replace the mount mutex with a rw_lock.
......................................................................
kernel/vfs: Replace the mount mutex with a rw_lock.
Since the entry_cache operations go through the mount lock,
this may considerably speed up parallel entry cache operations.
DON'T MERGE; not tested enough.
---
M src/system/kernel/fs/vfs.cpp
1 file changed, 27 insertions(+), 28 deletions(-)
git pull ssh://git.haiku-os.org:22/haiku refs/changes/62/2362/1
diff --git a/src/system/kernel/fs/vfs.cpp b/src/system/kernel/fs/vfs.cpp
index 493971b..033384f 100644
--- a/src/system/kernel/fs/vfs.cpp
+++ b/src/system/kernel/fs/vfs.cpp
@@ -214,7 +214,7 @@
Manipulation of the fs_mount structures themselves
(and their destruction) requires different locks though.
*/
-static mutex sMountMutex = MUTEX_INITIALIZER("vfs_mount_lock");
+static rw_lock sMountLock = MUTEX_INITIALIZER("vfs_mount_lock");
/*! \brief Guards mount/unmount operations.
@@ -226,7 +226,7 @@
sMountsTable will not be modified,
The thread trying to lock the lock must not hold sVnodeLock or
- sMountMutex.
+ sMountLock.
*/
static recursive_lock sMountOpLock;
@@ -241,7 +241,7 @@
locked. Write access to covered_by and covers requires to write lock
sVnodeLock.
- The thread trying to acquire the lock must not hold sMountMutex.
+ The thread trying to acquire the lock must not hold sMountLock.
You must not hold this lock when calling create_sem(), as this might
call
vfs_free_unused_vnodes() and thus cause a deadlock.
*/
@@ -732,12 +732,12 @@
/*! Finds the mounted device (the fs_mount structure) with the given ID.
- Note, you must hold the gMountMutex lock when you call this function.
+ Note, you must hold the sMountLock lock when you call this function.
*/
static struct fs_mount*
find_mount(dev_t id)
{
- ASSERT_LOCKED_MUTEX(&sMountMutex);
+ ASSERT_READ_LOCKED_RW_LOCK(&sMountLock);
return sMountsTable->Lookup(id);
}
@@ -749,7 +749,7 @@
struct fs_mount* mount;
ReadLocker nodeLocker(sVnodeLock);
- MutexLocker mountLocker(sMountMutex);
+ ReadLocker mountLocker(sMountLock);
mount = find_mount(id);
if (mount == NULL)
@@ -971,10 +971,10 @@
}
// get the mount structure
- mutex_lock(&sMountMutex);
+ rw_lock_read_lock(&sMountLock);
vnode->mount = find_mount(mountID);
if (!vnode->mount || vnode->mount->unmounting) {
- mutex_unlock(&sMountMutex);
+ rw_lock_read_unlock(&sMountLock);
rw_lock_write_unlock(&sVnodeLock);
free(vnode);
return B_ENTRY_NOT_FOUND;
@@ -984,7 +984,7 @@
sVnodeTable->Insert(vnode);
add_vnode_to_mount_list(vnode, vnode->mount);
- mutex_unlock(&sMountMutex);
+ rw_lock_read_unlock(&sMountLock);
_vnode = vnode;
_nodeCreated = true;
@@ -1062,7 +1062,7 @@
The caller must, of course, own a reference to the vnode to call this
function.
- The caller must not hold the sVnodeLock or the sMountMutex.
+ The caller must not hold the sVnodeLock or the sMountLock.
\param vnode the vnode.
\param alwaysFree don't move this vnode into the unused list, but really
@@ -1161,7 +1161,7 @@
If the node is not yet in memory, it will be loaded.
- The caller must not hold the sVnodeLock or the sMountMutex.
+ The caller must not hold the sVnodeLock or the sMountLock.
\param mountID the mount ID.
\param vnodeID the node ID.
@@ -1284,7 +1284,7 @@
The caller must, of course, own a reference to the vnode to call this
function.
- The caller must not hold the sVnodeLock or the sMountMutex.
+ The caller must not hold the sVnodeLock or the sMountLock.
\param vnode the vnode.
*/
@@ -4163,7 +4163,7 @@
{
// lookup mount -- the caller is required to make sure that the mount
// won't go away
- MutexLocker locker(sMountMutex);
+ ReadLocker locker(sMountLock);
struct fs_mount* mount = find_mount(mountID);
if (mount == NULL)
return B_BAD_VALUE;
@@ -4178,7 +4178,7 @@
{
// lookup mount -- the caller is required to make sure that the mount
// won't go away
- MutexLocker locker(sMountMutex);
+ ReadLocker locker(sMountLock);
struct fs_mount* mount = find_mount(mountID);
if (mount == NULL)
return B_BAD_VALUE;
@@ -4193,7 +4193,7 @@
{
// lookup mount -- the caller is required to make sure that the mount
// won't go away
- MutexLocker locker(sMountMutex);
+ ReadLocker locker(sMountLock);
struct fs_mount* mount = find_mount(mountID);
if (mount == NULL)
return B_BAD_VALUE;
@@ -5236,7 +5236,7 @@
ino_t* _mountPointNodeID)
{
ReadLocker nodeLocker(sVnodeLock);
- MutexLocker mountLocker(sMountMutex);
+ ReadLocker mountLocker(sMountLock);
struct fs_mount* mount = find_mount(mountID);
if (mount == NULL)
@@ -7574,9 +7574,9 @@
// insert mount struct into list before we call FS's mount() function
// so that vnodes can be created for this mount
- mutex_lock(&sMountMutex);
+ rw_lock_write_lock(&sMountLock);
sMountsTable->Insert(mount);
- mutex_unlock(&sMountMutex);
+ rw_lock_write_unlock(&sMountLock);
ino_t rootID;
@@ -7693,9 +7693,9 @@
if (coveredNode != NULL)
put_vnode(coveredNode);
err2:
- mutex_lock(&sMountMutex);
+ rw_lock_write_lock(&sMountLock);
sMountsTable->Remove(mount);
- mutex_unlock(&sMountMutex);
+ rw_lock_write_unlock(&sMountLock);
err1:
delete mount;
@@ -7720,17 +7720,16 @@
}
RecursiveLocker mountOpLocker(sMountOpLock);
+ ReadLocker mountLocker(sMountLock);
- // this lock is not strictly necessary, but here in case of KDEBUG
- // to keep the ASSERT in find_mount() working.
- KDEBUG_ONLY(mutex_lock(&sMountMutex));
mount = find_mount(path != NULL ? pathVnode->device : mountID);
- KDEBUG_ONLY(mutex_unlock(&sMountMutex));
if (mount == NULL) {
panic("fs_unmount: find_mount() failed on root vnode @%p of
mount\n",
pathVnode);
}
+ mountLocker.Unlock();
+
if (path != NULL) {
put_vnode(pathVnode);
@@ -7901,9 +7900,9 @@
}
// remove the mount structure from the hash table
- mutex_lock(&sMountMutex);
+ rw_lock_write_lock(&sMountLock);
sMountsTable->Remove(mount);
- mutex_unlock(&sMountMutex);
+ rw_lock_write_unlock(&sMountLock);
mountOpLocker.Unlock();
@@ -8071,7 +8070,7 @@
struct fs_mount* mount = NULL;
dev_t device = *_cookie;
- mutex_lock(&sMountMutex);
+ rw_lock_read_lock(&sMountLock);
// Since device IDs are assigned sequentially, this algorithm
// does work good enough. It makes sure that the device list
@@ -8091,7 +8090,7 @@
else
device = B_BAD_VALUE;
- mutex_unlock(&sMountMutex);
+ rw_lock_read_unlock(&sMountLock);
return device;
}
--
To view, visit https://review.haiku-os.org/c/haiku/+/2362
To unsubscribe, or for help writing mail filters, visit
https://review.haiku-os.org/settings
Gerrit-Project: haiku
Gerrit-Branch: master
Gerrit-Change-Id: Ib2f841e288eb593ee3f795922103459c77764c22
Gerrit-Change-Number: 2362
Gerrit-PatchSet: 1
Gerrit-Owner: waddlesplash <waddlesplash@xxxxxxxxx>
Gerrit-MessageType: newchange