* 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:
Axel Dörfler 2008-10-17 15:44:13 +00:00
parent 2bb834901c
commit 703aecaaa5

View File

@ -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;
} }