Replaced fs_mount::covers_vnode by Vnode::covers

Introduce a Vnode::covers field. It is currently only used for the root
node of an fs_mount, replacing fs_mount::covers_vnode.
This commit is contained in:
Ingo Weinhold
2011-11-25 06:17:42 +01:00
parent 7bb72b8daf
commit 02be66ca10
2 changed files with 35 additions and 32 deletions
+1
View File
@@ -28,6 +28,7 @@ struct vnode : fs_vnode, DoublyLinkedListLinkImpl<vnode> {
VMCache* cache; VMCache* cache;
struct fs_mount* mount; struct fs_mount* mount;
struct vnode* covered_by; struct vnode* covered_by;
struct vnode* covers;
struct advisory_locking* advisory_locking; struct advisory_locking* advisory_locking;
struct file_descriptor* mandatory_locked_by; struct file_descriptor* mandatory_locked_by;
list_link unused_link; list_link unused_link;
+34 -32
View File
@@ -121,15 +121,15 @@ 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 root_vnode->covers fields (what others?) are
initialized in fs_mount() and not changed afterwards. That is as soon initialized in fs_mount() and not changed afterwards. That is as soon
as the mount is mounted and it is made sure it won't be unmounted as the mount is mounted and it is made sure it won't be unmounted
(e.g. by holding a reference to a vnode of that mount) (read) access (e.g. by holding a reference to a vnode of that mount) (read) access
to those fields is always safe, even without additional locking. Morever to those fields is always safe, even without additional locking. Morever
while mounted the mount holds a reference to the covers_vnode, and thus while mounted the mount holds a reference to the root_vnode->covers vnode,
making the access path vnode->mount->covers_vnode->mount->... safe if a and thus making the access path vnode->mount->root_vnode->covers->mount->...
reference to vnode is held (note that for the root mount covers_vnode safe if a reference to vnode is held (note that for the root mount
is NULL, though). root_vnode->covers is NULL, though).
*/ */
struct fs_mount { struct fs_mount {
fs_mount() fs_mount()
@@ -164,7 +164,6 @@ struct fs_mount {
recursive_lock rlock; // guards the vnodes list recursive_lock rlock; // guards the vnodes list
// TODO: Make this a mutex! It is never used recursively. // TODO: Make this a mutex! It is never used recursively.
struct vnode* root_vnode; struct vnode* root_vnode;
struct vnode* covers_vnode;
KPartition* partition; KPartition* partition;
VnodeList vnodes; VnodeList vnodes;
EntryCache entry_cache; EntryCache entry_cache;
@@ -1737,7 +1736,7 @@ replace_vnode_if_disconnected(struct fs_mount* mount,
if (vnode == mount->root_vnode) { if (vnode == mount->root_vnode) {
// redirect the vnode to the covered vnode // redirect the vnode to the covered vnode
vnode = mount->covers_vnode; vnode = mount->root_vnode->covers;
} else } else
vnode = fallBack; vnode = fallBack;
@@ -1933,8 +1932,8 @@ resolve_volume_root_to_mount_point(struct vnode* vnode)
struct vnode* mountPoint = NULL; struct vnode* mountPoint = NULL;
struct fs_mount* mount = vnode->mount; struct fs_mount* mount = vnode->mount;
if (vnode == mount->root_vnode && mount->covers_vnode) { if (vnode == mount->root_vnode && mount->root_vnode->covers != NULL) {
mountPoint = mount->covers_vnode; mountPoint = mount->root_vnode->covers;
inc_vnode_ref_count(mountPoint); inc_vnode_ref_count(mountPoint);
} }
@@ -2119,8 +2118,8 @@ vnode_path_to_vnode(struct vnode* vnode, char* path, bool traverseLeafLink,
path = nextPath; path = nextPath;
continue; continue;
} else if (vnode->mount->root_vnode == vnode } else if (vnode->mount->root_vnode == vnode
&& vnode->mount->covers_vnode) { && vnode->mount->root_vnode->covers != NULL) {
nextVnode = vnode->mount->covers_vnode; nextVnode = vnode->mount->root_vnode->covers;
inc_vnode_ref_count(nextVnode); inc_vnode_ref_count(nextVnode);
put_vnode(vnode); put_vnode(vnode);
vnode = nextVnode; vnode = nextVnode;
@@ -2427,8 +2426,8 @@ get_vnode_name(struct vnode* vnode, struct vnode* parent, struct dirent* buffer,
// vnode so we get the underlying file system // vnode so we get the underlying file system
VNodePutter vnodePutter; VNodePutter vnodePutter;
if (vnode->mount->root_vnode == vnode if (vnode->mount->root_vnode == vnode
&& vnode->mount->covers_vnode != NULL) { && vnode->mount->root_vnode->covers != NULL) {
vnode = vnode->mount->covers_vnode; vnode = vnode->mount->root_vnode->covers;
inc_vnode_ref_count(vnode); inc_vnode_ref_count(vnode);
vnodePutter.SetTo(vnode); vnodePutter.SetTo(vnode);
} }
@@ -2938,7 +2937,7 @@ _dump_mount(struct fs_mount* mount)
kprintf(" id: %ld\n", mount->id); kprintf(" id: %ld\n", mount->id);
kprintf(" device_name: %s\n", mount->device_name); kprintf(" device_name: %s\n", mount->device_name);
kprintf(" root_vnode: %p\n", mount->root_vnode); kprintf(" root_vnode: %p\n", mount->root_vnode);
kprintf(" covers_vnode: %p\n", mount->covers_vnode); kprintf(" covers: %p\n", mount->root_vnode->covers);
kprintf(" partition: %p\n", mount->partition); kprintf(" partition: %p\n", mount->partition);
kprintf(" lock: %p\n", &mount->rlock); kprintf(" lock: %p\n", &mount->rlock);
kprintf(" flags: %s%s\n", mount->unmounting ? " unmounting" : "", kprintf(" flags: %s%s\n", mount->unmounting ? " unmounting" : "",
@@ -2957,7 +2956,7 @@ _dump_mount(struct fs_mount* mount)
set_debug_variable("_volume", (addr_t)mount->volume->private_volume); set_debug_variable("_volume", (addr_t)mount->volume->private_volume);
set_debug_variable("_root", (addr_t)mount->root_vnode); set_debug_variable("_root", (addr_t)mount->root_vnode);
set_debug_variable("_covers", (addr_t)mount->covers_vnode); set_debug_variable("_covers", (addr_t)mount->root_vnode->covers);
set_debug_variable("_partition", (addr_t)mount->partition); set_debug_variable("_partition", (addr_t)mount->partition);
} }
@@ -3018,8 +3017,8 @@ debug_resolve_vnode_path(struct vnode* vnode, char* buffer, size_t bufferSize,
while (true) { while (true) {
while (vnode->mount->root_vnode == vnode while (vnode->mount->root_vnode == vnode
&& vnode->mount->covers_vnode != NULL) { && vnode->mount->root_vnode->covers != NULL) {
vnode = vnode->mount->covers_vnode; vnode = vnode->mount->root_vnode->covers;
} }
if (vnode == sRoot) { if (vnode == sRoot) {
@@ -3146,7 +3145,7 @@ dump_mounts(int argc, char** argv)
while ((mount = (struct fs_mount*)hash_next(sMountsTable, &iterator)) while ((mount = (struct fs_mount*)hash_next(sMountsTable, &iterator))
!= NULL) { != NULL) {
kprintf("%p%4ld %p %p %p %s\n", mount, mount->id, mount->root_vnode, kprintf("%p%4ld %p %p %p %s\n", mount, mount->id, mount->root_vnode,
mount->covers_vnode, mount->volume->private_volume, mount->root_vnode->covers, mount->volume->private_volume,
mount->volume->file_system_name); mount->volume->file_system_name);
fs_volume* volume = mount->volume; fs_volume* volume = mount->volume;
@@ -5675,7 +5674,7 @@ fix_dirent(struct vnode* parent, struct dirent* entry,
// we need to replace d_dev and d_ino with the actual values. // we need to replace d_dev and d_ino with the actual values.
if (strcmp(entry->d_name, "..") == 0 if (strcmp(entry->d_name, "..") == 0
&& parent->mount->root_vnode == parent && parent->mount->root_vnode == parent
&& parent->mount->covers_vnode) { && parent->mount->root_vnode->covers != NULL) {
inc_vnode_ref_count(parent); inc_vnode_ref_count(parent);
// vnode_path_to_vnode() puts the node // vnode_path_to_vnode() puts the node
@@ -6978,6 +6977,7 @@ fs_mount(char* path, const char* device, const char* fsName, uint32 flags,
status_t status = B_OK; status_t status = B_OK;
fs_volume* volume = NULL; fs_volume* volume = NULL;
int32 layer = 0; int32 layer = 0;
Vnode* coveredNode = NULL;
FUNCTION(("fs_mount: entry. path = '%s', fs_name = '%s'\n", path, fsName)); FUNCTION(("fs_mount: entry. path = '%s', fs_name = '%s'\n", path, fsName));
@@ -7105,7 +7105,6 @@ fs_mount(char* path, const char* device, const char* fsName, uint32 flags,
mount->id = sNextMountID++; mount->id = sNextMountID++;
mount->partition = NULL; mount->partition = NULL;
mount->root_vnode = NULL; mount->root_vnode = NULL;
mount->covers_vnode = NULL;
mount->unmounting = false; mount->unmounting = false;
mount->owns_file_device = false; mount->owns_file_device = false;
mount->volume = NULL; mount->volume = NULL;
@@ -7185,17 +7184,17 @@ fs_mount(char* path, const char* device, const char* fsName, uint32 flags,
if (status != 0) if (status != 0)
goto err2; goto err2;
} else { } else {
status = path_to_vnode(path, true, &mount->covers_vnode, NULL, kernel); status = path_to_vnode(path, true, &coveredNode, NULL, kernel);
if (status != B_OK) if (status != B_OK)
goto err2; goto err2;
// make sure covered_vnode is a directory // make sure covered_vnode is a directory
if (!S_ISDIR(mount->covers_vnode->Type())) { if (!S_ISDIR(coveredNode->Type())) {
status = B_NOT_A_DIRECTORY; status = B_NOT_A_DIRECTORY;
goto err3; goto err3;
} }
if (mount->covers_vnode->mount->root_vnode == mount->covers_vnode) { if (coveredNode->mount->root_vnode == coveredNode) {
// this is already a mount point // this is already a mount point
status = B_BUSY; status = B_BUSY;
goto err3; goto err3;
@@ -7233,10 +7232,12 @@ fs_mount(char* path, const char* device, const char* fsName, uint32 flags,
} }
// No race here, since fs_mount() is the only function changing // No race here, since fs_mount() is the only function changing
// covers_vnode (and holds sMountOpLock at that time). // root_vnode->covers (and holds sMountOpLock at that time).
rw_lock_write_lock(&sVnodeLock); rw_lock_write_lock(&sVnodeLock);
if (mount->covers_vnode) if (coveredNode != NULL) {
mount->covers_vnode->covered_by = mount->root_vnode; mount->root_vnode->covers = coveredNode;
coveredNode->covered_by = mount->root_vnode;
}
rw_lock_write_unlock(&sVnodeLock); rw_lock_write_unlock(&sVnodeLock);
if (!sRoot) { if (!sRoot) {
@@ -7260,16 +7261,16 @@ fs_mount(char* path, const char* device, const char* fsName, uint32 flags,
} }
notify_mount(mount->id, notify_mount(mount->id,
mount->covers_vnode ? mount->covers_vnode->device : -1, coveredNode != NULL ? coveredNode->device : -1,
mount->covers_vnode ? mount->covers_vnode->id : -1); coveredNode ? coveredNode->id : -1);
return mount->id; return mount->id;
err4: err4:
FS_MOUNT_CALL_NO_PARAMS(mount, unmount); FS_MOUNT_CALL_NO_PARAMS(mount, unmount);
err3: err3:
if (mount->covers_vnode != NULL) if (coveredNode != NULL)
put_vnode(mount->covers_vnode); put_vnode(coveredNode);
err2: err2:
mutex_lock(&sMountMutex); mutex_lock(&sMountMutex);
hash_remove(sMountsTable, mount); hash_remove(sMountsTable, mount);
@@ -7413,11 +7414,12 @@ fs_unmount(char* path, dev_t mountID, uint32 flags, bool kernel)
mount->root_vnode->ref_count--; mount->root_vnode->ref_count--;
vnode_to_be_freed(mount->root_vnode); vnode_to_be_freed(mount->root_vnode);
mount->covers_vnode->covered_by = NULL; Vnode* coveredNode = mount->root_vnode->covers;
coveredNode->covered_by = NULL;
vnodesWriteLocker.Unlock(); vnodesWriteLocker.Unlock();
put_vnode(mount->covers_vnode); put_vnode(coveredNode);
// 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