Turns out we could remove a mount point...
Under BeOS remove_vnode() is failing in this case, which looks like a good idea to imitate. Also, pipefs/rootfs didn't handle that case - they even removed the entry before calling remove_vnode() - they now behave correctly. And also BFS now returns the actual error code received from remove_vnode() instead of B_ERROR. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14456 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -2043,8 +2043,9 @@ Inode::Remove(Transaction &transaction, const char *name, off_t *_id, bool isDir
|
|||||||
}
|
}
|
||||||
|
|
||||||
// remove_vnode() allows the inode to be accessed until the last put_vnode()
|
// remove_vnode() allows the inode to be accessed until the last put_vnode()
|
||||||
if (remove_vnode(fVolume->ID(), id) != B_OK)
|
status = remove_vnode(fVolume->ID(), id);
|
||||||
return B_ERROR;
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
if (tree->Remove(transaction, name, id) < B_OK) {
|
if (tree->Remove(transaction, name, id) < B_OK) {
|
||||||
unremove_vnode(fVolume->ID(), id);
|
unremove_vnode(fVolume->ID(), id);
|
||||||
|
|||||||
@@ -513,12 +513,14 @@ Volume::RemoveNode(Inode *directory, const char *name)
|
|||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
// schedule this vnode to be removed when it's ref goes to zero
|
||||||
|
status = remove_vnode(ID(), inode->ID());
|
||||||
|
if (status < B_OK)
|
||||||
|
goto err;
|
||||||
|
|
||||||
RemoveNode(inode);
|
RemoveNode(inode);
|
||||||
notify_entry_removed(ID(), directory->ID(), name, inode->ID());
|
notify_entry_removed(ID(), directory->ID(), name, inode->ID());
|
||||||
|
|
||||||
// schedule this vnode to be removed when it's ref goes to zero
|
|
||||||
remove_vnode(ID(), inode->ID());
|
|
||||||
|
|
||||||
err:
|
err:
|
||||||
Unlock();
|
Unlock();
|
||||||
|
|
||||||
|
|||||||
@@ -257,11 +257,15 @@ rootfs_is_dir_empty(struct rootfs_vnode *dir)
|
|||||||
static status_t
|
static status_t
|
||||||
remove_node(struct rootfs *fs, struct rootfs_vnode *directory, struct rootfs_vnode *vnode)
|
remove_node(struct rootfs *fs, struct rootfs_vnode *directory, struct rootfs_vnode *vnode)
|
||||||
{
|
{
|
||||||
|
// schedule this vnode to be removed when it's ref goes to zero
|
||||||
|
status_t status = remove_vnode(fs->id, vnode->id);
|
||||||
|
if (status < B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
rootfs_remove_from_dir(fs, directory, vnode);
|
rootfs_remove_from_dir(fs, directory, vnode);
|
||||||
notify_entry_removed(fs->id, directory->id, vnode->name, vnode->id);
|
notify_entry_removed(fs->id, directory->id, vnode->name, vnode->id);
|
||||||
|
|
||||||
// schedule this vnode to be removed when it's ref goes to zero
|
return B_OK;
|
||||||
return remove_vnode(fs->id, vnode->id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -286,7 +290,7 @@ rootfs_remove(struct rootfs *fs, struct rootfs_vnode *dir, const char *name, boo
|
|||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
remove_node(fs, dir, vnode);
|
status = remove_node(fs, dir, vnode);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
mutex_unlock(&fs->lock);
|
mutex_unlock(&fs->lock);
|
||||||
@@ -481,14 +485,14 @@ rootfs_remove_vnode(fs_volume _fs, fs_vnode _vnode, bool reenter)
|
|||||||
struct rootfs *fs = (struct rootfs *)_fs;
|
struct rootfs *fs = (struct rootfs *)_fs;
|
||||||
struct rootfs_vnode *vnode = (struct rootfs_vnode *)_vnode;
|
struct rootfs_vnode *vnode = (struct rootfs_vnode *)_vnode;
|
||||||
|
|
||||||
TRACE(("rootfs_removevnode: remove %p (0x%Lx), r %d\n", vnode, vnode->id, reenter));
|
TRACE(("rootfs_remove_vnode: remove %p (0x%Lx), r %d\n", vnode, vnode->id, reenter));
|
||||||
|
|
||||||
if (!reenter)
|
if (!reenter)
|
||||||
mutex_lock(&fs->lock);
|
mutex_lock(&fs->lock);
|
||||||
|
|
||||||
if (vnode->dir_next) {
|
if (vnode->dir_next) {
|
||||||
// can't remove node if it's linked to the dir
|
// can't remove node if it's linked to the dir
|
||||||
panic("rootfs_removevnode: vnode %p asked to be removed is present in dir\n", vnode);
|
panic("rootfs_remove_vnode: vnode %p asked to be removed is present in dir\n", vnode);
|
||||||
}
|
}
|
||||||
|
|
||||||
rootfs_delete_vnode(fs, vnode, false);
|
rootfs_delete_vnode(fs, vnode, false);
|
||||||
|
|||||||
@@ -2342,6 +2342,12 @@ remove_vnode(mount_id mountID, vnode_id vnodeID)
|
|||||||
|
|
||||||
vnode = lookup_vnode(mountID, vnodeID);
|
vnode = lookup_vnode(mountID, vnodeID);
|
||||||
if (vnode != NULL) {
|
if (vnode != NULL) {
|
||||||
|
if (vnode->covered_by != NULL) {
|
||||||
|
// this vnode is in use
|
||||||
|
mutex_unlock(&sVnodeMutex);
|
||||||
|
return B_BUSY;
|
||||||
|
}
|
||||||
|
|
||||||
vnode->remove = true;
|
vnode->remove = true;
|
||||||
if (vnode->unpublished) {
|
if (vnode->unpublished) {
|
||||||
// prepare the vnode for deletion
|
// prepare the vnode for deletion
|
||||||
|
|||||||
Reference in New Issue
Block a user