axeld + bonefish: Missed those changes in the previous commit:

* Added vfs_unmount(), which allows unmounting by dev_t (used by the DDM).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22910 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2007-11-12 20:54:17 +00:00
parent b3a5629b9e
commit 6e122bd99e
2 changed files with 33 additions and 15 deletions
+3
View File
@@ -26,6 +26,8 @@
#define DEFAULT_NODE_MONITORS 4096
#define MAX_NODE_MONITORS 65536
#define B_UNMOUNT_BUSY_PARTITION 0x80000000
struct kernel_args;
struct vm_cache;
struct file_descriptor;
@@ -107,6 +109,7 @@ status_t vfs_stat_vnode(struct vnode *vnode, struct stat *stat);
status_t vfs_get_vnode_name(struct vnode *vnode, char *name, size_t nameSize);
status_t vfs_get_cwd(dev_t *_mountID, ino_t *_vnodeID);
void vfs_unlock_vnode_if_locked(struct file_descriptor *descriptor);
status_t vfs_unmount(dev_t mountID, uint32 flags);
status_t vfs_disconnect_vnode(dev_t mountID, ino_t vnodeID);
void vfs_free_unused_vnodes(int32 level);
+30 -15
View File
@@ -244,6 +244,9 @@ static status_t fd_and_path_to_vnode(int fd, char *path, bool traverseLeafLink,
static void inc_vnode_ref_count(struct vnode *vnode);
static status_t dec_vnode_ref_count(struct vnode *vnode, bool reenter);
static inline void put_vnode(struct vnode *vnode);
static status_t fs_unmount(char *path, dev_t mountID, uint32 flags,
bool kernel);
static struct fd_ops sFileOps = {
file_read,
@@ -3338,6 +3341,13 @@ vfs_get_cwd(dev_t *_mountID, ino_t *_vnodeID)
}
status_t
vfs_unmount(dev_t mountID, uint32 flags)
{
return fs_unmount(NULL, mountID, flags, true);
}
extern "C" status_t
vfs_disconnect_vnode(dev_t mountID, ino_t vnodeID)
{
@@ -5800,7 +5810,7 @@ err1:
static status_t
fs_unmount(char *path, uint32 flags, bool kernel)
fs_unmount(char *path, dev_t mountID, uint32 flags, bool kernel)
{
struct fs_mount *mount;
struct vnode *vnode;
@@ -5808,9 +5818,11 @@ fs_unmount(char *path, uint32 flags, bool kernel)
FUNCTION(("vfs_unmount: entry. path = '%s', kernel %d\n", path, kernel));
err = path_to_vnode(path, true, &vnode, NULL, kernel);
if (err < 0)
return B_ENTRY_NOT_FOUND;
if (path != NULL) {
err = path_to_vnode(path, true, &vnode, NULL, kernel);
if (err != B_OK)
return B_ENTRY_NOT_FOUND;
}
RecursiveLocker mountOpLocker(sMountOpLock);
@@ -5818,10 +5830,13 @@ fs_unmount(char *path, uint32 flags, bool kernel)
if (!mount)
panic("vfs_unmount: find_mount() failed on root vnode @%p of mount\n", vnode);
if (mount->root_vnode != vnode) {
// not mountpoint
if (path != NULL) {
put_vnode(vnode);
return B_BAD_VALUE;
if (mount->root_vnode != vnode) {
// not mountpoint
return B_BAD_VALUE;
}
}
// if the volume is associated with a partition, lock the device of the
@@ -5840,7 +5855,7 @@ fs_unmount(char *path, uint32 flags, bool kernel)
// make sure, that the partition is not busy
if (partition) {
if (partition->IsBusy()) {
if ((flags & B_UNMOUNT_BUSY_PARTITION) == 0 && partition->IsBusy()) {
TRACE(("fs_unmount(): Partition is busy.\n"));
return B_BUSY;
}
@@ -5859,11 +5874,11 @@ fs_unmount(char *path, uint32 flags, bool kernel)
// make sure all of them are not busy or have refs on them
vnode = NULL;
while ((vnode = (struct vnode *)list_get_next_item(&mount->vnodes, vnode)) != NULL) {
// The root vnode ref_count needs to be 2 here: one for the file
// system, one from the path_to_vnode() call above
// The root vnode ref_count needs to be 1 here (the mount has a
// reference).
if (vnode->busy
|| ((vnode->ref_count != 0 && mount->root_vnode != vnode)
|| (vnode->ref_count != 2 && mount->root_vnode == vnode))) {
|| (vnode->ref_count != 1 && mount->root_vnode == vnode))) {
// there are still vnodes in use on this mount, so we cannot
// unmount yet
busy = true;
@@ -5919,8 +5934,8 @@ fs_unmount(char *path, uint32 flags, bool kernel)
}
}
// The ref_count of the root node is 2 at this point, see above why this is
mount->root_vnode->ref_count -= 2;
// The ref_count of the root node is 1 at this point, see above why this is
mount->root_vnode->ref_count--;
mutex_unlock(&sVnodeMutex);
@@ -6197,7 +6212,7 @@ _kern_unmount(const char *path, uint32 flags)
if (pathBuffer.InitCheck() != B_OK)
return B_NO_MEMORY;
return fs_unmount(pathBuffer.LockBuffer(), flags, true);
return fs_unmount(pathBuffer.LockBuffer(), -1, flags, true);
}
@@ -6908,7 +6923,7 @@ _user_unmount(const char *userPath, uint32 flags)
if (user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK)
return B_BAD_ADDRESS;
return fs_unmount(path, flags, false);
return fs_unmount(path, -1, flags & ~B_UNMOUNT_BUSY_PARTITION, false);
}