* Instead of having the mount_link, struct vnode now subclasses from
DoublyLinkedListLinkImpl, and fs_mount now uses a DoublyLinkedList instead of a typeless struct list. * Also added a constructor/destructor to fs_mount which simplifies and cleans some code. * This should not contain any functional changes :-) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28215 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
2bb834901c
commit
703aecaaa5
@ -264,11 +264,10 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct vnode : fs_vnode {
|
struct vnode : fs_vnode, DoublyLinkedListLinkImpl<vnode> {
|
||||||
struct vnode *next;
|
struct vnode *next;
|
||||||
vm_cache *cache;
|
vm_cache *cache;
|
||||||
dev_t device;
|
dev_t device;
|
||||||
list_link mount_link;
|
|
||||||
list_link unused_link;
|
list_link unused_link;
|
||||||
ino_t id;
|
ino_t id;
|
||||||
struct fs_mount *mount;
|
struct fs_mount *mount;
|
||||||
@ -289,6 +288,8 @@ struct vnode_hash_key {
|
|||||||
ino_t vnode;
|
ino_t vnode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef DoublyLinkedList<vnode> VnodeList;
|
||||||
|
|
||||||
/*! \brief Structure to manage a mounted file system
|
/*! \brief Structure to manage a mounted file system
|
||||||
|
|
||||||
Note: The root_vnode and covers_vnode fields (what others?) are
|
Note: The root_vnode and covers_vnode fields (what others?) are
|
||||||
@ -302,17 +303,34 @@ struct vnode_hash_key {
|
|||||||
is NULL, though).
|
is NULL, though).
|
||||||
*/
|
*/
|
||||||
struct fs_mount {
|
struct fs_mount {
|
||||||
struct fs_mount *next;
|
fs_mount()
|
||||||
file_system_module_info *fs;
|
:
|
||||||
|
volume(NULL),
|
||||||
|
device_name(NULL),
|
||||||
|
fs_name(NULL)
|
||||||
|
{
|
||||||
|
recursive_lock_init(&rlock, "mount rlock");
|
||||||
|
}
|
||||||
|
|
||||||
|
~fs_mount()
|
||||||
|
{
|
||||||
|
recursive_lock_destroy(&rlock);
|
||||||
|
free(device_name);
|
||||||
|
free(fs_name);
|
||||||
|
free(volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct fs_mount* next;
|
||||||
|
file_system_module_info* fs;
|
||||||
dev_t id;
|
dev_t id;
|
||||||
fs_volume *volume;
|
fs_volume* volume;
|
||||||
char *device_name;
|
char* device_name;
|
||||||
char *fs_name;
|
char* fs_name;
|
||||||
recursive_lock rlock; // guards the vnodes list
|
recursive_lock rlock; // guards the vnodes list
|
||||||
struct vnode *root_vnode;
|
struct vnode* root_vnode;
|
||||||
struct vnode *covers_vnode;
|
struct vnode* covers_vnode;
|
||||||
KPartition *partition;
|
KPartition* partition;
|
||||||
struct list vnodes;
|
VnodeList vnodes;
|
||||||
EntryCache entry_cache;
|
EntryCache entry_cache;
|
||||||
bool unmounting;
|
bool unmounting;
|
||||||
bool owns_file_device;
|
bool owns_file_device;
|
||||||
@ -947,23 +965,16 @@ vnode_hash(void *_vnode, const void *_key, uint32 range)
|
|||||||
static void
|
static void
|
||||||
add_vnode_to_mount_list(struct vnode *vnode, struct fs_mount *mount)
|
add_vnode_to_mount_list(struct vnode *vnode, struct fs_mount *mount)
|
||||||
{
|
{
|
||||||
recursive_lock_lock(&mount->rlock);
|
RecursiveLocker _(mount->rlock);
|
||||||
|
mount->vnodes.Add(vnode);
|
||||||
list_add_link_to_head(&mount->vnodes, &vnode->mount_link);
|
|
||||||
|
|
||||||
recursive_lock_unlock(&mount->rlock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
remove_vnode_from_mount_list(struct vnode *vnode, struct fs_mount *mount)
|
remove_vnode_from_mount_list(struct vnode *vnode, struct fs_mount *mount)
|
||||||
{
|
{
|
||||||
recursive_lock_lock(&mount->rlock);
|
RecursiveLocker _(mount->rlock);
|
||||||
|
mount->vnodes.Remove(vnode);
|
||||||
list_remove_link(&vnode->mount_link);
|
|
||||||
vnode->mount_link.next = vnode->mount_link.prev = NULL;
|
|
||||||
|
|
||||||
recursive_lock_unlock(&mount->rlock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -6666,10 +6677,10 @@ query_rewind(struct file_descriptor *descriptor)
|
|||||||
|
|
||||||
|
|
||||||
static dev_t
|
static dev_t
|
||||||
fs_mount(char *path, const char *device, const char *fsName, uint32 flags,
|
fs_mount(char* path, const char* device, const char* fsName, uint32 flags,
|
||||||
const char *args, bool kernel)
|
const char* args, bool kernel)
|
||||||
{
|
{
|
||||||
struct fs_mount *mount;
|
struct fs_mount* mount;
|
||||||
status_t status = 0;
|
status_t status = 0;
|
||||||
|
|
||||||
FUNCTION(("fs_mount: entry. path = '%s', fs_name = '%s'\n", path, fsName));
|
FUNCTION(("fs_mount: entry. path = '%s', fs_name = '%s'\n", path, fsName));
|
||||||
@ -6784,18 +6795,16 @@ fs_mount(char *path, const char *device, const char *fsName, uint32 flags,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mount = (struct fs_mount *)malloc(sizeof(struct fs_mount));
|
mount = new(std::nothrow) struct ::fs_mount;
|
||||||
if (mount == NULL)
|
if (mount == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
mount->volume = (fs_volume*)malloc(sizeof(fs_volume));
|
mount->volume = (fs_volume*)malloc(sizeof(fs_volume));
|
||||||
if (mount->volume == NULL) {
|
if (mount->volume == NULL) {
|
||||||
free(mount);
|
delete mount;
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
list_init_etc(&mount->vnodes, offsetof(struct vnode, mount_link));
|
|
||||||
|
|
||||||
mount->fs_name = get_file_system_name(fsName);
|
mount->fs_name = get_file_system_name(fsName);
|
||||||
if (mount->fs_name == NULL) {
|
if (mount->fs_name == NULL) {
|
||||||
status = B_NO_MEMORY;
|
status = B_NO_MEMORY;
|
||||||
@ -6815,8 +6824,6 @@ fs_mount(char *path, const char *device, const char *fsName, uint32 flags,
|
|||||||
goto err3;
|
goto err3;
|
||||||
}
|
}
|
||||||
|
|
||||||
recursive_lock_init(&mount->rlock, "mount rlock");
|
|
||||||
|
|
||||||
// initialize structure
|
// initialize structure
|
||||||
mount->id = sNextMountID++;
|
mount->id = sNextMountID++;
|
||||||
mount->partition = NULL;
|
mount->partition = NULL;
|
||||||
@ -6931,16 +6938,12 @@ err5:
|
|||||||
hash_remove(sMountsTable, mount);
|
hash_remove(sMountsTable, mount);
|
||||||
mutex_unlock(&sMountMutex);
|
mutex_unlock(&sMountMutex);
|
||||||
|
|
||||||
recursive_lock_destroy(&mount->rlock);
|
|
||||||
put_file_system(mount->fs);
|
put_file_system(mount->fs);
|
||||||
free(mount->device_name);
|
|
||||||
err3:
|
err3:
|
||||||
mount->entry_cache.Uninit();
|
mount->entry_cache.Uninit();
|
||||||
err2:
|
err2:
|
||||||
free(mount->fs_name);
|
|
||||||
err1:
|
err1:
|
||||||
free(mount->volume);
|
delete mount;
|
||||||
free(mount);
|
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -7021,8 +7024,10 @@ 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,
|
VnodeList::Iterator iterator = mount->vnodes.GetIterator();
|
||||||
vnode)) != NULL) {
|
while (iterator.HasNext()) {
|
||||||
|
vnode = iterator.Next();
|
||||||
|
|
||||||
// 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
|
||||||
@ -7072,7 +7077,9 @@ fs_unmount(char *path, dev_t mountID, uint32 flags, bool kernel)
|
|||||||
// structure in unmounting state
|
// structure in unmounting state
|
||||||
mount->unmounting = true;
|
mount->unmounting = true;
|
||||||
|
|
||||||
while ((vnode = (struct vnode *)list_get_next_item(&mount->vnodes, vnode)) != NULL) {
|
VnodeList::Iterator iterator = mount->vnodes.GetIterator();
|
||||||
|
while (iterator.HasNext()) {
|
||||||
|
vnode = iterator.Next();
|
||||||
vnode->busy = true;
|
vnode->busy = true;
|
||||||
|
|
||||||
if (vnode->ref_count == 0) {
|
if (vnode->ref_count == 0) {
|
||||||
@ -7095,8 +7102,7 @@ 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))
|
while ((vnode = mount->vnodes.RemoveHead()) != NULL) {
|
||||||
!= NULL) {
|
|
||||||
free_vnode(vnode, false);
|
free_vnode(vnode, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7124,11 +7130,7 @@ fs_unmount(char *path, dev_t mountID, uint32 flags, bool kernel)
|
|||||||
}
|
}
|
||||||
|
|
||||||
mount->entry_cache.Uninit();
|
mount->entry_cache.Uninit();
|
||||||
|
delete mount;
|
||||||
free(mount->device_name);
|
|
||||||
free(mount->fs_name);
|
|
||||||
free(mount->volume);
|
|
||||||
free(mount);
|
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@ -7155,23 +7157,22 @@ fs_sync(dev_t device)
|
|||||||
|
|
||||||
struct vnode *vnode;
|
struct vnode *vnode;
|
||||||
if (!marker.remove) {
|
if (!marker.remove) {
|
||||||
vnode = (struct vnode *)list_get_next_item(&mount->vnodes, &marker);
|
vnode = mount->vnodes.GetNext(&marker);
|
||||||
list_remove_item(&mount->vnodes, &marker);
|
mount->vnodes.Remove(&marker);
|
||||||
marker.remove = true;
|
marker.remove = true;
|
||||||
} else
|
} else
|
||||||
vnode = (struct vnode *)list_get_first_item(&mount->vnodes);
|
vnode = mount->vnodes.First();
|
||||||
|
|
||||||
while (vnode != NULL && (vnode->cache == NULL
|
while (vnode != NULL && (vnode->cache == NULL
|
||||||
|| vnode->remove || vnode->busy)) {
|
|| vnode->remove || vnode->busy)) {
|
||||||
// TODO: we could track writes (and writable mapped vnodes)
|
// TODO: we could track writes (and writable mapped vnodes)
|
||||||
// and have a simple flag that we could test for here
|
// and have a simple flag that we could test for here
|
||||||
vnode = (struct vnode *)list_get_next_item(&mount->vnodes, vnode);
|
vnode = mount->vnodes.GetNext(vnode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vnode != NULL) {
|
if (vnode != NULL) {
|
||||||
// insert marker vnode again
|
// insert marker vnode again
|
||||||
list_insert_item_before(&mount->vnodes,
|
mount->vnodes.Insert(mount->vnodes.GetNext(vnode), &marker);
|
||||||
list_get_next_item(&mount->vnodes, vnode), &marker);
|
|
||||||
marker.remove = false;
|
marker.remove = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user