Eliminated sVnodeCoveredByMutex. The Vnode::covered_by field is now also

protected by the global vnodes lock. The contention mostly moves to other
locks, though. The total -j8 Haiku image build time is only reduced
minimally.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34938 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2010-01-07 17:01:27 +00:00
parent bd0bff449f
commit fb1819be95
+16 -24
View File
@@ -225,27 +225,19 @@ static mutex sMountMutex = MUTEX_INITIALIZER("vfs_mount_lock");
*/ */
static recursive_lock sMountOpLock; static recursive_lock sMountOpLock;
/*! \brief Guards the vnode::covered_by field of any vnode
The holder is allowed to read access the vnode::covered_by field of any
vnode. Additionally holding sMountOpLock allows for write access.
The thread trying to lock the must not hold sVnodeLock.
*/
static mutex sVnodeCoveredByMutex
= MUTEX_INITIALIZER("vfs_vnode_covered_by_lock");
/*! \brief Guards sVnodeTable. /*! \brief Guards sVnodeTable.
The holder is allowed read/write access to sVnodeTable and to The holder is allowed read/write access to sVnodeTable and to
any unbusy vnode in that table, save to the immutable fields (device, id, any unbusy vnode in that table, save to the immutable fields (device, id,
private_node, mount) to which private_node, mount) to which only read-only access is allowed.
only read-only access is allowed, and to the field covered_by, which is The mutable fields advisory_locking, mandatory_locked_by, and ref_count, as
guarded by sMountOpLock and sVnodeCoveredByMutex. well as the busy, removed, unused flags, and the vnode's type can also be
write access when holding a read lock to sVnodeLock *and* having the vnode
locked. Writing access to covered_by requires to write lock sVnodeLock.
The thread trying to lock the mutex must not hold sMountMutex. The thread trying to acquire the lock must not hold sMountMutex.
You must not have this mutex held when calling create_sem(), as this You must not have this lock held when calling create_sem(), as this
might call vfs_free_unused_vnodes(). might call vfs_free_unused_vnodes() and thus cause a deadlock.
*/ */
static rw_lock sVnodeLock = RW_LOCK_INITIALIZER("vfs_vnode_lock"); static rw_lock sVnodeLock = RW_LOCK_INITIALIZER("vfs_vnode_lock");
@@ -1910,12 +1902,14 @@ resolve_mount_point_to_volume_root(struct vnode* vnode)
struct vnode* volumeRoot = NULL; struct vnode* volumeRoot = NULL;
mutex_lock(&sVnodeCoveredByMutex); rw_lock_read_lock(&sVnodeLock);
if (vnode->covered_by) { if (vnode->covered_by) {
volumeRoot = vnode->covered_by; volumeRoot = vnode->covered_by;
inc_vnode_ref_count(volumeRoot); inc_vnode_ref_count(volumeRoot);
} }
mutex_unlock(&sVnodeCoveredByMutex);
rw_lock_read_unlock(&sVnodeLock);
return volumeRoot; return volumeRoot;
} }
@@ -5589,7 +5583,6 @@ fix_dirent(struct vnode* parent, struct dirent* entry,
struct vnode* vnode = lookup_vnode(entry->d_dev, entry->d_ino); struct vnode* vnode = lookup_vnode(entry->d_dev, entry->d_ino);
if (vnode != NULL) { if (vnode != NULL) {
MutexLocker _(&sVnodeCoveredByMutex);
if (vnode->covered_by != NULL) { if (vnode->covered_by != NULL) {
entry->d_dev = vnode->covered_by->device; entry->d_dev = vnode->covered_by->device;
entry->d_ino = vnode->covered_by->id; entry->d_ino = vnode->covered_by->id;
@@ -7117,10 +7110,10 @@ fs_mount(char* path, const char* device, const char* fsName, uint32 flags,
// No race here, since fs_mount() is the only function changing // No race here, since fs_mount() is the only function changing
// covers_vnode (and holds sMountOpLock at that time). // covers_vnode (and holds sMountOpLock at that time).
mutex_lock(&sVnodeCoveredByMutex); rw_lock_write_lock(&sVnodeLock);
if (mount->covers_vnode) if (mount->covers_vnode)
mount->covers_vnode->covered_by = mount->root_vnode; mount->covers_vnode->covered_by = mount->root_vnode;
mutex_unlock(&sVnodeCoveredByMutex); rw_lock_write_unlock(&sVnodeLock);
if (!sRoot) { if (!sRoot) {
sRoot = mount->root_vnode; sRoot = mount->root_vnode;
@@ -7296,11 +7289,10 @@ fs_unmount(char* path, dev_t mountID, uint32 flags, bool kernel)
mount->root_vnode->ref_count--; mount->root_vnode->ref_count--;
vnode_to_be_freed(mount->root_vnode); vnode_to_be_freed(mount->root_vnode);
mount->covers_vnode->covered_by = NULL;
vnodesWriteLocker.Unlock(); vnodesWriteLocker.Unlock();
mutex_lock(&sVnodeCoveredByMutex);
mount->covers_vnode->covered_by = NULL;
mutex_unlock(&sVnodeCoveredByMutex);
put_vnode(mount->covers_vnode); put_vnode(mount->covers_vnode);
// Free all vnodes associated with this mount. // Free all vnodes associated with this mount.