diff options
-rw-r--r-- | sys/include/sys/mount.h | 6 | ||||
-rw-r--r-- | sys/kern/vfs_init.c | 3 | ||||
-rw-r--r-- | sys/kern/vfs_mount.c | 31 |
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; |