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:
@@ -26,6 +26,8 @@
|
|||||||
#define DEFAULT_NODE_MONITORS 4096
|
#define DEFAULT_NODE_MONITORS 4096
|
||||||
#define MAX_NODE_MONITORS 65536
|
#define MAX_NODE_MONITORS 65536
|
||||||
|
|
||||||
|
#define B_UNMOUNT_BUSY_PARTITION 0x80000000
|
||||||
|
|
||||||
struct kernel_args;
|
struct kernel_args;
|
||||||
struct vm_cache;
|
struct vm_cache;
|
||||||
struct file_descriptor;
|
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_vnode_name(struct vnode *vnode, char *name, size_t nameSize);
|
||||||
status_t vfs_get_cwd(dev_t *_mountID, ino_t *_vnodeID);
|
status_t vfs_get_cwd(dev_t *_mountID, ino_t *_vnodeID);
|
||||||
void vfs_unlock_vnode_if_locked(struct file_descriptor *descriptor);
|
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);
|
status_t vfs_disconnect_vnode(dev_t mountID, ino_t vnodeID);
|
||||||
void vfs_free_unused_vnodes(int32 level);
|
void vfs_free_unused_vnodes(int32 level);
|
||||||
|
|
||||||
|
|||||||
@@ -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 void inc_vnode_ref_count(struct vnode *vnode);
|
||||||
static status_t dec_vnode_ref_count(struct vnode *vnode, bool reenter);
|
static status_t dec_vnode_ref_count(struct vnode *vnode, bool reenter);
|
||||||
static inline void put_vnode(struct vnode *vnode);
|
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 = {
|
static struct fd_ops sFileOps = {
|
||||||
file_read,
|
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
|
extern "C" status_t
|
||||||
vfs_disconnect_vnode(dev_t mountID, ino_t vnodeID)
|
vfs_disconnect_vnode(dev_t mountID, ino_t vnodeID)
|
||||||
{
|
{
|
||||||
@@ -5800,7 +5810,7 @@ err1:
|
|||||||
|
|
||||||
|
|
||||||
static status_t
|
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 fs_mount *mount;
|
||||||
struct vnode *vnode;
|
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));
|
FUNCTION(("vfs_unmount: entry. path = '%s', kernel %d\n", path, kernel));
|
||||||
|
|
||||||
|
if (path != NULL) {
|
||||||
err = path_to_vnode(path, true, &vnode, NULL, kernel);
|
err = path_to_vnode(path, true, &vnode, NULL, kernel);
|
||||||
if (err < 0)
|
if (err != B_OK)
|
||||||
return B_ENTRY_NOT_FOUND;
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
RecursiveLocker mountOpLocker(sMountOpLock);
|
RecursiveLocker mountOpLocker(sMountOpLock);
|
||||||
|
|
||||||
@@ -5818,11 +5830,14 @@ fs_unmount(char *path, uint32 flags, bool kernel)
|
|||||||
if (!mount)
|
if (!mount)
|
||||||
panic("vfs_unmount: find_mount() failed on root vnode @%p of mount\n", vnode);
|
panic("vfs_unmount: find_mount() failed on root vnode @%p of mount\n", vnode);
|
||||||
|
|
||||||
|
if (path != NULL) {
|
||||||
|
put_vnode(vnode);
|
||||||
|
|
||||||
if (mount->root_vnode != vnode) {
|
if (mount->root_vnode != vnode) {
|
||||||
// not mountpoint
|
// not mountpoint
|
||||||
put_vnode(vnode);
|
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// if the volume is associated with a partition, lock the device of the
|
// if the volume is associated with a partition, lock the device of the
|
||||||
// partition as long as we are unmounting
|
// partition as long as we are unmounting
|
||||||
@@ -5840,7 +5855,7 @@ fs_unmount(char *path, uint32 flags, bool kernel)
|
|||||||
|
|
||||||
// make sure, that the partition is not busy
|
// make sure, that the partition is not busy
|
||||||
if (partition) {
|
if (partition) {
|
||||||
if (partition->IsBusy()) {
|
if ((flags & B_UNMOUNT_BUSY_PARTITION) == 0 && partition->IsBusy()) {
|
||||||
TRACE(("fs_unmount(): Partition is busy.\n"));
|
TRACE(("fs_unmount(): Partition is busy.\n"));
|
||||||
return B_BUSY;
|
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
|
// 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 2 here: one for the file
|
// The root vnode ref_count needs to be 1 here (the mount has a
|
||||||
// system, one from the path_to_vnode() call above
|
// reference).
|
||||||
if (vnode->busy
|
if (vnode->busy
|
||||||
|| ((vnode->ref_count != 0 && mount->root_vnode != vnode)
|
|| ((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
|
// there are still vnodes in use on this mount, so we cannot
|
||||||
// unmount yet
|
// unmount yet
|
||||||
busy = true;
|
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
|
// The ref_count of the root node is 1 at this point, see above why this is
|
||||||
mount->root_vnode->ref_count -= 2;
|
mount->root_vnode->ref_count--;
|
||||||
|
|
||||||
mutex_unlock(&sVnodeMutex);
|
mutex_unlock(&sVnodeMutex);
|
||||||
|
|
||||||
@@ -6197,7 +6212,7 @@ _kern_unmount(const char *path, uint32 flags)
|
|||||||
if (pathBuffer.InitCheck() != B_OK)
|
if (pathBuffer.InitCheck() != B_OK)
|
||||||
return B_NO_MEMORY;
|
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)
|
if (user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK)
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
return fs_unmount(path, flags, false);
|
return fs_unmount(path, -1, flags & ~B_UNMOUNT_BUSY_PARTITION, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user