fs_unmount(): We need to hold the vnodes write lock after all. The upside is

that it saves us from locking the individual vnodes.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34872 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2010-01-03 14:10:43 +00:00
parent a210e61053
commit 7fc65e1488
+6 -11
View File
@@ -7229,7 +7229,7 @@ fs_unmount(char* path, dev_t mountID, uint32 flags, bool kernel)
// grab the vnode master mutex to keep someone from creating // grab the vnode master mutex to keep someone from creating
// a vnode while we're figuring out if we can continue // a vnode while we're figuring out if we can continue
ReadLocker vnodesReadLocker(&sVnodeLock); WriteLocker vnodesWriteLocker(&sVnodeLock);
bool disconnectedDescriptors = false; bool disconnectedDescriptors = false;
@@ -7240,8 +7240,6 @@ fs_unmount(char* path, dev_t mountID, uint32 flags, bool kernel)
// make sure all of them are not busy or have refs on them // make sure all of them are not busy or have refs on them
VnodeList::Iterator iterator = mount->vnodes.GetIterator(); VnodeList::Iterator iterator = mount->vnodes.GetIterator();
while (struct vnode* vnode = iterator.Next()) { while (struct vnode* vnode = iterator.Next()) {
AutoLocker<Vnode> nodeLocker(vnode);
// The root vnode ref_count needs to be 1 here (the mount has a // The root vnode ref_count needs to be 1 here (the mount has a
// reference). // reference).
if (vnode->IsBusy() if (vnode->IsBusy()
@@ -7262,11 +7260,11 @@ fs_unmount(char* path, dev_t mountID, uint32 flags, bool kernel)
if (disconnectedDescriptors) { if (disconnectedDescriptors) {
// wait a bit until the last access is finished, and then try again // wait a bit until the last access is finished, and then try again
vnodesReadLocker.Unlock(); vnodesWriteLocker.Unlock();
snooze(100000); snooze(100000);
// TODO: if there is some kind of bug that prevents the ref counts // TODO: if there is some kind of bug that prevents the ref counts
// from getting back to zero, this will fall into an endless loop... // from getting back to zero, this will fall into an endless loop...
vnodesReadLocker.Lock(); vnodesWriteLocker.Lock();
continue; continue;
} }
@@ -7276,12 +7274,12 @@ fs_unmount(char* path, dev_t mountID, uint32 flags, bool kernel)
mount->unmounting = true; mount->unmounting = true;
// prevent new vnodes from being created // prevent new vnodes from being created
vnodesReadLocker.Unlock(); vnodesWriteLocker.Unlock();
disconnect_mount_or_vnode_fds(mount, NULL); disconnect_mount_or_vnode_fds(mount, NULL);
disconnectedDescriptors = true; disconnectedDescriptors = true;
vnodesReadLocker.Lock(); vnodesWriteLocker.Lock();
} }
// we can safely continue, mark all of the vnodes busy and this mount // we can safely continue, mark all of the vnodes busy and this mount
@@ -7290,18 +7288,15 @@ fs_unmount(char* path, dev_t mountID, uint32 flags, bool kernel)
VnodeList::Iterator iterator = mount->vnodes.GetIterator(); VnodeList::Iterator iterator = mount->vnodes.GetIterator();
while (struct vnode* vnode = iterator.Next()) { while (struct vnode* vnode = iterator.Next()) {
AutoLocker<Vnode> nodeLocker(vnode);
vnode->SetBusy(true); vnode->SetBusy(true);
vnode_to_be_freed(vnode); vnode_to_be_freed(vnode);
} }
// The ref_count of the root node is 1 at this point, see above why this is // The ref_count of the root node is 1 at this point, see above why this is
mount->root_vnode->Lock();
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->root_vnode->Unlock();
vnodesReadLocker.Unlock(); vnodesWriteLocker.Unlock();
mutex_lock(&sVnodeCoveredByMutex); mutex_lock(&sVnodeCoveredByMutex);
mount->covers_vnode->covered_by = NULL; mount->covers_vnode->covered_by = NULL;