aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2024-04-09 22:48:53 -0400
committerIan Moffett <ian@osmora.org>2024-04-09 22:48:53 -0400
commite326f77a5441abbacd23b8309a59e744999779ca (patch)
treea3d65aa32971f8ab42789e26db7725f3ac7a75a2
parent0103817eb5b580d769e793c8bef053eb077fa0be (diff)
kernel: vfs_mount: Fix mount code
Signed-off-by: Ian Moffett <ian@osmora.org>
-rw-r--r--sys/include/sys/mount.h6
-rw-r--r--sys/kern/vfs_init.c3
-rw-r--r--sys/kern/vfs_mount.c31
3 files changed, 30 insertions, 10 deletions
diff --git a/sys/include/sys/mount.h b/sys/include/sys/mount.h
index 209fa3e..a9478e7 100644
--- a/sys/include/sys/mount.h
+++ b/sys/include/sys/mount.h
@@ -47,13 +47,15 @@ struct vfsops {
struct mount {
int flags;
size_t phash; /* Path hash */
- struct vnode *vnode;
+ struct fs_info *fs;
TAILQ_ENTRY(mount) link;
};
struct fs_info {
char name[FS_NAME_MAX]; /* Filesystem type name */
struct vfsops *vfsops; /* Filesystem operations */
+ struct vops *vops; /* Vops for our vnode */
+ struct vnode *vnode; /* Vnode for this filesystem */
struct mount *mp_root;
uint16_t caps;
};
@@ -69,7 +71,7 @@ struct fs_info {
#define MNT_RDONLY 0x00000001
#if defined(_KERNEL)
-int vfs_mount(const char *path, int mntflags);
+int vfs_mount(const char *path, int mntflags, struct fs_info *fs);
int vfs_get_mp(const char *path, struct mount **mp);
void vfs_mount_init(void);
#endif /* defined(_KERNEL) */
diff --git a/sys/kern/vfs_init.c b/sys/kern/vfs_init.c
index 0d8d194..9039e6a 100644
--- a/sys/kern/vfs_init.c
+++ b/sys/kern/vfs_init.c
@@ -43,7 +43,7 @@ __KERNEL_META("$Hyra$: vfs.c, Ian Marco Moffett, "
#define INITRAMFS_ID 0
static struct fs_info filesystems[] = {
- [INITRAMFS_ID] = { "initramfs", &g_initramfs_ops }
+ [INITRAMFS_ID] = { "initramfs", &g_initramfs_ops, NULL},
};
struct vnode *g_root_vnode = NULL;
@@ -74,6 +74,7 @@ vfs_init(void)
vfsops = info->vfsops;
__assert(vfsops->init != NULL);
+ __assert(vfs_mount(info->name, 0, info) == 0);
vfsops->init(info);
}
diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c
index 3efd7a7..84985bf 100644
--- a/sys/kern/vfs_mount.c
+++ b/sys/kern/vfs_mount.c
@@ -63,23 +63,32 @@ vfs_create_mp(const char *path, int mntflags, struct mount **mp_out)
/*
* Mount a mountpoint
*
- * @mp: Mountpoint to mount
* @path: Path this mountpoint belongs to
+ * @mntflags: Flags to mount with
+ * @fs: Filesystem to mount
*
* If this mount entry already exists, -EEXIST
* will be returned.
*/
int
-vfs_mount(const char *path, int mntflags)
+vfs_mount(const char *path, int mntflags, struct fs_info *fs)
{
size_t hash;
int status;
struct mountlist_entry *entry;
struct mount *mp;
+ /* Exclude leading slash */
+ if (*path == '/') {
+ ++path;
+ }
+
+ hash = vfs_hash_path(path);
+
if ((status = vfs_create_mp(path, mntflags, &mp)) != 0) {
return status;
}
+
if (hash == -1) {
/* Something is wrong with the path */
return -EINVAL;
@@ -90,13 +99,14 @@ vfs_mount(const char *path, int mntflags)
return -EEXIST;
}
- mp->phash = hash;
- status = vfs_alloc_vnode(&mp->vnode, mp, VDIR);
-
- if (status != 0) {
+ if ((status = vfs_alloc_vnode(&fs->vnode, mp, VDIR)) != 0) {
return status;
}
+ mp->phash = hash;
+ mp->fs = fs;
+ fs->vnode->vops = fs->vops;
+
entry = &mountlist[hash % MOUNTLIST_SIZE];
TAILQ_INSERT_TAIL(&entry->buckets, mp, link);
return 0;
@@ -115,10 +125,17 @@ vfs_mount(const char *path, int mntflags)
int
vfs_get_mp(const char *path, struct mount **mp)
{
- size_t hash = vfs_hash_path(path);
+ size_t hash;
struct mountlist_entry *entry;
struct mount *mount_iter;
+ /* Exclude leading slash */
+ if (*path == '/') {
+ ++path;
+ }
+
+ hash = vfs_hash_path(path);
+
if (hash == 0) {
/* Something is wrong with the path */
return -EINVAL;