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:
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user