From c0c1099e119fa1c039b526666387fa77fa2d509d Mon Sep 17 00:00:00 2001 From: mohrcore Date: Thu, 27 May 2021 18:00:21 +0200 Subject: [PATCH 1/3] Added source support for mount --- include/sys/mount.h | 10 ++++++---- include/sys/syscallargs.h | 1 + include/sys/vfs.h | 2 +- sys/kern/main.c | 6 +++--- sys/kern/syscalls.c | 12 +++++++++++- sys/kern/syscalls.master | 2 +- sys/kern/sysent.h | 2 +- sys/kern/vfs.c | 15 ++++++++------- sys/kern/vfs_syscalls.c | 10 ++++++---- 9 files changed, 38 insertions(+), 22 deletions(-) diff --git a/include/sys/mount.h b/include/sys/mount.h index 71feb8a158..217d9677a0 100644 --- a/include/sys/mount.h +++ b/include/sys/mount.h @@ -71,6 +71,7 @@ typedef struct mount { vfsops_t *mnt_vfsops; /* Filesystem operations */ vfsconf_t *mnt_vfc; /* Link to filesystem info */ vnode_t *mnt_vnodecovered; /* The vnode covered by this mount */ + vnode_t *mnt_source; /* The source of filesystem's underlying data */ refcnt_t mnt_refcnt; /* Reference count */ mtx_t mnt_mtx; @@ -103,11 +104,12 @@ vfsconf_t *vfs_get_by_name(const char *name); /* Allocates and initializes a new mount struct, using filesystem vfc, covering * vnode v. Does not modify v. Does not insert new mount onto the all mounts * list. */ -mount_t *vfs_mount_alloc(vnode_t *v, vfsconf_t *vfc); +mount_t *vfs_mount_alloc(vnode_t *vdst, vnode_t *vsrc, vfsconf_t *vfc); -/* Mount a new instance of the filesystem vfc at the vnode v. Does not support - * remounting. TODO: Additional filesystem-specific arguments. */ -int vfs_domount(vfsconf_t *vfc, vnode_t *v); +/* Mount a new instance of the filesystem vfc at the vnode vdst. Does not + * support remounting. Use vsrc as a source for fs data if not NULL. + *TODO: Additional filesystem-specific arguments. */ +int vfs_domount(vfsconf_t *vfc, vnode_t *vdst, vnode_t *vsrc); #else /* !_KERNEL */ #include diff --git a/include/sys/syscallargs.h b/include/sys/syscallargs.h index 28ad24bd10..9a43c38cff 100644 --- a/include/sys/syscallargs.h +++ b/include/sys/syscallargs.h @@ -78,6 +78,7 @@ typedef struct { } mmap_args_t; typedef struct { + SYSCALLARG(const char *) source; SYSCALLARG(const char *) type; SYSCALLARG(const char *) path; } mount_args_t; diff --git a/include/sys/vfs.h b/include/sys/vfs.h index 91b7d55d4f..724340cef5 100644 --- a/include/sys/vfs.h +++ b/include/sys/vfs.h @@ -105,7 +105,7 @@ int do_futimens(proc_t *p, int fd, timespec_t *times); int do_utimensat(proc_t *p, int fd, char *path, timespec_t *times, int flag); /* Mount a new instance of the filesystem named fs at the requested path. */ -int do_mount(proc_t *p, const char *fs, const char *path); +int do_mount(proc_t *p, const char *source, const char *fs, const char *path); int do_getdents(proc_t *p, int fd, uio_t *uio); int do_statvfs(proc_t *p, char *path, statvfs_t *buf); int do_fstatvfs(proc_t *p, int fd, statvfs_t *buf); diff --git a/sys/kern/main.c b/sys/kern/main.c index 9e667bc8a6..b43eaa511c 100644 --- a/sys/kern/main.c +++ b/sys/kern/main.c @@ -33,9 +33,9 @@ userspace init program. */ static void mount_fs(void) { proc_t *p = &proc0; - do_mount(p, "initrd", "/"); - do_mount(p, "devfs", "/dev"); - do_mount(p, "tmpfs", "/tmp"); + do_mount(p, NULL, "initrd", "/"); + do_mount(p, NULL, "devfs", "/dev"); + do_mount(p, NULL, "tmpfs", "/tmp"); do_fchmodat(p, AT_FDCWD, "/tmp", ACCESSPERMS | S_ISTXT, 0); } diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c index 8939ffcf7a..71bc5b59eb 100644 --- a/sys/kern/syscalls.c +++ b/sys/kern/syscalls.c @@ -335,9 +335,11 @@ static int sys_getcwd(proc_t *p, getcwd_args_t *args, register_t *res) { static int sys_mount(proc_t *p, mount_args_t *args, register_t *res) { const char *u_type = SCARG(args, type); const char *u_path = SCARG(args, path); + const char *u_source = SCARG(args, source); char *type = kmalloc(M_TEMP, PATH_MAX, 0); char *path = kmalloc(M_TEMP, PATH_MAX, 0); + char *source = NULL; size_t n = 0; int error; @@ -348,13 +350,21 @@ static int sys_mount(proc_t *p, mount_args_t *args, register_t *res) { /* Copyout pathname. */ if ((error = copyinstr(u_path, path, PATH_MAX, &n))) goto end; + /* Alloc and copyout source pathanme */ + if (u_source) { + source = kmalloc(M_TEMP, PATH_MAX, 0); + if ((error = copyinstr(u_source, source, PATH_MAX, &n))) + goto end; + } klog("mount(\"%s\", \"%s\")", path, type); - error = do_mount(p, type, path); + error = do_mount(p, source, type, path); end: kfree(M_TEMP, type); kfree(M_TEMP, path); + if (u_source) + kfree(M_TEMP, source); return error; } diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 6eaa152e38..18b93165bb 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -23,7 +23,7 @@ 12 { void *sys_sbrk(intptr_t increment); } 13 { void *sys_mmap(void *addr, size_t len, int prot, int flags, \ int fd, off_t pos); } -14 { int sys_mount(const char *type, const char *path); } +14 { int sys_mount(const char *source, const char *type, const char *path); } 15 { int sys_getdents(int fd, void *buf, size_t len); } 16 { int sys_dup(int fd); } 17 { int sys_dup2(int from, int to); } diff --git a/sys/kern/sysent.h b/sys/kern/sysent.h index d370e999be..6774828d71 100644 --- a/sys/kern/sysent.h +++ b/sys/kern/sysent.h @@ -107,7 +107,7 @@ struct sysent sysent[] = { [SYS_fstat] = { .nargs = 2, .call = (syscall_t *)sys_fstat }, [SYS_sbrk] = { .nargs = 1, .call = (syscall_t *)sys_sbrk }, [SYS_mmap] = { .nargs = 6, .call = (syscall_t *)sys_mmap }, - [SYS_mount] = { .nargs = 2, .call = (syscall_t *)sys_mount }, + [SYS_mount] = { .nargs = 3, .call = (syscall_t *)sys_mount }, [SYS_getdents] = { .nargs = 3, .call = (syscall_t *)sys_getdents }, [SYS_dup] = { .nargs = 1, .call = (syscall_t *)sys_dup }, [SYS_dup2] = { .nargs = 2, .call = (syscall_t *)sys_dup2 }, diff --git a/sys/kern/vfs.c b/sys/kern/vfs.c index 5983ba1a57..b655a74e1d 100644 --- a/sys/kern/vfs.c +++ b/sys/kern/vfs.c @@ -115,7 +115,7 @@ static int vfs_default_init(vfsconf_t *vfc) { return 0; } -mount_t *vfs_mount_alloc(vnode_t *v, vfsconf_t *vfc) { +mount_t *vfs_mount_alloc(vnode_t *vdst, vnode_t *vsrc, vfsconf_t *vfc) { mount_t *m = kmalloc(M_VFS, sizeof(mount_t), M_ZERO); m->mnt_vfc = vfc; @@ -123,7 +123,8 @@ mount_t *vfs_mount_alloc(vnode_t *v, vfsconf_t *vfc) { vfc->vfc_mountcnt++; /* TODO: vfc_mtx? */ m->mnt_data = NULL; - m->mnt_vnodecovered = v; + m->mnt_vnodecovered = vdst; + m->mnt_source = vsrc; m->mnt_refcnt = 0; mtx_init(&m->mnt_mtx, 0); @@ -131,24 +132,24 @@ mount_t *vfs_mount_alloc(vnode_t *v, vfsconf_t *vfc) { return m; } -int vfs_domount(vfsconf_t *vfc, vnode_t *v) { +int vfs_domount(vfsconf_t *vfc, vnode_t *vdst, vnode_t *vsrc) { int error; /* Start by checking whether this vnode can be used for mounting */ - if (v->v_type != V_DIR) + if (vdst->v_type != V_DIR) return ENOTDIR; - if (is_mountpoint(v)) + if (is_mountpoint(vdst)) return EBUSY; /* TODO: Mark the vnode is in-progress of mounting? See VI_MOUNT in FreeBSD */ - mount_t *m = vfs_mount_alloc(v, vfc); + mount_t *m = vfs_mount_alloc(vdst, vsrc, vfc); /* Mount the filesystem. */ if ((error = VFS_MOUNT(m))) return error; - v->v_mountedhere = m; + vdst->v_mountedhere = m; WITH_MTX_LOCK (&mount_list_mtx) TAILQ_INSERT_TAIL(&mount_list, m, mnt_list); diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 3c05767133..b9fa972d60 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -214,17 +214,19 @@ int do_fstatat(proc_t *p, int fd, char *path, stat_t *sb, int flag) { return error; } -int do_mount(proc_t *p, const char *fs, const char *path) { +int do_mount(proc_t *p, const char *source, const char *fs, const char *path) { vfsconf_t *vfs; - vnode_t *v; + vnode_t *vdest, *vsource = NULL; int error; if (!(vfs = vfs_get_by_name(fs))) return EINVAL; - if ((error = vfs_namelookup(path, &v, &p->p_cred))) + if ((error = vfs_namelookup(path, &vdest, &p->p_cred))) + return error; + if (source && (error = vfs_namelookup(source, &vsource, &p->p_cred))) return error; - return vfs_domount(vfs, v); + return vfs_domount(vfs, vdest, vsource); } int do_getdents(proc_t *p, int fd, uio_t *uio) { From 92917de71d5381d8dc5419922f3fa78a0c78d6e5 Mon Sep 17 00:00:00 2001 From: mohrcore Date: Fri, 28 May 2021 00:27:06 +0200 Subject: [PATCH 2/3] Updated a comment --- include/sys/mount.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/sys/mount.h b/include/sys/mount.h index 217d9677a0..7b0723046b 100644 --- a/include/sys/mount.h +++ b/include/sys/mount.h @@ -102,8 +102,8 @@ extern vnode_t *vfs_root_vnode; vfsconf_t *vfs_get_by_name(const char *name); /* Allocates and initializes a new mount struct, using filesystem vfc, covering - * vnode v. Does not modify v. Does not insert new mount onto the all mounts - * list. */ + * vnode vdst. Does not modify vdst. Does not insert new mount onto the all + * mounts list. vsrc is a vnode used to read the filesystem if not NULL */ mount_t *vfs_mount_alloc(vnode_t *vdst, vnode_t *vsrc, vfsconf_t *vfc); /* Mount a new instance of the filesystem vfc at the vnode vdst. Does not From 89f452c7349bab7751b5ca4e71e6062a570423fe Mon Sep 17 00:00:00 2001 From: mohrcore Date: Sun, 30 May 2021 17:53:26 +0200 Subject: [PATCH 3/3] source is no longe part of mount_t and is passed explicitely to vfs_mount --- include/sys/mount.h | 13 ++++++------- sys/kern/devfs.c | 2 +- sys/kern/initrd.c | 2 +- sys/kern/tmpfs.c | 2 +- sys/kern/vfs.c | 9 ++++----- 5 files changed, 13 insertions(+), 15 deletions(-) diff --git a/include/sys/mount.h b/include/sys/mount.h index 7b0723046b..0115b0ef21 100644 --- a/include/sys/mount.h +++ b/include/sys/mount.h @@ -34,7 +34,7 @@ typedef struct vfsconf vfsconf_t; typedef struct statvfs statvfs_t; /* VFS operations */ -typedef int vfs_mount_t(mount_t *m); +typedef int vfs_mount_t(mount_t *m, vnode_t *vsrc); typedef int vfs_root_t(mount_t *m, vnode_t **vp); typedef int vfs_statvfs_t(mount_t *m, statvfs_t *sb); typedef int vfs_vget_t(mount_t *m, ino_t ino, vnode_t **vp); @@ -71,7 +71,6 @@ typedef struct mount { vfsops_t *mnt_vfsops; /* Filesystem operations */ vfsconf_t *mnt_vfc; /* Link to filesystem info */ vnode_t *mnt_vnodecovered; /* The vnode covered by this mount */ - vnode_t *mnt_source; /* The source of filesystem's underlying data */ refcnt_t mnt_refcnt; /* Reference count */ mtx_t mnt_mtx; @@ -79,8 +78,8 @@ typedef struct mount { void *mnt_data; /* Filesystem-specific arbitrary data */ } mount_t; -static inline int VFS_MOUNT(mount_t *m) { - return m->mnt_vfsops->vfs_mount(m); +static inline int VFS_MOUNT(mount_t *m, vnode_t *vsrc) { + return m->mnt_vfsops->vfs_mount(m, vsrc); } static inline int VFS_ROOT(mount_t *m, vnode_t **vp) { @@ -102,9 +101,9 @@ extern vnode_t *vfs_root_vnode; vfsconf_t *vfs_get_by_name(const char *name); /* Allocates and initializes a new mount struct, using filesystem vfc, covering - * vnode vdst. Does not modify vdst. Does not insert new mount onto the all - * mounts list. vsrc is a vnode used to read the filesystem if not NULL */ -mount_t *vfs_mount_alloc(vnode_t *vdst, vnode_t *vsrc, vfsconf_t *vfc); + * vnode v. Does not modify v. Does not insert new mount onto the all mounts + * list. */ +mount_t *vfs_mount_alloc(vnode_t *v, vfsconf_t *vfc); /* Mount a new instance of the filesystem vfc at the vnode vdst. Does not * support remounting. Use vsrc as a source for fs data if not NULL. diff --git a/sys/kern/devfs.c b/sys/kern/devfs.c index a968fd438b..0274ba4c8f 100644 --- a/sys/kern/devfs.c +++ b/sys/kern/devfs.c @@ -345,7 +345,7 @@ static vnodeops_t devfs_dir_vnodeops = { /* We are using a single vnode for each devfs_node * instead of allocating a new one each time, to simplify things. */ -static int devfs_mount(mount_t *m) { +static int devfs_mount(mount_t *m, vnode_t *vsrc) { devfs.root->dn_vnode->v_mount = m; m->mnt_data = &devfs; return 0; diff --git a/sys/kern/initrd.c b/sys/kern/initrd.c index 524bde5512..7755e89a20 100644 --- a/sys/kern/initrd.c +++ b/sys/kern/initrd.c @@ -330,7 +330,7 @@ static int initrd_root(mount_t *m, vnode_t **v) { return 0; } -static int initrd_mount(mount_t *m) { +static int initrd_mount(mount_t *m, vnode_t *vsrc) { vnode_t *root = vnode_new(V_DIR, &initrd_vops, root_node); root->v_mount = m; root_node->c_vnode = root; diff --git a/sys/kern/tmpfs.c b/sys/kern/tmpfs.c index ac8f9927b6..621cd00901 100644 --- a/sys/kern/tmpfs.c +++ b/sys/kern/tmpfs.c @@ -1029,7 +1029,7 @@ static void tmpfs_update_time(tmpfs_node_t *v, tmpfs_time_type_t type) { /* tmpfs vfs operations */ -static int tmpfs_mount(mount_t *mp) { +static int tmpfs_mount(mount_t *mp, vnode_t *vsrc) { /* Allocate the tmpfs mount structure and fill it. */ tmpfs_mount_t *tfm = &tmpfs; diff --git a/sys/kern/vfs.c b/sys/kern/vfs.c index b655a74e1d..c056537d48 100644 --- a/sys/kern/vfs.c +++ b/sys/kern/vfs.c @@ -115,7 +115,7 @@ static int vfs_default_init(vfsconf_t *vfc) { return 0; } -mount_t *vfs_mount_alloc(vnode_t *vdst, vnode_t *vsrc, vfsconf_t *vfc) { +mount_t *vfs_mount_alloc(vnode_t *v, vfsconf_t *vfc) { mount_t *m = kmalloc(M_VFS, sizeof(mount_t), M_ZERO); m->mnt_vfc = vfc; @@ -123,8 +123,7 @@ mount_t *vfs_mount_alloc(vnode_t *vdst, vnode_t *vsrc, vfsconf_t *vfc) { vfc->vfc_mountcnt++; /* TODO: vfc_mtx? */ m->mnt_data = NULL; - m->mnt_vnodecovered = vdst; - m->mnt_source = vsrc; + m->mnt_vnodecovered = v; m->mnt_refcnt = 0; mtx_init(&m->mnt_mtx, 0); @@ -143,10 +142,10 @@ int vfs_domount(vfsconf_t *vfc, vnode_t *vdst, vnode_t *vsrc) { /* TODO: Mark the vnode is in-progress of mounting? See VI_MOUNT in FreeBSD */ - mount_t *m = vfs_mount_alloc(vdst, vsrc, vfc); + mount_t *m = vfs_mount_alloc(vdst, vfc); /* Mount the filesystem. */ - if ((error = VFS_MOUNT(m))) + if ((error = VFS_MOUNT(m, vsrc))) return error; vdst->v_mountedhere = m;