* vfs_unmount() can now safely be called from the kernel (fs_unmount() still
tried to access the uninitialized vnode in that case). * That means that it's now safe to remove a mounted CD from the drive, it will then be unmounted automatically. * Added a check for partition::Device() - even though Ingo tells me it's impossible, it was NULL once. * Minor cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22922 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -5812,11 +5812,12 @@ err1:
|
|||||||
static status_t
|
static status_t
|
||||||
fs_unmount(char *path, dev_t mountID, uint32 flags, bool kernel)
|
fs_unmount(char *path, dev_t mountID, uint32 flags, bool kernel)
|
||||||
{
|
{
|
||||||
|
struct vnode *vnode = NULL;
|
||||||
struct fs_mount *mount;
|
struct fs_mount *mount;
|
||||||
struct vnode *vnode;
|
|
||||||
status_t err;
|
status_t err;
|
||||||
|
|
||||||
FUNCTION(("vfs_unmount: entry. path = '%s', kernel %d\n", path, kernel));
|
FUNCTION(("fs_unmount(path '%s', dev %ld, kernel %d\n", path, mountID,
|
||||||
|
kernel));
|
||||||
|
|
||||||
if (path != NULL) {
|
if (path != NULL) {
|
||||||
err = path_to_vnode(path, true, &vnode, NULL, kernel);
|
err = path_to_vnode(path, true, &vnode, NULL, kernel);
|
||||||
@@ -5826,9 +5827,11 @@ fs_unmount(char *path, dev_t mountID, uint32 flags, bool kernel)
|
|||||||
|
|
||||||
RecursiveLocker mountOpLocker(sMountOpLock);
|
RecursiveLocker mountOpLocker(sMountOpLock);
|
||||||
|
|
||||||
mount = find_mount(vnode->device);
|
mount = find_mount(path != NULL ? vnode->device : mountID);
|
||||||
if (!mount)
|
if (mount == NULL) {
|
||||||
panic("vfs_unmount: find_mount() failed on root vnode @%p of mount\n", vnode);
|
panic("fs_unmount: find_mount() failed on root vnode @%p of mount\n",
|
||||||
|
vnode);
|
||||||
|
}
|
||||||
|
|
||||||
if (path != NULL) {
|
if (path != NULL) {
|
||||||
put_vnode(vnode);
|
put_vnode(vnode);
|
||||||
@@ -5845,6 +5848,10 @@ fs_unmount(char *path, dev_t mountID, uint32 flags, bool kernel)
|
|||||||
KPartition *partition = mount->partition;
|
KPartition *partition = mount->partition;
|
||||||
KDiskDevice *diskDevice = NULL;
|
KDiskDevice *diskDevice = NULL;
|
||||||
if (partition) {
|
if (partition) {
|
||||||
|
if (partition->Device() == NULL) {
|
||||||
|
dprintf("fs_unmount(): There is no device!\n");
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
diskDevice = ddm->WriteLockDevice(partition->Device()->ID());
|
diskDevice = ddm->WriteLockDevice(partition->Device()->ID());
|
||||||
if (!diskDevice) {
|
if (!diskDevice) {
|
||||||
TRACE(("fs_unmount(): Failed to lock disk device!\n"));
|
TRACE(("fs_unmount(): Failed to lock disk device!\n"));
|
||||||
@@ -5873,7 +5880,8 @@ fs_unmount(char *path, dev_t mountID, uint32 flags, bool kernel)
|
|||||||
// cycle through the list of vnodes associated with this mount and
|
// cycle through the list of vnodes associated with this mount and
|
||||||
// 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
|
||||||
vnode = NULL;
|
vnode = NULL;
|
||||||
while ((vnode = (struct vnode *)list_get_next_item(&mount->vnodes, vnode)) != NULL) {
|
while ((vnode = (struct vnode *)list_get_next_item(&mount->vnodes,
|
||||||
|
vnode)) != NULL) {
|
||||||
// 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->busy
|
if (vnode->busy
|
||||||
@@ -5947,7 +5955,8 @@ fs_unmount(char *path, dev_t mountID, uint32 flags, bool kernel)
|
|||||||
// Free all vnodes associated with this mount.
|
// Free all vnodes associated with this mount.
|
||||||
// They will be removed from the mount list by free_vnode(), so
|
// They will be removed from the mount list by free_vnode(), so
|
||||||
// we don't have to do this.
|
// we don't have to do this.
|
||||||
while ((vnode = (struct vnode *)list_get_first_item(&mount->vnodes)) != NULL) {
|
while ((vnode = (struct vnode *)list_get_first_item(&mount->vnodes))
|
||||||
|
!= NULL) {
|
||||||
free_vnode(vnode, false);
|
free_vnode(vnode, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user