diff --git a/sys/amd64/amd64/autoconf.c b/sys/amd64/amd64/autoconf.c index 96e9a05823a3..36e43dbb40bb 100644 --- a/sys/amd64/amd64/autoconf.c +++ b/sys/amd64/amd64/autoconf.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)autoconf.c 7.1 (Berkeley) 5/9/91 - * $Id: autoconf.c,v 1.33 1995/05/30 07:59:14 rgrimes Exp $ + * $Id: autoconf.c,v 1.34 1995/07/16 10:45:04 phk Exp $ */ /* @@ -53,6 +53,7 @@ #include #include #include +#include /* mountrootvfsops, struct vfsops*/ #include #include @@ -66,9 +67,12 @@ static void setroot(void); */ int dkn; /* number of iostat dk numbers assigned so far */ -extern int (*mountroot) __P((void)); +int vfs_mountroot __P((caddr_t)); /* XXX goes away*/ #ifdef FFS -int ffs_mountroot __P((void)); +extern struct vfsops ufs_vfsops; +#endif +#ifdef LFS +extern struct vfsops lfs_vfsops; #endif #ifdef NFS int nfs_mountroot __P((void)); @@ -181,7 +185,7 @@ configure() configure_finish(); #ifdef MFS_ROOT - mfs_initminiroot(mfs_root); + mfs_initminiroot(mfs_root); /* XXX UGLY*/ #endif /* MFS_ROOT */ #ifdef CD9660 @@ -196,7 +200,24 @@ configure() #ifdef FFS if (!mountroot) { - mountroot = ffs_mountroot; + mountroot = vfs_mountroot; /* XXX goes away*/ + mountrootvfsops = &ufs_vfsops; + /* + * Ignore the -a flag if this kernel isn't compiled + * with a generic root/swap configuration: if we skip + * setroot() and we aren't a generic kernel, chaos + * will ensue because setconf() will be a no-op. + * (rootdev is always initialized to NODEV in a + * generic configuration, so we test for that.) + */ + if ((boothowto & RB_ASKNAME) == 0 || rootdev != NODEV) + setroot(); + } +#endif +#ifdef LFS + if (!mountroot) { + mountroot = vfs_mountroot; /* XXX goes away*/ + mountrootvfsops = &lfs_vfsops; /* * Ignore the -a flag if this kernel isn't compiled * with a generic root/swap configuration: if we skip diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index 6394f254e9e2..5618983127f7 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 - * $Id: machdep.c,v 1.135 1995/07/29 11:38:52 bde Exp $ + * $Id: machdep.c,v 1.136 1995/08/20 04:41:02 davidg Exp $ */ #include "npx.h" @@ -126,6 +126,15 @@ #include #include +/* + * System initialization + */ + +static void cpu_startup __P(( caddr_t)); + +SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL) + + static void identifycpu(void); static void initcpu(void); @@ -187,8 +196,10 @@ extern struct linker_set netisr_set; #define offsetof(type, member) ((size_t)(&((type *)0)->member)) -void -cpu_startup() +/* ARGSUSED*/ +static void +cpu_startup( udata) +caddr_t udata; /* not used*/ { register unsigned i; register caddr_t v; diff --git a/sys/compat/linux/linux_stats.c b/sys/compat/linux/linux_stats.c index 1dbfcf11e64b..95839e0c97a1 100644 --- a/sys/compat/linux/linux_stats.c +++ b/sys/compat/linux/linux_stats.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: linux_stats.c,v 1.3 1995/06/08 13:50:52 sos Exp $ + * $Id: linux_stats.c,v 1.1 1995/06/25 17:32:42 sos Exp $ */ #include @@ -206,12 +206,7 @@ linux_statfs(struct proc *p, struct linux_statfs_args *args, int *retval) printf("Linux-emul(%d): statfs(%s, *)\n", p->p_pid, args->path); #endif ndp = &nd; - ndp->ni_cnd.cn_nameiop = LOOKUP; - ndp->ni_cnd.cn_flags = FOLLOW; - ndp->ni_cnd.cn_proc = curproc; - ndp->ni_cnd.cn_cred = curproc->p_cred->pc_ucred; - ndp->ni_segflg = UIO_USERSPACE; - ndp->ni_dirp = args->path; + NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args->path, curproc); if (error = namei(ndp)) return error; mp = ndp->ni_vp->v_mount; diff --git a/sys/i386/i386/autoconf.c b/sys/i386/i386/autoconf.c index 96e9a05823a3..36e43dbb40bb 100644 --- a/sys/i386/i386/autoconf.c +++ b/sys/i386/i386/autoconf.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)autoconf.c 7.1 (Berkeley) 5/9/91 - * $Id: autoconf.c,v 1.33 1995/05/30 07:59:14 rgrimes Exp $ + * $Id: autoconf.c,v 1.34 1995/07/16 10:45:04 phk Exp $ */ /* @@ -53,6 +53,7 @@ #include #include #include +#include /* mountrootvfsops, struct vfsops*/ #include #include @@ -66,9 +67,12 @@ static void setroot(void); */ int dkn; /* number of iostat dk numbers assigned so far */ -extern int (*mountroot) __P((void)); +int vfs_mountroot __P((caddr_t)); /* XXX goes away*/ #ifdef FFS -int ffs_mountroot __P((void)); +extern struct vfsops ufs_vfsops; +#endif +#ifdef LFS +extern struct vfsops lfs_vfsops; #endif #ifdef NFS int nfs_mountroot __P((void)); @@ -181,7 +185,7 @@ configure() configure_finish(); #ifdef MFS_ROOT - mfs_initminiroot(mfs_root); + mfs_initminiroot(mfs_root); /* XXX UGLY*/ #endif /* MFS_ROOT */ #ifdef CD9660 @@ -196,7 +200,24 @@ configure() #ifdef FFS if (!mountroot) { - mountroot = ffs_mountroot; + mountroot = vfs_mountroot; /* XXX goes away*/ + mountrootvfsops = &ufs_vfsops; + /* + * Ignore the -a flag if this kernel isn't compiled + * with a generic root/swap configuration: if we skip + * setroot() and we aren't a generic kernel, chaos + * will ensue because setconf() will be a no-op. + * (rootdev is always initialized to NODEV in a + * generic configuration, so we test for that.) + */ + if ((boothowto & RB_ASKNAME) == 0 || rootdev != NODEV) + setroot(); + } +#endif +#ifdef LFS + if (!mountroot) { + mountroot = vfs_mountroot; /* XXX goes away*/ + mountrootvfsops = &lfs_vfsops; /* * Ignore the -a flag if this kernel isn't compiled * with a generic root/swap configuration: if we skip diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index 6394f254e9e2..5618983127f7 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 - * $Id: machdep.c,v 1.135 1995/07/29 11:38:52 bde Exp $ + * $Id: machdep.c,v 1.136 1995/08/20 04:41:02 davidg Exp $ */ #include "npx.h" @@ -126,6 +126,15 @@ #include #include +/* + * System initialization + */ + +static void cpu_startup __P(( caddr_t)); + +SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL) + + static void identifycpu(void); static void initcpu(void); @@ -187,8 +196,10 @@ extern struct linker_set netisr_set; #define offsetof(type, member) ((size_t)(&((type *)0)->member)) -void -cpu_startup() +/* ARGSUSED*/ +static void +cpu_startup( udata) +caddr_t udata; /* not used*/ { register unsigned i; register caddr_t v; diff --git a/sys/i386/ibcs2/ibcs2_stats.c b/sys/i386/ibcs2/ibcs2_stats.c index eee1ef4ca155..4a8a80ca8059 100644 --- a/sys/i386/ibcs2/ibcs2_stats.c +++ b/sys/i386/ibcs2/ibcs2_stats.c @@ -35,7 +35,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: ibcs2_stats.c,v 1.1 1994/10/14 08:53:09 sos Exp $ + * $Id: ibcs2_stats.c,v 1.2 1995/05/30 08:00:11 rgrimes Exp $ */ #include @@ -103,12 +103,8 @@ ibcs2_stat(struct proc *p, struct ibcs2_stat_args *args, int *retval) if (ibcs2_trace & IBCS2_TRACE_STATS) printf("IBCS2: 'stat' path=%s\n", args->path); - nd.ni_cnd.cn_nameiop = LOOKUP; - nd.ni_cnd.cn_flags = LOCKLEAF | FOLLOW; - nd.ni_cnd.cn_proc = curproc; - nd.ni_cnd.cn_cred = curproc->p_cred->pc_ucred; - nd.ni_segflg = UIO_USERSPACE; - nd.ni_dirp = args->path; + /* XXX use of 'curproc' should be 'p'?*/ + NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, args->path, curproc); error = namei(&nd); if (!error) { @@ -132,12 +128,9 @@ ibcs2_lstat(struct proc *p, struct ibcs2_stat_args *args, int *retval) if (ibcs2_trace & IBCS2_TRACE_STATS) printf("IBCS2: 'lstat' path=%s\n", args->path); - nd.ni_cnd.cn_nameiop = LOOKUP; - nd.ni_cnd.cn_flags = LOCKLEAF | FOLLOW; - nd.ni_cnd.cn_proc = curproc; - nd.ni_cnd.cn_cred = curproc->p_cred->pc_ucred; - nd.ni_segflg = UIO_USERSPACE; - nd.ni_dirp = args->path; + + /* XXX use of 'curproc' should be 'p'?*/ + NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, args->path, curproc); error = namei(&nd); if (!error) { @@ -222,12 +215,8 @@ ibcs2_statfs(struct proc *p, struct ibcs2_statfs_args *args, int *retval) if (ibcs2_trace & IBCS2_TRACE_STATS) printf("IBCS2: 'statfs' path=%s\n", args->path); ndp = &nd; - ndp->ni_cnd.cn_nameiop = LOOKUP; - ndp->ni_cnd.cn_flags = FOLLOW; - ndp->ni_cnd.cn_proc = curproc; - ndp->ni_cnd.cn_cred = curproc->p_cred->pc_ucred; - ndp->ni_segflg = UIO_USERSPACE; - ndp->ni_dirp = args->path; + /* XXX use of 'curproc' should be 'p'?*/ + NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args->path, curproc); if (error = namei(ndp)) return error; mp = ndp->ni_vp->v_mount; diff --git a/sys/i386/ibcs2/imgact_coff.c b/sys/i386/ibcs2/imgact_coff.c index 14accfb26abf..b866d1db7d7b 100644 --- a/sys/i386/ibcs2/imgact_coff.c +++ b/sys/i386/ibcs2/imgact_coff.c @@ -26,7 +26,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: imgact_coff.c,v 1.4 1995/05/30 08:00:17 rgrimes Exp $ + * $Id: imgact_coff.c,v 1.5 1995/08/24 10:30:36 davidg Exp $ */ #include @@ -163,12 +163,8 @@ coff_load_file(struct proc *p, char *name) unsigned long bss_size = 0; int i; - nd.ni_cnd.cn_nameiop = LOOKUP; - nd.ni_cnd.cn_flags = LOCKLEAF | FOLLOW | SAVENAME; - nd.ni_cnd.cn_proc = curproc; - nd.ni_cnd.cn_cred = curproc->p_cred->pc_ucred; - nd.ni_segflg = UIO_SYSSPACE; - nd.ni_dirp = name; + /* XXX use of 'curproc' should be 'p'?*/ + NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW | SAVENAME, UIO_SYSSPACE, name, curproc); error = namei(&nd); if (error) diff --git a/sys/i386/linux/linux_stats.c b/sys/i386/linux/linux_stats.c index 1dbfcf11e64b..95839e0c97a1 100644 --- a/sys/i386/linux/linux_stats.c +++ b/sys/i386/linux/linux_stats.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: linux_stats.c,v 1.3 1995/06/08 13:50:52 sos Exp $ + * $Id: linux_stats.c,v 1.1 1995/06/25 17:32:42 sos Exp $ */ #include @@ -206,12 +206,7 @@ linux_statfs(struct proc *p, struct linux_statfs_args *args, int *retval) printf("Linux-emul(%d): statfs(%s, *)\n", p->p_pid, args->path); #endif ndp = &nd; - ndp->ni_cnd.cn_nameiop = LOOKUP; - ndp->ni_cnd.cn_flags = FOLLOW; - ndp->ni_cnd.cn_proc = curproc; - ndp->ni_cnd.cn_cred = curproc->p_cred->pc_ucred; - ndp->ni_segflg = UIO_USERSPACE; - ndp->ni_dirp = args->path; + NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args->path, curproc); if (error = namei(ndp)) return error; mp = ndp->ni_vp->v_mount; diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index 854b6caa2bad..b38b25a3f4d3 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -1,4 +1,7 @@ /* + * Copyright (c) 1995 Terrence R. Lambert + * All rights reserved. + * * Copyright (c) 1982, 1986, 1989, 1991, 1992, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. @@ -72,13 +75,6 @@ #include #include -#ifdef HPFPLIB -char copyright[] = -"Copyright (c) 1982, 1986, 1989, 1991, 1993\n\tThe Regents of the University of California.\nCopyright (c) 1992 Hewlett-Packard Company\nCopyright (c) 1992 Motorola Inc.\nAll rights reserved.\n\n"; -#else -char copyright[] = -"Copyright (c) 1982, 1986, 1989, 1991, 1993\n\tThe Regents of the University of California. All rights reserved.\n\n"; -#endif /* Components of the first process -- never freed. */ struct session session0; @@ -89,7 +85,7 @@ struct filedesc0 filedesc0; struct plimit limit0; struct vmspace vmspace0; struct proc *curproc = &proc0; -struct proc *initproc, *pageproc, *updateproc, *vmproc; +struct proc *initproc; int cmask = CMASK; extern struct user *proc0paddr; @@ -99,51 +95,212 @@ int boothowto; struct timeval boottime; struct timeval runtime; -static void start_init __P((struct proc *p, void *framep)); +/* + * Promiscuous argument pass for start_init() + * + * This is a kludge because we use a return from main() rather than a call + * to a new reoutine in locore.s to kick the kernel alive from locore.s. + */ +static void *init_framep; + #if __GNUC__ >= 2 void __main() {} #endif + /* - * This table is filled in by the linker with functions that need to be - * called to initialize various pseudo-devices and whatnot. + * This ensures that there is at least one entry so that the sysinit_set + * symbol is not undefined. A sybsystem ID of SI_SUB_DUMMY is never + * executed. */ +SYSINIT(placeholder, SI_SUB_DUMMY,SI_ORDER_ANY, NULL, NULL) -static void dummyinit() {} -TEXT_SET(pseudo_set, dummyinit); - -typedef void (*pseudo_func_t)(void); -extern const struct linker_set pseudo_set; -static const pseudo_func_t *pseudos = - (const pseudo_func_t *)&pseudo_set.ls_items[0]; /* * System startup; initialize the world, create process 0, mount root * filesystem, and fork to create init and pagedaemon. Most of the * hard work is done in the lower-level initialization routines including * startup(), which does memory initialization and autoconfiguration. + * + * This allows simple addition of new kernel subsystems that require + * boot time initialization. It also allows substitution of subsystem + * (for instance, a scheduler, kernel profiler, or VM system) by object + * module. Finally, it allows for optional "kernel threads", like an LFS + * cleaner. */ void main(framep) void *framep; { - register struct proc *p; - register struct filedesc0 *fdp; + + register struct sysinit **sipp; /* system initialization*/ + register struct sysinit **xipp; /* interior loop of sort*/ + register struct sysinit *save; /* bubble*/ + int rval[2]; /* SI_TYPE_KTHREAD support*/ + + extern struct linker_set sysinit_set; + + /* + * Save the locore.s frame pointer for start_init(). + */ + init_framep = framep; + + /* + * Perform a bubble sort of the system initialization objects by + * their subsystem (primary key) and order (secondary key). + * + * Since some things care about execution order, this is the + * operation which ensures continued function. + */ + for( sipp = (struct sysinit **)sysinit_set.ls_items; *sipp; sipp++) { + for( xipp = sipp + 1; *xipp; xipp++) { + if( (*sipp)->subsystem < (*xipp)->subsystem || + ( (*sipp)->subsystem == (*xipp)->subsystem && + (*sipp)->order < (*xipp)->order)) + continue; /* skip*/ + save = *sipp; + *sipp = *xipp; + *xipp = save; + } + } + + /* + * Traverse the (now) ordered list of system initialization tasks. + * Perform each task, and continue on to the next task. + * + * The last item on the list is expected to be the scheduler, + * which will not return. + */ + for( sipp = (struct sysinit **)sysinit_set.ls_items; *sipp; sipp++) { + if( (*sipp)->subsystem == SI_SUB_DUMMY) + continue; /* skip dummy task(s)*/ + + switch( (*sipp)->type) { + case SI_TYPE_DEFAULT: + /* no special processing*/ + (*((*sipp)->func))( (*sipp)->udata); + break; + + case SI_TYPE_KTHREAD: + /* kernel thread*/ + if (fork(&proc0, NULL, rval)) + panic("fork kernel process"); + if (rval[1]) { + (*((*sipp)->func))( (*sipp)->udata); + /* + * The call to start "init" returns + * here after the scheduler has been + * started, and returns to the caller + * in i386/i386/locore.s. This is a + * necessary part of initialization + * and is rather non-obvious. + * + * No other "kernel threads" should + * return here. Call panic() instead. + */ + return; + } + break; + + default: + panic( "init_main: unrecognized init type"); + } + } + + /* NOTREACHED*/ +} + + +/* + * Start a kernel process. This is called after a fork() call in + * main() in the file kern/init_main.c. + * + * This function is used to start "internal" daemons. + */ +/* ARGSUSED*/ +void +kproc_start( udata) +caddr_t udata; /* not used*/ +{ + struct kproc_desc *kp = (struct kproc_desc *)udata; + struct proc *p = curproc; + + /* save a global descriptor, if desired*/ + if( kp->global_procpp != NULL) + *kp->global_procpp = p; + + /* this is a non-swapped system process*/ + p->p_flag |= P_INMEM | P_SYSTEM; + + /* set up arg0 for 'ps', et al*/ + strcpy( p->p_comm, kp->arg0); + + /* call the processes' main()...*/ + (*kp->func)(); + + /* NOTREACHED */ + panic( "kproc_start: %s", kp->arg0); +} + + +/* + *************************************************************************** + **** + **** The following SYSINIT's belong elsewhere, but have not yet + **** been moved. + **** + *************************************************************************** + */ +#ifdef OMIT +/* + * Handled by vfs_mountroot (bad idea) at this time... should be + * done the same as 4.4Lite2. + */ +SYSINIT(swapinit, SI_SUB_SWAP, SI_ORDER_FIRST, swapinit, NULL) +#endif /* OMIT*/ + +/* + * Should get its own file... + */ +#ifdef HPFPLIB +char copyright[] = +"Copyright (c) 1982, 1986, 1989, 1991, 1993\n\tThe Regents of the University of California.\nCopyright (c) 1992 Hewlett-Packard Company\nCopyright (c) 1992 Motorola Inc.\nAll rights reserved.\n\n"; +#else +char copyright[] = +"Copyright (c) 1982, 1986, 1989, 1991, 1993\n\tThe Regents of the University of California. All rights reserved.\n\n"; +#endif +SYSINIT(announce, SI_SUB_COPYRIGHT, SI_ORDER_FIRST, printf, (caddr_t)copyright) + + +/* + *************************************************************************** + **** + **** The two following SYSINT's are proc0 specific glue code. I am not + **** convinced that they can not be safely combined, but their order of + **** operation has been maintained as the same as the original init_main.c + **** for right now. + **** + **** These probably belong in init_proc.c or kern_proc.c, since they + **** deal with proc0 (the fork template process). + **** + *************************************************************************** + */ +/* ARGSUSED*/ +void +proc0_init( udata) +caddr_t udata; /* not used*/ +{ + register struct proc *p; + register struct filedesc0 *fdp; register int i; - int s, rval[2]; /* * Initialize the current process pointer (curproc) before * any possible traps/probes to simplify trap processing. */ p = &proc0; - curproc = p; - printf(copyright); - - vm_mem_init(); - kmeminit(); - cpu_startup(); + curproc = p; /* XXX redundant*/ /* * Create process 0 (the swapper). @@ -204,13 +361,16 @@ main(framep) vmspace0.vm_map.pmap = &vmspace0.vm_pmap; p->p_addr = proc0paddr; /* XXX */ +#define INCOMPAT_LITES2 +#ifdef INCOMPAT_LITES2 /* * proc0 needs to have a coherent frame base, too. * This probably makes the identical call for the init proc * that happens later unnecessary since it should inherit * it during the fork. */ - cpu_set_init_frame(p, framep); /* XXX! */ + cpu_set_init_frame(p, init_framep); /* XXX! */ +#endif /* INCOMPAT_LITES2*/ /* * We continue to place resource usage info and signal @@ -225,67 +385,66 @@ main(framep) */ usrinfoinit(); (void)chgproccnt(0, 1); +} +SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_FIRST, proc0_init, NULL) - rqinit(); - - /* Configure virtual memory system, set vm rlimits. */ - vm_init_limits(p); - - /* Initialize the file systems. */ - vfsinit(); - - /* Start real time and statistics clocks. */ - initclocks(); - - /* Initialize mbuf's. */ - mbinit(); - - /* Initialize clists. */ - clist_init(); - -#ifdef SYSVSHM - /* Initialize System V style shared memory. */ - shminit(); -#endif - -#ifdef SYSVSEM - /* Initialize System V style semaphores. */ - seminit(); -#endif - -#ifdef SYSVMSG - /* Initialize System V style message queues. */ - msginit(); -#endif - +/* ARGSUSED*/ +void +proc0_post( udata) +caddr_t udata; /* not used*/ +{ /* - * Attach pseudo-devices. + * Now can look at time, having had a chance to verify the time + * from the file system. Reset p->p_rtime as it may have been + * munched in mi_switch() after the time got set. */ - while(*pseudos) { - (**pseudos++)(); - } + proc0.p_stats->p_start = runtime = mono_time = boottime = time; + proc0.p_rtime.tv_sec = proc0.p_rtime.tv_usec = 0; - /* - * Initialize protocols. Block reception of incoming packets - * until everything is ready. - */ - s = splimp(); - ifinit(); - domaininit(); - splx(s); + /* Initialize signal state for process 0. */ + siginit(&proc0); +} +SYSINIT(p0post, SI_SUB_INTRINSIC_POST, SI_ORDER_FIRST, proc0_post, NULL) -#ifdef GPROF - /* Initialize kernel profiling. */ - kmstartup(); -#endif + + +/* + *************************************************************************** + **** + **** The following SYSINIT's and glue code should be moved to the + **** respective files on a per subsystem basis. + **** + *************************************************************************** + */ +/* ARGSUSED*/ +void +sched_setup( udata) +caddr_t udata; /* not used*/ +{ /* Kick off timeout driven events by calling first time. */ roundrobin(NULL); schedcpu(NULL); +} +SYSINIT(sched_setup, SI_SUB_KICK_SCHEDULER, SI_ORDER_FIRST, sched_setup, NULL) +/* ARGSUSED*/ +void +xxx_vfs_mountroot( udata) +caddr_t udata; /* not used*/ +{ /* Mount the root file system. */ - if ((*mountroot)()) + if ((*mountroot)( (caddr_t)mountrootvfsops)) panic("cannot mount root"); +} +SYSINIT(mountroot, SI_SUB_ROOT, SI_ORDER_FIRST, xxx_vfs_mountroot, NULL) + +/* ARGSUSED*/ +void +xxx_vfs_root_fdtab( udata) +caddr_t udata; /* not used*/ +{ + register struct filedesc0 *fdp = &filedesc0; /* Get the vnode for '/'. Set fdp->fd_fd.fd_cdir to reference it. */ if (VFS_ROOT(mountlist.cqh_first, &rootvnode)) @@ -294,74 +453,46 @@ main(framep) VREF(fdp->fd_fd.fd_cdir); VOP_UNLOCK(rootvnode); fdp->fd_fd.fd_rdir = NULL; +} +SYSINIT(retrofit, SI_SUB_ROOT_FDTAB, SI_ORDER_FIRST, xxx_vfs_root_fdtab, NULL) - /* - * Now can look at time, having had a chance to verify the time - * from the file system. Reset p->p_rtime as it may have been - * munched in mi_switch() after the time got set. - */ - p->p_stats->p_start = runtime = mono_time = boottime = time; - p->p_rtime.tv_sec = p->p_rtime.tv_usec = 0; - /* Initialize signal state for process 0. */ - siginit(p); +/* + *************************************************************************** + **** + **** The following code probably belongs in another file, like + **** kern/init_init.c. It is here for two reasons only: + **** + **** 1) This code returns to startup the system; this is + **** abnormal for a kernel thread. + **** 2) This code promiscuously uses init_frame + **** + *************************************************************************** + */ + +static void kthread_init __P(( caddr_t udata)); +SYSINIT_KT(init,SI_SUB_KTHREAD_INIT, SI_ORDER_FIRST, kthread_init, NULL) + + +static void start_init __P((struct proc *p, void *framep)); + +/* ARGSUSED*/ +static void +kthread_init( udata) +caddr_t udata; /* not used*/ +{ /* Create process 1 (init(8)). */ - if (fork(p, NULL, rval)) - panic("fork init"); - if (rval[1]) { - start_init(curproc, framep); - return; - } - - /* Create process 2 (the pageout daemon). */ - if (fork(p, NULL, rval)) - panic("fork pager"); - if (rval[1]) { - /* - * Now in process 2. - */ - p = curproc; - pageproc = p; - p->p_flag |= P_INMEM | P_SYSTEM; /* XXX */ - bcopy("pagedaemon", curproc->p_comm, sizeof ("pagedaemon")); - vm_pageout(); - /* NOTREACHED */ - } + start_init(curproc, init_framep); /* - * Start high level vm daemon (process 3). + * This is the only kernel thread allowed to return yo the + * caller!!! */ - if (fork(p, (void *) NULL, rval)) - panic("failed fork vm daemon"); - if (rval[1]) { - p = curproc; - vmproc = p; - p->p_flag |= P_INMEM | P_SYSTEM; - bcopy("vmdaemon", p->p_comm, sizeof("vmdaemon")); - vm_daemon(); - /*NOTREACHED*/ - } - - /* - * Start update daemon (process 4). - */ - if (fork(p, (void *) NULL, rval)) - panic("failed fork update daemon"); - if (rval[1]) { - p = curproc; - updateproc = p; - p->p_flag |= P_INMEM | P_SYSTEM; - bcopy("update", p->p_comm, sizeof("update")); - vfs_update(); - /*NOTREACHED*/ - } - - /* The scheduler is an infinite loop. */ - scheduler(); - /* NOTREACHED */ + return; } + /* * List of paths to try when searching for "init". */ @@ -459,6 +590,9 @@ start_init(p, framep) /* * Now try to exec the program. If can't for any reason * other than it doesn't exist, complain. + * + * Otherwise return to main() which returns to btext + * which completes the system startup. */ if ((error = execve(p, &args, &retval[0])) == 0) return; diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c index fb686b1100b4..04af42b97927 100644 --- a/sys/kern/kern_clock.c +++ b/sys/kern/kern_clock.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)kern_clock.c 8.5 (Berkeley) 1/21/94 - * $Id: kern_clock.c,v 1.13 1995/05/30 08:05:20 rgrimes Exp $ + * $Id: kern_clock.c,v 1.14 1995/07/29 11:40:12 bde Exp $ */ /* Portions of this software are covered by the following: */ @@ -75,6 +75,14 @@ #include #endif +/* + * System initialization + */ + +static void initclocks __P(( caddr_t udata)); +SYSINIT(clocks, SI_SUB_CLOCKS, SI_ORDER_FIRST, initclocks, NULL) + + /* Does anybody else really care about these? */ struct callout *callfree, *callout, calltodo; @@ -383,8 +391,10 @@ hardupdate(offset) /* * Initialize clock frequencies and start both clocks running. */ -void -initclocks() +/* ARGSUSED*/ +static void +initclocks( udata) +caddr_t udata; /* not used*/ { register int i; diff --git a/sys/kern/kern_malloc.c b/sys/kern/kern_malloc.c index 600e54f6b1ce..52c95c5228ea 100644 --- a/sys/kern/kern_malloc.c +++ b/sys/kern/kern_malloc.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)kern_malloc.c 8.3 (Berkeley) 1/4/94 - * $Id: kern_malloc.c,v 1.11 1995/04/16 11:25:15 davidg Exp $ + * $Id: kern_malloc.c,v 1.12 1995/05/30 08:05:33 rgrimes Exp $ */ #include @@ -43,6 +43,14 @@ #include #include +/* + * System initialization + */ + +static void kmeminit __P((caddr_t)); +SYSINIT(kmem, SI_SUB_KMEM, SI_ORDER_FIRST, kmeminit, NULL) + + struct kmembuckets bucket[MINBUCKET + 16]; struct kmemstats kmemstats[M_LAST]; struct kmemusage *kmemusage; @@ -356,8 +364,10 @@ free(addr, type) /* * Initialize the kernel memory allocator */ -void -kmeminit() +/* ARGSUSED*/ +static void +kmeminit( udata) +caddr_t udata; /* not used*/ { register long indx; int npg; diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index 534e477d303f..6f97a637b4b0 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)kern_synch.c 8.6 (Berkeley) 1/21/94 - * $Id: kern_synch.c,v 1.10 1995/03/16 18:12:36 bde Exp $ + * $Id: kern_synch.c,v 1.11 1995/05/30 08:05:44 rgrimes Exp $ */ #include @@ -54,6 +54,16 @@ #include + +/* + * System initialization + */ + +static void rqinit __P((caddr_t)); +SYSINIT(runqueue, SI_SUB_RUN_QUEUE, SI_ORDER_FIRST, rqinit, NULL) + + + u_char curpriority; /* usrpri of curproc */ int lbolt; /* once a second sleep address */ @@ -602,8 +612,10 @@ mi_switch() * Initialize the (doubly-linked) run queues * to be empty. */ -void -rqinit() +/* ARGSUSED*/ +static void +rqinit( udata) +caddr_t udata; /* not used*/ { register int i; diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c index fb686b1100b4..04af42b97927 100644 --- a/sys/kern/kern_tc.c +++ b/sys/kern/kern_tc.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)kern_clock.c 8.5 (Berkeley) 1/21/94 - * $Id: kern_clock.c,v 1.13 1995/05/30 08:05:20 rgrimes Exp $ + * $Id: kern_clock.c,v 1.14 1995/07/29 11:40:12 bde Exp $ */ /* Portions of this software are covered by the following: */ @@ -75,6 +75,14 @@ #include #endif +/* + * System initialization + */ + +static void initclocks __P(( caddr_t udata)); +SYSINIT(clocks, SI_SUB_CLOCKS, SI_ORDER_FIRST, initclocks, NULL) + + /* Does anybody else really care about these? */ struct callout *callfree, *callout, calltodo; @@ -383,8 +391,10 @@ hardupdate(offset) /* * Initialize clock frequencies and start both clocks running. */ -void -initclocks() +/* ARGSUSED*/ +static void +initclocks( udata) +caddr_t udata; /* not used*/ { register int i; diff --git a/sys/kern/kern_timeout.c b/sys/kern/kern_timeout.c index fb686b1100b4..04af42b97927 100644 --- a/sys/kern/kern_timeout.c +++ b/sys/kern/kern_timeout.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)kern_clock.c 8.5 (Berkeley) 1/21/94 - * $Id: kern_clock.c,v 1.13 1995/05/30 08:05:20 rgrimes Exp $ + * $Id: kern_clock.c,v 1.14 1995/07/29 11:40:12 bde Exp $ */ /* Portions of this software are covered by the following: */ @@ -75,6 +75,14 @@ #include #endif +/* + * System initialization + */ + +static void initclocks __P(( caddr_t udata)); +SYSINIT(clocks, SI_SUB_CLOCKS, SI_ORDER_FIRST, initclocks, NULL) + + /* Does anybody else really care about these? */ struct callout *callfree, *callout, calltodo; @@ -383,8 +391,10 @@ hardupdate(offset) /* * Initialize clock frequencies and start both clocks running. */ -void -initclocks() +/* ARGSUSED*/ +static void +initclocks( udata) +caddr_t udata; /* not used*/ { register int i; diff --git a/sys/kern/subr_clist.c b/sys/kern/subr_clist.c index d80d12757696..9694bcbef739 100644 --- a/sys/kern/subr_clist.c +++ b/sys/kern/subr_clist.c @@ -6,7 +6,7 @@ * of this software, nor does the author assume any responsibility * for damages incurred with its use. * - * $Id: tty_subr.c,v 1.10 1995/05/30 08:06:18 rgrimes Exp $ + * $Id: tty_subr.c,v 1.11 1995/07/11 19:39:54 bde Exp $ */ /* @@ -14,12 +14,20 @@ */ #include +#include #include #include #include #include #include +/* + * System initialization + */ + +static void clist_init __P((caddr_t)); +SYSINIT(clist, SI_SUB_CLIST, SI_ORDER_FIRST, clist_init, NULL) + struct cblock *cfreelist = 0; int cfreecount = 0; static int cslushcount; @@ -47,8 +55,10 @@ cbstat() /* * Called from init_main.c */ -void -clist_init() +/* ARGSUSED*/ +static void +clist_init( udata) +caddr_t udata; /* not used*/ { /* * Allocate an initial base set of cblocks as a 'slush'. diff --git a/sys/kern/subr_prof.c b/sys/kern/subr_prof.c index 3c8ef387223e..56c2a6e89068 100644 --- a/sys/kern/subr_prof.c +++ b/sys/kern/subr_prof.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)subr_prof.c 8.3 (Berkeley) 9/23/93 - * $Id: subr_prof.c,v 1.5 1995/01/29 03:03:23 bde Exp $ + * $Id: subr_prof.c,v 1.6 1995/03/16 18:12:41 bde Exp $ */ #include @@ -48,6 +48,14 @@ #include #include +/* + * System initialization + */ + +extern void kmstartup(); /* should be static*/ +SYSINIT(kmem, SI_SUB_KPROF, SI_ORDER_FIRST, kmstartup, NULL) + + struct gmonparam _gmonparam = { GMON_PROF_OFF }; extern char btext[]; diff --git a/sys/kern/sysv_msg.c b/sys/kern/sysv_msg.c index 09ed9ab0f52f..3eaa6b520b85 100644 --- a/sys/kern/sysv_msg.c +++ b/sys/kern/sysv_msg.c @@ -1,4 +1,4 @@ -/* $Id: sysv_msg.c,v 1.4 1995/05/30 08:06:01 rgrimes Exp $ */ +/* $Id: sysv_msg.c,v 1.5 1995/07/29 11:40:13 bde Exp $ */ /* * Implementation of SVID messages @@ -26,6 +26,13 @@ #include #include +/* + * System initialization + */ + +extern void msginit(); /* should be static*/ +SYSINIT(sysv_msg, SI_SUB_SYSV_MSG, SI_ORDER_FIRST, msginit, NULL) + #define MSG_DEBUG #undef MSG_DEBUG_OK diff --git a/sys/kern/sysv_sem.c b/sys/kern/sysv_sem.c index 9141c6f31b92..6cadbd52f655 100644 --- a/sys/kern/sysv_sem.c +++ b/sys/kern/sysv_sem.c @@ -1,4 +1,4 @@ -/* $Id: sysv_sem.c,v 1.5 1995/05/30 08:06:02 rgrimes Exp $ */ +/* $Id: sysv_sem.c,v 1.6 1995/07/29 11:40:14 bde Exp $ */ /* * Implementation of SVID semaphores @@ -15,6 +15,13 @@ #include #include +/* + * System initialization + */ + +extern void seminit(); /* should be static*/ +SYSINIT(sysv_sem, SI_SUB_SYSV_SEM, SI_ORDER_FIRST, seminit, NULL) + static int semctl(), semget(), semop(), semconfig(); int (*semcalls[])() = { semctl, semget, semop, semconfig }; int semtot = 0; diff --git a/sys/kern/sysv_shm.c b/sys/kern/sysv_shm.c index 8610d9065a63..3c0fc35f8888 100644 --- a/sys/kern/sysv_shm.c +++ b/sys/kern/sysv_shm.c @@ -1,4 +1,4 @@ -/* $Id: sysv_shm.c,v 1.5 1995/05/30 08:06:04 rgrimes Exp $ */ +/* $Id: sysv_shm.c,v 1.6 1995/07/29 11:40:15 bde Exp $ */ /* $NetBSD: sysv_shm.c,v 1.23 1994/07/04 23:25:12 glass Exp $ */ /* @@ -61,6 +61,13 @@ * per proc array of 'struct shmmap_state' */ +/* + * System initialization + */ + +extern void shminit(); /* should be static*/ +SYSINIT(sysv_shm, SI_SUB_SYSV_SHM, SI_ORDER_FIRST, shminit, NULL) + int oshmctl(); int shmat(), shmctl(), shmdt(), shmget(); int (*shmcalls[])() = { shmat, oshmctl, shmdt, shmget, shmctl }; diff --git a/sys/kern/tty_subr.c b/sys/kern/tty_subr.c index d80d12757696..9694bcbef739 100644 --- a/sys/kern/tty_subr.c +++ b/sys/kern/tty_subr.c @@ -6,7 +6,7 @@ * of this software, nor does the author assume any responsibility * for damages incurred with its use. * - * $Id: tty_subr.c,v 1.10 1995/05/30 08:06:18 rgrimes Exp $ + * $Id: tty_subr.c,v 1.11 1995/07/11 19:39:54 bde Exp $ */ /* @@ -14,12 +14,20 @@ */ #include +#include #include #include #include #include #include +/* + * System initialization + */ + +static void clist_init __P((caddr_t)); +SYSINIT(clist, SI_SUB_CLIST, SI_ORDER_FIRST, clist_init, NULL) + struct cblock *cfreelist = 0; int cfreecount = 0; static int cslushcount; @@ -47,8 +55,10 @@ cbstat() /* * Called from init_main.c */ -void -clist_init() +/* ARGSUSED*/ +static void +clist_init( udata) +caddr_t udata; /* not used*/ { /* * Allocate an initial base set of cblocks as a 'slush'. diff --git a/sys/kern/uipc_domain.c b/sys/kern/uipc_domain.c index 6332c075e2ab..7eea0429633e 100644 --- a/sys/kern/uipc_domain.c +++ b/sys/kern/uipc_domain.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)uipc_domain.c 8.2 (Berkeley) 10/18/93 - * $Id: uipc_domain.c,v 1.6 1995/05/11 00:16:44 wollman Exp $ + * $Id: uipc_domain.c,v 1.7 1995/08/16 16:13:21 bde Exp $ */ #include @@ -46,6 +46,29 @@ #include #include +/* + * System initialization + * + * Note: domain initialization wants to take place on a per domain basis + * as a result of traversing a linker set. Most likely, each domain + * want to call a registration function rather than being handled here + * in domaininit(). Probably this will look like: + * + * SYSINIT(unique, SI_SUB_PROTO_DOMAI, SI_ORDER_ANY, domain_add, (caddr_t)xxx) + * + * Where 'xxx' is replaced by the address of a parameter struct to be + * passed to the doamin_add() function. + */ + +static int x_save_spl; /* used by kludge*/ +static void kludge_splimp __P((caddr_t)); +static void kludge_splx __P((caddr_t)); +static void domaininit __P((caddr_t)); +SYSINIT(splimp, SI_SUB_PROTO_BEGIN, SI_ORDER_FIRST, kludge_splimp, (caddr_t)&x_save_spl) +SYSINIT(domain, SI_SUB_PROTO_DOMAIN, SI_ORDER_FIRST, domaininit, NULL) +SYSINIT(splx, SI_SUB_PROTO_END, SI_ORDER_FIRST, kludge_splx, (caddr_t)&x_save_spl) + + void pffasttimo __P((void *)); void pfslowtimo __P((void *)); @@ -58,8 +81,10 @@ struct domain *domains; extern struct linker_set domain_set; -void -domaininit() +/* ARGSUSED*/ +static void +domaininit( udata) +caddr_t udata; /* not used*/ { register struct domain *dp, **dpp; register struct protosw *pr; @@ -96,6 +121,35 @@ domaininit() timeout(pfslowtimo, (void *)0, 1); } + +/* + * The following two operations are kludge code. Most likely, they should + * be done as a "domainpreinit()" for the first function and then rolled + * in as the last act of "domaininit()" for the second. + * + * In point of fact, it is questionable why other initialization prior + * to this does not also take place at splimp by default. + */ +static void +kludge_splimp( udata) +caddr_t udata; +{ + int *savesplp = (int *)udata; + + *savesplp = splimp(); +} + +static void +kludge_splx( udata) +caddr_t udata; +{ + int *savesplp = (int *)udata; + + splx( *savesplp); +} + + + struct protosw * pffindtype(family, type) int family, type; diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c index 652fe660257b..77a0af18315f 100644 --- a/sys/kern/uipc_mbuf.c +++ b/sys/kern/uipc_mbuf.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94 - * $Id: uipc_mbuf.c,v 1.9 1995/03/15 07:51:53 davidg Exp $ + * $Id: uipc_mbuf.c,v 1.10 1995/07/29 11:40:16 bde Exp $ */ #include @@ -48,6 +48,14 @@ #include #include +/* + * System initialization + */ + +static void mbinit __P((caddr_t)); +SYSINIT(mbuf, SI_SUB_MBUF, SI_ORDER_FIRST, mbinit, NULL) + + struct mbuf *mbutl; char *mclrefcnt; struct mbstat mbstat; @@ -57,8 +65,10 @@ int max_protohdr; int max_hdr; int max_datalen; -void -mbinit() +/* ARGSUSED*/ +static void +mbinit( udata) +caddr_t udata; /* not used*/ { int s; diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index d2b5ba0600c3..6e8d2018eb8b 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -18,7 +18,7 @@ * 5. Modifications may be freely made to this file if the above conditions * are met. * - * $Id: vfs_bio.c,v 1.58 1995/08/24 13:28:16 davidg Exp $ + * $Id: vfs_bio.c,v 1.59 1995/08/24 13:59:14 davidg Exp $ */ /* @@ -51,6 +51,21 @@ #include +/* + * System initialization + */ + +static void vfs_update __P((void)); +struct proc *updateproc; + +static struct kproc_desc up_kp = { + "update", + vfs_update, + &updateproc +}; +SYSINIT_KT(update, SI_SUB_KTHREAD_UPDATE, SI_ORDER_FIRST, kproc_start, (caddr_t)&up_kp) + + struct buf *buf; /* buffer header pool */ struct swqueue bswlist; @@ -1270,10 +1285,10 @@ count_lock_queue() int vfs_update_interval = 30; -void +static void vfs_update() { - (void) spl0(); + (void) spl0(); /* XXX redundant? wrong place?*/ while (1) { tsleep(&vfs_update_wakeup, PRIBIO, "update", hz * vfs_update_interval); diff --git a/sys/kern/vfs_conf.c b/sys/kern/vfs_conf.c index 251d704e176c..e8497f248af0 100644 --- a/sys/kern/vfs_conf.c +++ b/sys/kern/vfs_conf.c @@ -1,6 +1,7 @@ /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. + * Copyright (c) 1995 Artisoft, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -31,13 +32,144 @@ * SUCH DAMAGE. * * @(#)vfs_conf.c 8.8 (Berkeley) 3/31/94 - * $Id: vfs_conf.c,v 1.5 1994/09/21 03:46:47 wollman Exp $ + * $Id: vfs_conf.c,v 1.6 1994/11/12 01:47:43 phk Exp $ */ -#include -#include -#include +/* + * PURPOSE: This file abstracts the root mounting interface from + * the per file system semantics for handling mounts, + * the overall intent of which is to move the BSD + * internals dependence out of the FS code, both to + * make the FS code more portable and to free up some + * of the BSD internals so that they may more easily + * be changed. + * + * NOTE1: Code is single entry/single exit to aid debugging + * and conversion for kernel multithreading. + * + * NOTE2: Code notes lock state in headers on entry and exit + * as an aid to conversion for kernel multithreading + * on SMP reentrancy + */ +#include /* dev_t (types.h)*/ +#include /* rootvp*/ +#include /* curproc*/ +#include /* NULLVP*/ +#include /* struct mount*/ +#include /* M_MOUNT*/ -int (*mountroot) __P((void)); +/* + * GLOBALS + */ +int (*mountroot) __P((caddr_t)); struct vnode *rootvnode; +struct vfsops *mountrootvfsops; + +/* + * Common root mount code shared by all filesystems + */ +#define ROOTDIR "/" +#define ROOTNAME "root_device" + + + +/* + * vfs_mountroot + * + * Common entry point for root mounts + * + * PARAMETERS: + * data pointer to the vfs_ops for the FS type mounting + * + * RETURNS: 0 Success + * !0 error number (errno.h) + * + * LOCK STATE: + * ENTRY + * + * EXIT + * + * + * NOTES: + * This code is currently supported only for use for + * the FFS file system type. This is a matter of + * fixing the other file systems, not this code! + */ +int +vfs_mountroot( data) +caddr_t *data; /* file system function table*/ +{ + struct mount *mp; + u_int size; + int err = 0; + struct proc *p = curproc; /* XXX */ + register struct fs *fs; + struct vfsops *mnt_op = (struct vfsops *)data; + + /* + * New root mount structure + */ + mp = malloc((u_long)sizeof(struct mount), M_MOUNT, M_WAITOK); + bzero((char *)mp, (u_long)sizeof(struct mount)); + mp->mnt_op = mnt_op; + mp->mnt_flag = MNT_ROOTFS; + mp->mnt_vnodecovered = NULLVP; + + /* + * Lock mount point + */ + if( ( err = vfs_lock(mp)) != 0) + goto error_1; + + /* Save "last mounted on" info for mount point (NULL pad)*/ + copystr( ROOTDIR, /* mount point*/ + mp->mnt_stat.f_mntonname, /* save area*/ + MNAMELEN - 1, /* max size*/ + &size); /* real size*/ + bzero( mp->mnt_stat.f_mntonname + size, MNAMELEN - size); + + /* Save "mounted from" info for mount point (NULL pad)*/ + copystr( ROOTNAME, /* device name*/ + mp->mnt_stat.f_mntfromname, /* save area*/ + MNAMELEN - 1, /* max size*/ + &size); /* real size*/ + bzero( mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); + + /* + * Attempt the mount + */ + err = VFS_MOUNT( mp, NULL, NULL, NULL, p); + if( err) + goto error_2; + + /* Add fs to list of mounted file systems*/ + CIRCLEQ_INSERT_TAIL( &mountlist, mp, mnt_list); + + /* Unlock mount point*/ + vfs_unlock(mp); + + /* root mount, update system time from FS specific data*/ + inittodr( mp->mnt_time); + + goto success; + + +error_2: /* mount error*/ + + /* unlock before failing*/ + vfs_unlock( mp); + +error_1: /* lock error*/ + + /* free mount struct before failing*/ + free( mp, M_MOUNT); + +success: + return( err); +} + + +/* + * EOF -- This file has not been truncated. + */ diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c index 33f9ce50338e..1f7135ae14dc 100644 --- a/sys/kern/vfs_extattr.c +++ b/sys/kern/vfs_extattr.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94 - * $Id: vfs_syscalls.c,v 1.31 1995/08/11 11:31:08 davidg Exp $ + * $Id: vfs_syscalls.c,v 1.32 1995/08/17 11:53:40 bde Exp $ */ #include @@ -835,11 +835,9 @@ link(p, uap, retval) vp = nd.ni_vp; if (vp->v_type != VDIR || (error = suser(p->p_ucred, &p->p_acflag)) == 0) { - nd.ni_cnd.cn_nameiop = CREATE; - nd.ni_cnd.cn_flags = LOCKPARENT; + NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, uap->link, p); if (vp->v_type == VDIR) - nd.ni_cnd.cn_flags |= WILLBEDIR; - nd.ni_dirp = uap->link; + nd.ni_cnd.cn_flags |= WILLBEDIR; error = namei(&nd); if (!error) { if (nd.ni_vp != NULL) { diff --git a/sys/kern/vfs_init.c b/sys/kern/vfs_init.c index ad1272142241..d772c8dbe31a 100644 --- a/sys/kern/vfs_init.c +++ b/sys/kern/vfs_init.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_init.c 8.3 (Berkeley) 1/4/94 - * $Id: vfs_init.c,v 1.9 1994/10/20 00:48:28 wollman Exp $ + * $Id: vfs_init.c,v 1.10 1995/05/30 08:06:32 rgrimes Exp $ */ @@ -56,6 +56,13 @@ #include #include +/* + * System initialization + */ + +static void vfsinit __P((caddr_t)); +SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_FIRST, vfsinit, NULL) + /* * Sigh, such primitive tools are these... */ @@ -230,8 +237,10 @@ struct vattr va_null; /* * Initialize the vnode structures and initialize each file system type. */ -void -vfsinit() +/* ARGSUSED*/ +static void +vfsinit( udata) +caddr_t udata; /* not used*/ { struct vfsops **vfsp; struct vfsconf **vfc; diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c index 251d704e176c..e8497f248af0 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -1,6 +1,7 @@ /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. + * Copyright (c) 1995 Artisoft, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -31,13 +32,144 @@ * SUCH DAMAGE. * * @(#)vfs_conf.c 8.8 (Berkeley) 3/31/94 - * $Id: vfs_conf.c,v 1.5 1994/09/21 03:46:47 wollman Exp $ + * $Id: vfs_conf.c,v 1.6 1994/11/12 01:47:43 phk Exp $ */ -#include -#include -#include +/* + * PURPOSE: This file abstracts the root mounting interface from + * the per file system semantics for handling mounts, + * the overall intent of which is to move the BSD + * internals dependence out of the FS code, both to + * make the FS code more portable and to free up some + * of the BSD internals so that they may more easily + * be changed. + * + * NOTE1: Code is single entry/single exit to aid debugging + * and conversion for kernel multithreading. + * + * NOTE2: Code notes lock state in headers on entry and exit + * as an aid to conversion for kernel multithreading + * on SMP reentrancy + */ +#include /* dev_t (types.h)*/ +#include /* rootvp*/ +#include /* curproc*/ +#include /* NULLVP*/ +#include /* struct mount*/ +#include /* M_MOUNT*/ -int (*mountroot) __P((void)); +/* + * GLOBALS + */ +int (*mountroot) __P((caddr_t)); struct vnode *rootvnode; +struct vfsops *mountrootvfsops; + +/* + * Common root mount code shared by all filesystems + */ +#define ROOTDIR "/" +#define ROOTNAME "root_device" + + + +/* + * vfs_mountroot + * + * Common entry point for root mounts + * + * PARAMETERS: + * data pointer to the vfs_ops for the FS type mounting + * + * RETURNS: 0 Success + * !0 error number (errno.h) + * + * LOCK STATE: + * ENTRY + * + * EXIT + * + * + * NOTES: + * This code is currently supported only for use for + * the FFS file system type. This is a matter of + * fixing the other file systems, not this code! + */ +int +vfs_mountroot( data) +caddr_t *data; /* file system function table*/ +{ + struct mount *mp; + u_int size; + int err = 0; + struct proc *p = curproc; /* XXX */ + register struct fs *fs; + struct vfsops *mnt_op = (struct vfsops *)data; + + /* + * New root mount structure + */ + mp = malloc((u_long)sizeof(struct mount), M_MOUNT, M_WAITOK); + bzero((char *)mp, (u_long)sizeof(struct mount)); + mp->mnt_op = mnt_op; + mp->mnt_flag = MNT_ROOTFS; + mp->mnt_vnodecovered = NULLVP; + + /* + * Lock mount point + */ + if( ( err = vfs_lock(mp)) != 0) + goto error_1; + + /* Save "last mounted on" info for mount point (NULL pad)*/ + copystr( ROOTDIR, /* mount point*/ + mp->mnt_stat.f_mntonname, /* save area*/ + MNAMELEN - 1, /* max size*/ + &size); /* real size*/ + bzero( mp->mnt_stat.f_mntonname + size, MNAMELEN - size); + + /* Save "mounted from" info for mount point (NULL pad)*/ + copystr( ROOTNAME, /* device name*/ + mp->mnt_stat.f_mntfromname, /* save area*/ + MNAMELEN - 1, /* max size*/ + &size); /* real size*/ + bzero( mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); + + /* + * Attempt the mount + */ + err = VFS_MOUNT( mp, NULL, NULL, NULL, p); + if( err) + goto error_2; + + /* Add fs to list of mounted file systems*/ + CIRCLEQ_INSERT_TAIL( &mountlist, mp, mnt_list); + + /* Unlock mount point*/ + vfs_unlock(mp); + + /* root mount, update system time from FS specific data*/ + inittodr( mp->mnt_time); + + goto success; + + +error_2: /* mount error*/ + + /* unlock before failing*/ + vfs_unlock( mp); + +error_1: /* lock error*/ + + /* free mount struct before failing*/ + free( mp, M_MOUNT); + +success: + return( err); +} + + +/* + * EOF -- This file has not been truncated. + */ diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 33f9ce50338e..1f7135ae14dc 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94 - * $Id: vfs_syscalls.c,v 1.31 1995/08/11 11:31:08 davidg Exp $ + * $Id: vfs_syscalls.c,v 1.32 1995/08/17 11:53:40 bde Exp $ */ #include @@ -835,11 +835,9 @@ link(p, uap, retval) vp = nd.ni_vp; if (vp->v_type != VDIR || (error = suser(p->p_ucred, &p->p_acflag)) == 0) { - nd.ni_cnd.cn_nameiop = CREATE; - nd.ni_cnd.cn_flags = LOCKPARENT; + NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, uap->link, p); if (vp->v_type == VDIR) - nd.ni_cnd.cn_flags |= WILLBEDIR; - nd.ni_dirp = uap->link; + nd.ni_cnd.cn_flags |= WILLBEDIR; error = namei(&nd); if (!error) { if (nd.ni_vp != NULL) { diff --git a/sys/net/if.c b/sys/net/if.c index 65ef003da23c..fc4f15d4aab3 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)if.c 8.3 (Berkeley) 1/4/94 - * $Id: if.c,v 1.16 1995/06/15 00:19:56 davidg Exp $ + * $Id: if.c,v 1.17 1995/06/28 05:31:03 davidg Exp $ */ #include @@ -51,6 +51,14 @@ #include #include +/* + * System initialization + */ + +static void ifinit __P((caddr_t)); +SYSINIT(interfaces, SI_SUB_PROTO_IF, SI_ORDER_FIRST, ifinit, NULL) + + int ifqmaxlen = IFQ_MAXLEN; struct ifnet *ifnet; @@ -59,9 +67,13 @@ struct ifnet *ifnet; * * Routines with ifa_ifwith* names take sockaddr *'s as * parameters. + * + * This routine assumes that it will be called at splimp() or higher. */ +/* ARGSUSED*/ void -ifinit() +ifinit( udata) +caddr_t udata; /* not used*/ { register struct ifnet *ifp; diff --git a/sys/sys/kernel.h b/sys/sys/kernel.h index 7c032b2a03f0..917797d3be4a 100644 --- a/sys/sys/kernel.h +++ b/sys/sys/kernel.h @@ -1,4 +1,7 @@ /*- + * Copyright (c) 1995 Terrence R. Lambert + * All rights reserved. + * * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. @@ -36,7 +39,7 @@ * SUCH DAMAGE. * * @(#)kernel.h 8.3 (Berkeley) 1/21/94 - * $Id: kernel.h,v 1.8 1995/03/17 22:02:05 wollman Exp $ + * $Id: kernel.h,v 1.9 1995/03/20 19:20:26 wollman Exp $ */ #ifndef _SYS_KERNEL_H_ @@ -83,6 +86,146 @@ extern long timedelta; #define BSS_SET(set, sym) MAKE_SET(set, sym, 27) #define ABS_SET(set, sym) MAKE_SET(set, sym, 21) + +/* + * Enumerated types for known system startup interfaces. + * + * Startup occurs in ascending numeric order; the list entries are + * sorted prior to attempting startup to guarantee order. Items + * of the same level are arbitrated for order based on the 'order' + * element. + * + * These numbers are arbitrary and are chosen ONLY for ordering; the + * enumeration values are explicit rather than imlicit to provide + * for binary compatability with inserted elements. + * + * The SI_SUB_RUN_SCHEDULER value must have the highest lexical value. + * + * The SI_SUB_CONSOLE and SI_SUB_SWAP values represent values used by + * the BSD 4.4Lite but not by FreeBSD; they are maintained in dependent + * order to support porting. + * + * The SI_SUB_PROTO_BEGIN and SI_SUB_PROTO_END bracket a range of + * initializations to take place at splimp(). This is a historical + * wart that should be removed -- probably running everything at + * splimp() until the first init that doesn't want it is the correct + * fix. They are currently present to ensure historical behaviour. + */ +enum sysinit_sub_id { + SI_SUB_DUMMY = 0x00000000, /* not executed; for linker*/ + SI_SUB_CONSOLE = 0x08000000, /* console*/ + SI_SUB_COPYRIGHT = 0x08000001, /* first use of console*/ + SI_SUB_VM = 0x10000000, /* virtual memory system init*/ + SI_SUB_KMEM = 0x18000000, /* kernel memory*/ + SI_SUB_CPU = 0x20000000, /* CPU resource(s)*/ + SI_SUB_INTRINSIC = 0x28000000, /* proc 0*/ + SI_SUB_RUN_QUEUE = 0x30000000, /* the run queue*/ + SI_SUB_VM_CONF = 0x38000000, /* config VM, set limits*/ + SI_SUB_VFS = 0x40000000, /* virtual file system*/ + SI_SUB_CLOCKS = 0x48000000, /* real time and stat clocks*/ + SI_SUB_MBUF = 0x50000000, /* mbufs*/ + SI_SUB_CLIST = 0x58000000, /* clists*/ + SI_SUB_SYSV_SHM = 0x64000000, /* System V shared memory*/ + SI_SUB_SYSV_SEM = 0x68000000, /* System V semaphores*/ + SI_SUB_SYSV_MSG = 0x6C000000, /* System V message queues*/ + SI_SUB_PSEUDO = 0x70000000, /* pseudo devices*/ + SI_SUB_PROTO_BEGIN = 0x80000000, /* XXX: set splimp (kludge)*/ + SI_SUB_PROTO_IF = 0x84000000, /* interfaces*/ + SI_SUB_PROTO_DOMAIN = 0x88000000, /* domains (address families?)*/ + SI_SUB_PROTO_END = 0x8fffffff, /* XXX: set splx (kludge)*/ + SI_SUB_KPROF = 0x90000000, /* kernel profiling*/ + SI_SUB_KICK_SCHEDULER = 0xa0000000, /* start the timeout events*/ + SI_SUB_ROOT = 0xb0000000, /* root mount*/ + SI_SUB_ROOT_FDTAB = 0xb8000000, /* root vnode in fd table...*/ + SI_SUB_SWAP = 0xc0000000, /* swap*/ + SI_SUB_INTRINSIC_POST = 0xd0000000, /* proc 0 cleanup*/ + SI_SUB_KTHREAD_INIT = 0xe0000000, /* init process*/ + SI_SUB_KTHREAD_PAGE = 0xe4000000, /* pageout daemon*/ + SI_SUB_KTHREAD_VM = 0xe8000000, /* vm daemon*/ + SI_SUB_KTHREAD_UPDATE = 0xec000000, /* update daemon*/ + SI_SUB_RUN_SCHEDULER = 0xffffffff /* scheduler: no return*/ +}; + + +/* + * Some enumerated orders; "ANY" sorts last. + */ +enum sysinit_elem_order { + SI_ORDER_FIRST = 0x00000000, /* first*/ + SI_ORDER_SECOND = 0x00000001, /* second*/ + SI_ORDER_THIRD = 0x00000002, /* third*/ + SI_ORDER_ANY = 0xffffffff /* last*/ +}; + + +/* + * System initialization call types; currently two are supported... one + * to do a simple function call and one to cause a process to be started + * by the kernel on the callers behalf. + */ +typedef enum sysinit_elem_type { + SI_TYPE_DEFAULT = 0x00000000, /* No special processing*/ + SI_TYPE_KTHREAD = 0x00000001 /* start kernel thread*/ +} si_elem_t; + + +/* + * A system initialization call instance + * + * The subsystem + */ +struct sysinit { + unsigned int subsystem; /* subsystem identifier*/ + unsigned int order; /* init order within subsystem*/ + void (*func) __P((caddr_t)); /* init function*/ + caddr_t udata; /* multiplexer/argument*/ + si_elem_t type; /* sysinit_elem_type*/ +}; + + +/* + * Default: no special processing + */ +#define SYSINIT(uniquifier, subsystem, order, func, ident) \ + static struct sysinit uniquifier ## _sys_init = { \ + subsystem, \ + order, \ + func, \ + ident, \ + SI_TYPE_DEFAULT \ + }; \ + DATA_SET(sysinit_set,uniquifier ## _sys_init); + +/* + * Call 'fork()' before calling '(*func)(ident)'; kernel 'thread' or + * builtin process. + */ +#define SYSINIT_KT(uniquifier, subsystem, order, func, ident) \ + static struct sysinit uniquifier ## _sys_init = { \ + subsystem, \ + order, \ + func, \ + ident, \ + SI_TYPE_KTHREAD \ + }; \ + DATA_SET(sysinit_set,uniquifier ## _sys_init); + + +/* + * A kernel process descriptor; used to start "internal" daemons + * + * Note: global_procpp may be NULL for no global save area + */ +struct kproc_desc { + char *arg0; /* arg 0 (for 'ps' listing)*/ + void (*func) __P((void)); /* "main" for kernel process*/ + struct proc **global_procpp; /* ptr to proc ptr save area*/ +}; + +/* init_proc.c*/ +extern void kproc_start __P(( caddr_t udata)); + + #ifdef PSEUDO_LKM #include #include @@ -102,7 +245,10 @@ extern long timedelta; nosys); } #else /* PSEUDO_LKM */ -#define PSEUDO_SET(sym, name) TEXT_SET(pseudo_set, sym) +/* + * Compatability. To be deprecated after LKM is updated. + */ +#define PSEUDO_SET(sym, name) SYSINIT(ps, SI_SUB_PSEUDO, SI_ORDER_ANY, sym, 0) #endif /* PSEUDO_LKM */ @@ -113,4 +259,4 @@ struct linker_set { extern const struct linker_set execsw_set; -#endif +#endif /* _SYS_KERNEL_H_*/ diff --git a/sys/sys/mdioctl.h b/sys/sys/mdioctl.h index 1df5502ff9ae..4f2e9371ce96 100644 --- a/sys/sys/mdioctl.h +++ b/sys/sys/mdioctl.h @@ -40,6 +40,9 @@ * @(#)vnioctl.h 8.1 (Berkeley) 6/10/93 */ +#ifndef _SYS_VNIOCTL_H_ +#define _SYS_VNIOCTL_H_ + /* * Ioctl definitions for file (vnode) disk pseudo-device. */ @@ -69,3 +72,5 @@ struct vn_ioctl { #define VN_DEBUG 0x4 /* Debug data in vn driver */ #define VN_IO 0x8 /* Debug I/O in vn driver */ #define VN_DONTCLUSTER 0x10 /* Don't cluster */ + +#endif /* _SYS_VNIOCTL_H_*/ diff --git a/sys/sys/mount.h b/sys/sys/mount.h index fc50ef6042ec..fc14024032f9 100644 --- a/sys/sys/mount.h +++ b/sys/sys/mount.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)mount.h 8.13 (Berkeley) 3/27/94 - * $Id: mount.h,v 1.23 1995/08/23 13:30:52 jkh Exp $ + * $Id: mount.h,v 1.24 1995/08/26 05:40:52 davidg Exp $ */ #ifndef _SYS_MOUNT_H_ @@ -138,6 +138,8 @@ struct mount { int mnt_maxsymlinklen; /* max size of short symlink */ struct statfs mnt_stat; /* cache of filesystem stats */ qaddr_t mnt_data; /* private data */ +/* struct vfsconf *mnt_vfc; */ /* configuration info */ + time_t mnt_time; /* last time written*/ }; /* @@ -209,11 +211,12 @@ struct vfsconf { * NB: these flags refer to IMPLEMENTATION properties, not properties of * any actual mounts; i.e., it does not make sense to change the flags. */ -#define VFCF_STATIC 1 /* FS is statically compiled into kernel */ -#define VFCF_NETWORK 2 /* FS may get data over the network */ -#define VFCF_READONLY 4 /* writes are not implemented by FS */ -#define VFCF_SYNTHETIC 8 /* data in FS does not represent real files */ -#define VFCF_LOOPBACK 16 /* FS aliases some other mounted FS */ +#define VFCF_STATIC 0x00000001 /* statically compiled into kernel */ +#define VFCF_NETWORK 0x00000002 /* may get data over the network */ +#define VFCF_READONLY 0x00000004 /* writes are not implemented */ +#define VFCF_SYNTHETIC 0x00000008 /* data does not represent real files */ +#define VFCF_LOOPBACK 0x00000010 /* aliases some other mounted FS */ +#define VFCF_UNICODE 0x00000020 /* stores file names as Unicode*/ /* * Operations supported on mounted file system. @@ -464,7 +467,8 @@ struct nfs_args { #endif /* NFS */ #ifdef KERNEL -extern int (*mountroot) __P((void)); +extern int (*mountroot) __P((caddr_t)); +extern struct vfsops *mountrootvfsops; /* * exported vnode operations diff --git a/sys/sys/namei.h b/sys/sys/namei.h index fcd48ce641fd..9900f7ebc3dc 100644 --- a/sys/sys/namei.h +++ b/sys/sys/namei.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)namei.h 8.2 (Berkeley) 1/4/94 - * $Id: namei.h,v 1.6 1995/07/29 11:42:49 bde Exp $ + * $Id: namei.h,v 1.7 1995/07/31 00:35:58 bde Exp $ */ #ifndef _SYS_NAMEI_H_ @@ -134,7 +134,8 @@ struct nameidata { #define MAKEENTRY 0x04000 /* entry is to be added to name cache */ #define ISLASTCN 0x08000 /* this is last component of pathname */ #define ISSYMLINK 0x10000 /* symlink needs interpretation */ -#define WILLBEDIR 0x20000 /* new files will be dirs; allow trailing / */ +#define WILLBEDIR 0x20000 /* new files will be dirs; allow trailing / */ +#define ISUNICODE 0x40000 /* current component name is unicode*/ #define PARAMASK 0xfff00 /* mask of parameter descriptors */ /* * Initialization of an nameidata structure. diff --git a/sys/sys/systm.h b/sys/sys/systm.h index 0b22167680af..630811a81114 100644 --- a/sys/sys/systm.h +++ b/sys/sys/systm.h @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)systm.h 8.4 (Berkeley) 2/23/94 - * $Id: systm.h,v 1.22 1995/05/30 08:14:38 rgrimes Exp $ + * $Id: systm.h,v 1.23 1995/07/05 12:04:51 davidg Exp $ */ #ifndef _SYS_SYSTM_H_ @@ -157,8 +157,6 @@ void hardclock __P((struct clockframe *frame)); void softclock __P((void)); void statclock __P((struct clockframe *frame)); -void initclocks __P((void)); - void startprofclock __P((struct proc *)); void stopprofclock __P((struct proc *)); void setstatclockrate __P((int hzrate)); @@ -168,15 +166,7 @@ void hardupdate __P((long)); /* Initialize the world */ extern void consinit(void); -extern void kmeminit(void); -extern void cpu_startup(void); extern void usrinfoinit(void); -extern void rqinit(void); -extern void vfsinit(void); -extern void mbinit(void); -extern void clist_init(void); -extern void ifinit(void); -extern void domaininit(void); extern void cpu_initclocks(void); extern void vntblinit(void); extern void nchinit(void); @@ -184,9 +174,6 @@ extern void nchinit(void); /* Finalize the world. */ void shutdown_nice __P((void)); -extern __dead void vm_pageout(void) __dead2; /* pagedaemon, called in proc 2 */ -extern __dead void vfs_update(void) __dead2; /* update, called in proc 3 */ -extern __dead void scheduler(void) __dead2; /* sched, called in process 0 */ /* * Kernel to clock driver interface. diff --git a/sys/sys/vnioctl.h b/sys/sys/vnioctl.h index 1df5502ff9ae..4f2e9371ce96 100644 --- a/sys/sys/vnioctl.h +++ b/sys/sys/vnioctl.h @@ -40,6 +40,9 @@ * @(#)vnioctl.h 8.1 (Berkeley) 6/10/93 */ +#ifndef _SYS_VNIOCTL_H_ +#define _SYS_VNIOCTL_H_ + /* * Ioctl definitions for file (vnode) disk pseudo-device. */ @@ -69,3 +72,5 @@ struct vn_ioctl { #define VN_DEBUG 0x4 /* Debug data in vn driver */ #define VN_IO 0x8 /* Debug I/O in vn driver */ #define VN_DONTCLUSTER 0x10 /* Don't cluster */ + +#endif /* _SYS_VNIOCTL_H_*/ diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c index 19c78cf3e94f..78cbfda71584 100644 --- a/sys/ufs/ffs/ffs_vfsops.c +++ b/sys/ufs/ffs/ffs_vfsops.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)ffs_vfsops.c 8.8 (Berkeley) 4/18/94 - * $Id: ffs_vfsops.c,v 1.26 1995/08/06 11:56:42 davidg Exp $ + * $Id: ffs_vfsops.c,v 1.27 1995/08/11 11:31:15 davidg Exp $ */ #include @@ -87,85 +87,103 @@ VFS_SET(ufs_vfsops, ufs, MOUNT_UFS, 0); extern u_long nextgennumber; -/* - * Called by main() when ufs is going to be mounted as root. - * - * Name is updated by mount(8) after booting. - */ -#define ROOTNAME "root_device" - -int -ffs_mountroot() -{ - register struct fs *fs; - register struct mount *mp; - struct proc *p = curproc; /* XXX */ - struct ufsmount *ump; - u_int size; - int error; - - /* - * Get vnode for rootdev. - */ - if (bdevvp(rootdev, &rootvp)) - panic("ffs_mountroot: can't setup bdevvp for root"); - - mp = malloc((u_long)sizeof(struct mount), M_MOUNT, M_WAITOK); - bzero((char *)mp, (u_long)sizeof(struct mount)); - mp->mnt_op = &ufs_vfsops; - mp->mnt_flag = MNT_RDONLY; - error = ffs_mountfs(rootvp, mp, p); - if (error) { - free(mp, M_MOUNT); - return (error); - } - error = vfs_lock(mp); - if (error) { - (void)ffs_unmount(mp, 0, p); - free(mp, M_MOUNT); - return (error); - } - CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list); - mp->mnt_flag |= MNT_ROOTFS; - mp->mnt_vnodecovered = NULLVP; - ump = VFSTOUFS(mp); - fs = ump->um_fs; - bzero(fs->fs_fsmnt, sizeof(fs->fs_fsmnt)); - fs->fs_fsmnt[0] = '/'; - bcopy((caddr_t)fs->fs_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname, - MNAMELEN); - (void) copystr(ROOTNAME, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, - &size); - bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); - (void)ffs_statfs(mp, &mp->mnt_stat, p); - vfs_unlock(mp); - inittodr(fs->fs_time); - return (0); -} /* - * VFS Operations. + * ffs_mount * - * mount system call + * Called when mounting local physical media + * + * PARAMETERS: + * mountroot + * mp mount point structure + * path NULL (flag for root mount!!!) + * data + * ndp + * p process (user credentials check [statfs]) + * + * mount + * mp mount point structure + * path path to mount point + * data pointer to argument struct in user space + * ndp mount point namei() return (used for + * credentials on reload), reused to look + * up block device. + * p process (user credentials check) + * + * RETURNS: 0 Success + * !0 error number (errno.h) + * + * LOCK STATE: + * + * ENTRY + * mount point is locked + * EXIT + * mount point is locked + * + * NOTES: + * A NULL path can be used for a flag since the mount + * system call will fail with EFAULT in copyinstr in + * namei() if it is a genuine NULL from the user. */ int -ffs_mount(mp, path, data, ndp, p) - register struct mount *mp; - char *path; - caddr_t data; - struct nameidata *ndp; - struct proc *p; +ffs_mount( mp, path, data, ndp, p) + register struct mount *mp; /* mount struct pointer*/ + char *path; /* path to mount point*/ + caddr_t data; /* arguments to FS specific mount*/ + struct nameidata *ndp; /* mount point credentials*/ + struct proc *p; /* process requesting mount*/ { - struct vnode *devvp; + u_int size; + int err = 0; + struct vnode *devvp; + struct ufs_args args; struct ufsmount *ump = 0; register struct fs *fs; - u_int size; - int error, flags; + int flags; + + /* + * Use NULL path to flag a root mount + */ + if( path == NULL) { + /* + *** + * Mounting root file system + *** + */ + + /* Get vnode for root device*/ + if( bdevvp( rootdev, &rootvp)) + panic("ffs_mountroot: can't setup bdevvp for root"); + + /* + * FS specific handling + */ + mp->mnt_flag |= MNT_RDONLY; /* XXX globally applicable?*/ + + /* + * Attempt mount + */ + if( ( err = ffs_mountfs(rootvp, mp, p)) != 0) { + /* fs specific cleanup (if any)*/ + goto error_1; + } + + goto dostatfs; /* success*/ + + } + + /* + *** + * Mounting non-root file system or updating a file system + *** + */ + + /* copy in user arguments*/ + err = copyin(data, (caddr_t)&args, sizeof (struct ufs_args)); + if (err) + goto error_1; /* can't get arguments*/ - error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args)); - if (error) - return (error); /* * If updating, check whether changing from read-only to * read/write; if there is no device name, that's all we do. @@ -173,20 +191,23 @@ ffs_mount(mp, path, data, ndp, p) if (mp->mnt_flag & MNT_UPDATE) { ump = VFSTOUFS(mp); fs = ump->um_fs; - error = 0; + err = 0; if (fs->fs_ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) { flags = WRITECLOSE; if (mp->mnt_flag & MNT_FORCE) flags |= FORCECLOSE; - if (vfs_busy(mp)) - return (EBUSY); - error = ffs_flushfiles(mp, flags, p); + if (vfs_busy(mp)) { + err = EBUSY; + goto error_1; + } + err = ffs_flushfiles(mp, flags, p); vfs_unbusy(mp); } - if (!error && (mp->mnt_flag & MNT_RELOAD)) - error = ffs_reload(mp, ndp->ni_cnd.cn_cred, p); - if (error) - return (error); + if (!err && (mp->mnt_flag & MNT_RELOAD)) + err = ffs_reload(mp, ndp->ni_cnd.cn_cred, p); + if (err) { + goto error_1; + } if (fs->fs_ronly && (mp->mnt_flag & MNT_WANTRDWR)) { if (!fs->fs_clean) { if (mp->mnt_flag & MNT_FORCE) { @@ -194,7 +215,8 @@ ffs_mount(mp, path, data, ndp, p) } else { printf("WARNING: R/W mount of %s denied. Filesystem is not clean - run fsck.\n", fs->fs_fsmnt); - return (EPERM); + err = EPERM; + goto error_1; } } fs->fs_ronly = 0; @@ -203,56 +225,117 @@ ffs_mount(mp, path, data, ndp, p) fs->fs_clean = 0; ffs_sbupdate(ump, MNT_WAIT); } + /* if not updating name...*/ if (args.fspec == 0) { /* - * Process export requests. + * Process export requests. Jumping to "success" + * will return the vfs_export() error code. */ - return (vfs_export(mp, &ump->um_export, &args.export)); + err = vfs_export(mp, &ump->um_export, &args.export); + goto success; } } + /* * Not an update, or updating the name: look up the name * and verify that it refers to a sensible block device. */ NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, p); - error = namei(ndp); - if (error) - return (error); + err = namei(ndp); + if (err) { + /* can't get devvp!*/ + goto error_1; + } + devvp = ndp->ni_vp; if (devvp->v_type != VBLK) { - vrele(devvp); - return (ENOTBLK); + err = ENOTBLK; + goto error_2; } if (major(devvp->v_rdev) >= nblkdev) { - vrele(devvp); - return (ENXIO); + err = ENXIO; + goto error_2; } - if ((mp->mnt_flag & MNT_UPDATE) == 0) - error = ffs_mountfs(devvp, mp, p); - else { + if (mp->mnt_flag & MNT_UPDATE) { + /* + ******************** + * UPDATE + ******************** + */ + if (devvp != ump->um_devvp) - error = EINVAL; /* needs translation */ + err = EINVAL; /* needs translation */ else vrele(devvp); + /* + * Update device name only on success + */ + if( !err) { + /* Save "mounted from" info for mount point (NULL pad)*/ + copyinstr( args.fspec, + mp->mnt_stat.f_mntfromname, + MNAMELEN - 1, + &size); + bzero( mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); + } + } else { + /* + ******************** + * NEW MOUNT + ******************** + */ + + /* + * Since this is a new mount, we want the names for + * the device and the mount point copied in. If an + * error occurs, the mountpoint is discarded by the + * upper level code. + */ + /* Save "last mounted on" info for mount point (NULL pad)*/ + copyinstr( path, /* mount point*/ + mp->mnt_stat.f_mntonname, /* save area*/ + MNAMELEN - 1, /* max size*/ + &size); /* real size*/ + bzero( mp->mnt_stat.f_mntonname + size, MNAMELEN - size); + + /* Save "mounted from" info for mount point (NULL pad)*/ + copyinstr( args.fspec, /* device name*/ + mp->mnt_stat.f_mntfromname, /* save area*/ + MNAMELEN - 1, /* max size*/ + &size); /* real size*/ + bzero( mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); + + err = ffs_mountfs(devvp, mp, p); } - if (error) { - vrele(devvp); - return (error); + if (err) { + goto error_2; } - ump = VFSTOUFS(mp); - fs = ump->um_fs; - (void) copyinstr(path, fs->fs_fsmnt, sizeof(fs->fs_fsmnt) - 1, &size); - bzero(fs->fs_fsmnt + size, sizeof(fs->fs_fsmnt) - size); - bcopy((caddr_t)fs->fs_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname, - MNAMELEN); - (void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, - &size); - bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); - (void)ffs_statfs(mp, &mp->mnt_stat, p); - return (0); + +dostatfs: + /* + * Initialize FS stat information in mount struct; uses both + * mp->mnt_stat.f_mntonname and mp->mnt_stat.f_mntfromname + * + * This code is common to root and non-root mounts + */ + (void)VFS_STATFS(mp, &mp->mnt_stat, p); + + goto success; + + +error_2: /* error with devvp held*/ + + /* release devvp before failing*/ + vrele(devvp); + +error_1: /* no state to back out*/ + +success: + return( err); } + /* * Reload all incore data for a filesystem (used after running fsck on * the root filesystem and finding things to fix). The filesystem must @@ -267,8 +350,8 @@ ffs_mount(mp, path, data, ndp, p) * 6) re-read inode data for all active vnodes. */ int -ffs_reload(mountp, cred, p) - register struct mount *mountp; +ffs_reload(mp, cred, p) + register struct mount *mp; struct ucred *cred; struct proc *p; { @@ -279,12 +362,12 @@ ffs_reload(mountp, cred, p) struct fs *fs; int i, blks, size, error; - if ((mountp->mnt_flag & MNT_RDONLY) == 0) + if ((mp->mnt_flag & MNT_RDONLY) == 0) return (EINVAL); /* * Step 1: invalidate all cached meta-data. */ - devvp = VFSTOUFS(mountp)->um_devvp; + devvp = VFSTOUFS(mp)->um_devvp; if (vinvalbuf(devvp, 0, cred, p, 0, 0)) panic("ffs_reload: dirty1"); /* @@ -299,7 +382,7 @@ ffs_reload(mountp, cred, p) brelse(bp); return (EIO); /* XXX needs translation */ } - fs = VFSTOUFS(mountp)->um_fs; + fs = VFSTOUFS(mp)->um_fs; bcopy(&fs->fs_csp[0], &((struct fs *)bp->b_data)->fs_csp[0], sizeof(fs->fs_csp)); bcopy(bp->b_data, fs, (u_int)fs->fs_sbsize); @@ -325,7 +408,7 @@ ffs_reload(mountp, cred, p) brelse(bp); } loop: - for (vp = mountp->mnt_vnodelist.lh_first; vp != NULL; vp = nvp) { + for (vp = mp->mnt_vnodelist.lh_first; vp != NULL; vp = nvp) { nvp = vp->v_mntvnodes.le_next; /* * Step 4: invalidate all inactive vnodes. @@ -356,7 +439,7 @@ ffs_reload(mountp, cred, p) ino_to_fsbo(fs, ip->i_number)); brelse(bp); vput(vp); - if (vp->v_mount != mountp) + if (vp->v_mount != mp) goto loop; } return (0); @@ -380,6 +463,7 @@ ffs_mountfs(devvp, mp, p) int havepart = 0, blks; int error, i, size; int ronly; + u_int strsize; /* * Disallow multiple mounts of the same device. @@ -477,6 +561,24 @@ ffs_mountfs(devvp, mp, p) devvp->v_specflags |= SI_MOUNTEDON; ffs_oldfscompat(fs); ffs_vmlimits(fs); + + /* + * Set FS local "last mounted on" information (NULL pad) + */ + copystr( mp->mnt_stat.f_mntonname, /* mount point*/ + fs->fs_fsmnt, /* copy area*/ + sizeof(fs->fs_fsmnt) - 1, /* max size*/ + &strsize); /* real size*/ + bzero( fs->fs_fsmnt + strsize, sizeof(fs->fs_fsmnt) - strsize); + + if( mp->mnt_flag & MNT_ROOTFS) { + /* + * Root mount; update timestamp in mount structure. + * this will be used by the common root mount code + * to update the system clock. + */ + mp->mnt_time = fs->fs_time; + } if (ronly == 0) ffs_sbupdate(ump, MNT_WAIT); return (0); diff --git a/sys/ufs/lfs/lfs_vfsops.c b/sys/ufs/lfs/lfs_vfsops.c index e571dcd628af..80fb731d6d21 100644 --- a/sys/ufs/lfs/lfs_vfsops.c +++ b/sys/ufs/lfs/lfs_vfsops.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)lfs_vfsops.c 8.7 (Berkeley) 4/16/94 - * $Id: lfs_vfsops.c,v 1.10 1995/03/16 18:16:48 bde Exp $ + * $Id: lfs_vfsops.c,v 1.11 1995/03/19 14:29:20 davidg Exp $ */ #include @@ -78,16 +78,45 @@ struct vfsops lfs_vfsops = { VFS_SET(lfs_vfsops, lfs, MOUNT_LFS, 0); -int -lfs_mountroot() -{ - panic("lfs_mountroot"); /* XXX -- implement */ -} /* - * VFS Operations. + * lfs_mount * - * mount system call + * Called when mounting local physical media + * + * PARAMETERS: + * mountroot + * mp mount point structure + * path NULL (flag for root mount!!!) + * data + * ndp + * p process (user credentials check [statfs]) + * + * mount + * mp mount point structure + * path path to mount point + * data pointer to argument struct in user space + * ndp mount point namei() return (used for + * credentials on reload), reused to look + * up block device. + * p process (user credentials check) + * + * RETURNS: 0 Success + * !0 error number (errno.h) + * + * LOCK STATE: + * + * ENTRY + * mount point is locked + * EXIT + * mount point is locked + * + * NOTES: + * A NULL path can be used for a flag since the mount + * system call will fail with EFAULT in copyinstr in + * namei() if it is a genuine NULL from the user. + * + * Root mounts are not currently supported. */ int lfs_mount(mp, path, data, ndp, p) @@ -102,14 +131,37 @@ lfs_mount(mp, path, data, ndp, p) struct ufsmount *ump = 0; register struct lfs *fs; /* LFS */ u_int size; - int error; + int err; - if (error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args))) - return (error); + /* + * Use NULL path to flag a root mount + */ + if( path == NULL) { + /* + *** + * Mounting root file system + *** + */ + + /* XXX -- implement*/ + panic("lfs_mountroot: can't setup bdevvp for root"); + } + + /* + *** + * Mounting non-root file system or updating a file system + *** + */ + + /* copy in user arguments*/ + if (err = copyin(data, (caddr_t)&args, sizeof (struct ufs_args))) + goto error_1; /* Until LFS can do NFS right. XXX */ - if (args.export.ex_flags & MNT_EXPORTED) - return (EINVAL); + if (args.export.ex_flags & MNT_EXPORTED) { + err = EINVAL; + goto error_1; + } /* * If updating, check whether changing from read-only to @@ -128,9 +180,11 @@ lfs_mount(mp, path, data, ndp, p) #endif if (args.fspec == 0) { /* - * Process export requests. + * Process export requests. Jumping to "success" + * will return the vfs_export() error code. */ - return (vfs_export(mp, &ump->um_export, &args.export)); + err = vfs_export(mp, &ump->um_export, &args.export); + goto success; } } /* @@ -138,28 +192,27 @@ lfs_mount(mp, path, data, ndp, p) * and verify that it refers to a sensible block device. */ NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, p); - if (error = namei(ndp)) - return (error); + if (err = namei(ndp)) + goto error_1; devvp = ndp->ni_vp; if (devvp->v_type != VBLK) { - vrele(devvp); - return (ENOTBLK); + err = ENOTBLK; + goto error_2; } if (major(devvp->v_rdev) >= nblkdev) { - vrele(devvp); - return (ENXIO); + err = ENXIO; + goto error_2; } if ((mp->mnt_flag & MNT_UPDATE) == 0) - error = lfs_mountfs(devvp, mp, p); /* LFS */ + err = lfs_mountfs(devvp, mp, p); /* LFS */ else { if (devvp != ump->um_devvp) - error = EINVAL; /* needs translation */ + err = EINVAL; /* needs translation */ else vrele(devvp); } - if (error) { - vrele(devvp); - return (error); + if (err) { + goto error_2; } ump = VFSTOUFS(mp); fs = ump->um_lfs; /* LFS */ @@ -182,7 +235,18 @@ lfs_mount(mp, path, data, ndp, p) bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); (void) lfs_statfs(mp, &mp->mnt_stat, p); #endif - return (0); + + + +error_2: /* error with devvp held*/ + + /* release devvp before failing*/ + vrele(devvp); + +error_1: /* no state to back out*/ + +success: + return( err); } /* diff --git a/sys/ufs/mfs/mfs_extern.h b/sys/ufs/mfs/mfs_extern.h index fa51177ac9fe..887c3d76404a 100644 --- a/sys/ufs/mfs/mfs_extern.h +++ b/sys/ufs/mfs/mfs_extern.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)mfs_extern.h 8.1 (Berkeley) 6/11/93 - * $Id: mfs_extern.h,v 1.2 1994/08/02 07:54:42 davidg Exp $ + * $Id: mfs_extern.h,v 1.3 1994/08/21 07:16:10 paul Exp $ */ #ifndef _UFS_MFS_MFS_EXTERN_H_ @@ -56,6 +56,8 @@ int mfs_init __P((void)); int mfs_ioctl __P((struct vop_ioctl_args *)); int mfs_mount __P((struct mount *mp, char *path, caddr_t data, struct nameidata *ndp, struct proc *p)); +int mfs_mountfs __P((struct vnode *, struct mount *, struct proc *)); +int mfs_mountroot __P((void)); int mfs_open __P((struct vop_open_args *)); int mfs_print __P((struct vop_print_args *)); /* XXX */ int mfs_start __P((struct mount *mp, int flags, struct proc *p)); diff --git a/sys/ufs/mfs/mfs_vfsops.c b/sys/ufs/mfs/mfs_vfsops.c index cc62f94be894..3213cea85a98 100644 --- a/sys/ufs/mfs/mfs_vfsops.c +++ b/sys/ufs/mfs/mfs_vfsops.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)mfs_vfsops.c 8.4 (Berkeley) 4/16/94 - * $Id: mfs_vfsops.c,v 1.10 1995/08/11 11:31:18 davidg Exp $ + * $Id: mfs_vfsops.c,v 1.11 1995/08/20 10:26:00 davidg Exp $ */ #include @@ -40,11 +40,17 @@ #include #include #include +#include +#include +#include +#include #include #include #include #include +#include + #include #include #include @@ -82,74 +88,14 @@ struct vfsops mfs_vfsops = { VFS_SET(mfs_vfsops, mfs, MOUNT_MFS, 0); -/* - * Called by main() when mfs is going to be mounted as root. - * - * Name is updated by mount(8) after booting. - */ -#define ROOTNAME "mfs_root" - -int -mfs_mountroot() -{ - register struct fs *fs; - register struct mount *mp; - struct proc *p = curproc; /* XXX */ - struct ufsmount *ump; - struct mfsnode *mfsp; - u_int size; - int error; - - /* - * Get vnode for rootdev. - */ - if (bdevvp(rootdev, &rootvp)) - panic("mfs_mountroot: can't setup bdevvp for rootdev"); - - mp = malloc((u_long)sizeof(struct mount), M_MOUNT, M_WAITOK); - bzero((char *)mp, (u_long)sizeof(struct mount)); - mp->mnt_op = &mfs_vfsops; - mfsp = malloc(sizeof *mfsp, M_MFSNODE, M_WAITOK); - rootvp->v_data = mfsp; - rootvp->v_op = mfs_vnodeop_p; - rootvp->v_tag = VT_MFS; - mfsp->mfs_baseoff = mfs_rootbase; - mfsp->mfs_size = mfs_rootsize; - mfsp->mfs_vnode = rootvp; - mfsp->mfs_pid = p->p_pid; - mfsp->mfs_buflist = (struct buf *)0; - if (error = ffs_mountfs(rootvp, mp, p)) { - free(mp, M_MOUNT); - free(mfsp, M_MFSNODE); - return (error); - } - if (error = vfs_lock(mp)) { - (void)ffs_unmount(mp, 0, p); - free(mp, M_MOUNT); - free(mfsp, M_MFSNODE); - return (error); - } - CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list); - mp->mnt_flag |= MNT_ROOTFS; - mp->mnt_vnodecovered = NULLVP; - ump = VFSTOUFS(mp); - fs = ump->um_fs; - bzero(fs->fs_fsmnt, sizeof(fs->fs_fsmnt)); - fs->fs_fsmnt[0] = '/'; - bcopy((caddr_t)fs->fs_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname, - MNAMELEN); - (void) copystr(ROOTNAME, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, - &size); - bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); - (void)ffs_statfs(mp, &mp->mnt_stat, p); - vfs_unlock(mp); - inittodr((time_t)0); - return (0); -} +int vfs_mountroot __P((caddr_t)); /* XXX goes away*/ /* * This is called early in boot to set the base address and size * of the mini-root. + * + * XXX THIS IS A DESIGN ERROR; THIS CODE SHOULD BE MOVED INTO + * XXX THE ROOT MOUNT CODE IN "mfs_mount"!!! */ int mfs_initminiroot(base) @@ -161,7 +107,8 @@ mfs_initminiroot(base) if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE || fs->fs_bsize < sizeof(struct fs)) return (0); - mountroot = mfs_mountroot; + mountroot = vfs_mountroot; /* XXX goes away*/ + mountrootvfsops = &mfs_vfsops; mfs_rootbase = base; mfs_rootsize = fs->fs_fsize * fs->fs_size; rootdev = makedev(255, mfs_minor++); @@ -169,10 +116,43 @@ mfs_initminiroot(base) return (mfs_rootsize); } + /* - * VFS Operations. + * mfs_mount * - * mount system call + * Called when mounting local physical media + * + * PARAMETERS: + * mountroot + * mp mount point structure + * path NULL (flag for root mount!!!) + * data + * ndp + * p process (user credentials check [statfs]) + * + * mount + * mp mount point structure + * path path to mount point + * data pointer to argument struct in user space + * ndp mount point namei() return (used for + * credentials on reload), reused to look + * up block device. + * p process (user credentials check) + * + * RETURNS: 0 Success + * !0 error number (errno.h) + * + * LOCK STATE: + * + * ENTRY + * mount point is locked + * EXIT + * mount point is locked + * + * NOTES: + * A NULL path can be used for a flag since the mount + * system call will fail with EFAULT in copyinstr in + * namei() if it is a genuine NULL from the user. */ /* ARGSUSED */ int @@ -189,40 +169,103 @@ mfs_mount(mp, path, data, ndp, p) register struct fs *fs; register struct mfsnode *mfsp; u_int size; - int flags, error; + int flags, err; - if (error = copyin(data, (caddr_t)&args, sizeof (struct mfs_args))) - return (error); + /* + * Use NULL path to flag a root mount + */ + if( path == NULL) { + /* + *** + * Mounting root file system + *** + */ + + /* Get vnode for root device*/ + if( bdevvp( rootdev, &rootvp)) + panic("mfs_mountroot: can't setup bdevvp for rootdev"); + + /* + * FS specific handling + */ + mfsp = malloc(sizeof *mfsp, M_MFSNODE, M_WAITOK); + rootvp->v_data = mfsp; + rootvp->v_op = mfs_vnodeop_p; + rootvp->v_tag = VT_MFS; + mfsp->mfs_baseoff = mfs_rootbase; + mfsp->mfs_size = mfs_rootsize; + mfsp->mfs_vnode = rootvp; + mfsp->mfs_pid = p->p_pid; + mfsp->mfs_buflist = (struct buf *)0; + + /* + * Attempt mount + */ + if( (err = ffs_mountfs(rootvp, mp, p)) != 0 ) { + /* fs specific cleanup (if any)*/ + rootvp->v_data = NULL; + free(mfsp, M_MFSNODE); + goto error_1; + } + + goto dostatfs; /* success*/ + } + + /* + *** + * Mounting non-root file system or updating a file system + *** + */ + + /* copy in user arguments*/ + if (err = copyin(data, (caddr_t)&args, sizeof (struct mfs_args))) + goto error_1; /* * If updating, check whether changing from read-only to * read/write; if there is no device name, that's all we do. */ if (mp->mnt_flag & MNT_UPDATE) { + /* + ******************** + * UPDATE + ******************** + */ ump = VFSTOUFS(mp); fs = ump->um_fs; if (fs->fs_ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) { flags = WRITECLOSE; if (mp->mnt_flag & MNT_FORCE) flags |= FORCECLOSE; - if (vfs_busy(mp)) - return (EBUSY); - error = ffs_flushfiles(mp, flags, p); + if (vfs_busy(mp)) { + err = EBUSY; + goto error_1; + } + err = ffs_flushfiles(mp, flags, p); vfs_unbusy(mp); - if (error) - return (error); + if (err) + goto error_1; } if (fs->fs_ronly && (mp->mnt_flag & MNT_WANTRDWR)) fs->fs_ronly = 0; #ifdef EXPORTMFS - if (args.fspec == 0) - return (vfs_export(mp, &ump->um_export, &args.export)); + /* if not updating name...*/ + if (args.fspec == 0) { + /* + * Process export requests. Jumping to "success" + * will return the vfs_export() error code. + */ + err = vfs_export(mp, &ump->um_export, &args.export); + goto success; + } #endif - return (0); + + /* XXX MFS does not support name updating*/ + goto success; } - error = getnewvnode(VT_MFS, (struct mount *)0, mfs_vnodeop_p, &devvp); - if (error) - return (error); + err = getnewvnode(VT_MFS, (struct mount *)0, mfs_vnodeop_p, &devvp); + if (err) + goto error_1; devvp->v_type = VBLK; if (checkalias(devvp, makedev(255, mfs_minor++), (struct mount *)0)) panic("mfs_mount: dup dev"); @@ -233,24 +276,55 @@ mfs_mount(mp, path, data, ndp, p) mfsp->mfs_vnode = devvp; mfsp->mfs_pid = p->p_pid; mfsp->mfs_buflist = (struct buf *)0; - if (error = ffs_mountfs(devvp, mp, p)) { + + /* + * Since this is a new mount, we want the names for + * the device and the mount point copied in. If an + * error occurs, the mountpoint is discarded by the + * upper level code. + */ + /* Save "last mounted on" info for mount point (NULL pad)*/ + copyinstr( path, /* mount point*/ + mp->mnt_stat.f_mntonname, /* save area*/ + MNAMELEN - 1, /* max size*/ + &size); /* real size*/ + bzero( mp->mnt_stat.f_mntonname + size, MNAMELEN - size); + + /* Save "mounted from" info for mount point (NULL pad)*/ + copyinstr( args.fspec, /* device name*/ + mp->mnt_stat.f_mntfromname, /* save area*/ + MNAMELEN - 1, /* max size*/ + &size); /* real size*/ + bzero( mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); + + if (err = ffs_mountfs(devvp, mp, p)) { mfsp->mfs_buflist = (struct buf *)-1; - vrele(devvp); - return (error); + goto error_2; } - ump = VFSTOUFS(mp); - fs = ump->um_fs; - (void) copyinstr(path, fs->fs_fsmnt, sizeof(fs->fs_fsmnt) - 1, &size); - bzero(fs->fs_fsmnt + size, sizeof(fs->fs_fsmnt) - size); - bcopy((caddr_t)fs->fs_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname, - MNAMELEN); - (void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, - &size); - bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); - (void) mfs_statfs(mp, &mp->mnt_stat, p); - return (0); + +dostatfs: + /* + * Initialize FS stat information in mount struct; uses both + * mp->mnt_stat.f_mntonname and mp->mnt_stat.f_mntfromname + * + * This code is common to root and non-root mounts + */ + (void) VFS_STATFS(mp, &mp->mnt_stat, p); + + goto success; + +error_2: /* error with devvp held*/ + + /* release devvp before failing*/ + vrele(devvp); + +error_1: /* no state to back out*/ + +success: + return( err); } + int mfs_pri = PWAIT | PCATCH; /* XXX prob. temp */ /* diff --git a/sys/ufs/ufs/dir.h b/sys/ufs/ufs/dir.h index f18eca8dc8aa..3eae47a40511 100644 --- a/sys/ufs/ufs/dir.h +++ b/sys/ufs/ufs/dir.h @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)dir.h 8.2 (Berkeley) 1/21/94 - * $Id: dir.h,v 1.2 1994/08/02 07:54:48 davidg Exp $ + * $Id: dir.h,v 1.3 1994/08/21 07:16:14 paul Exp $ */ #ifndef _UFS_UFS_DIR_H_ @@ -101,15 +101,18 @@ struct direct { * the directory entry. This requires the amount of space in struct direct * without the d_name field, plus enough space for the name with a terminating * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary. + * + * */ +#define DIRECTSIZ(namlen) \ + (((int)&((struct direct *)0)->d_name + \ + ((namlen)+1)*sizeof(((struct direct *)0)->d_name[0]) + 3) & ~3) #if (BYTE_ORDER == LITTLE_ENDIAN) #define DIRSIZ(oldfmt, dp) \ - ((oldfmt) ? \ - ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_type+1 + 3) &~ 3)) : \ - ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))) + ((oldfmt) ? DIRECTSIZ((dp)->d_type) : DIRECTSIZ((dp)->d_namlen)) #else #define DIRSIZ(oldfmt, dp) \ - ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3)) + DIRECTSIZ((dp)->d_namlen) #endif #define OLDDIRFMT 1 #define NEWDIRFMT 0 diff --git a/sys/ufs/ufs/ufs_lookup.c b/sys/ufs/ufs/ufs_lookup.c index 2994c5c7f7c7..045de4b036fc 100644 --- a/sys/ufs/ufs/ufs_lookup.c +++ b/sys/ufs/ufs/ufs_lookup.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)ufs_lookup.c 8.6 (Berkeley) 4/1/94 - * $Id: ufs_lookup.c,v 1.3 1994/10/08 06:57:26 phk Exp $ + * $Id: ufs_lookup.c,v 1.4 1995/07/29 11:43:23 bde Exp $ */ #include @@ -59,7 +59,8 @@ int dirchk = 1; int dirchk = 0; #endif -#define FSFMT(vp) ((vp)->v_mount->mnt_maxsymlinklen <= 0) +/* true if old FS format...*/ +#define OFSFMT(vp) ((vp)->v_mount->mnt_maxsymlinklen <= 0) /* * Convert a component of a pathname into a pointer to a locked inode. @@ -210,8 +211,7 @@ ufs_lookup(ap) if ((nameiop == CREATE || nameiop == RENAME) && (flags & ISLASTCN)) { slotstatus = NONE; - slotneeded = (sizeof(struct direct) - MAXNAMLEN + - cnp->cn_namelen + 3) &~ 3; + slotneeded = DIRECTSIZ(cnp->cn_namelen); } /* @@ -295,7 +295,7 @@ ufs_lookup(ap) int size = ep->d_reclen; if (ep->d_ino != 0) - size -= DIRSIZ(FSFMT(vdp), ep); + size -= DIRSIZ(OFSFMT(vdp), ep); if (size > 0) { if (size >= slotneeded) { slotstatus = FOUND; @@ -319,10 +319,10 @@ ufs_lookup(ap) */ if (ep->d_ino) { # if (BYTE_ORDER == LITTLE_ENDIAN) - if (vdp->v_mount->mnt_maxsymlinklen > 0) - namlen = ep->d_namlen; - else + if (OFSFMT(vdp)) namlen = ep->d_type; + else + namlen = ep->d_namlen; # else namlen = ep->d_namlen; # endif @@ -426,9 +426,9 @@ ufs_lookup(ap) * Check that directory length properly reflects presence * of this entry. */ - if (entryoffsetinblock + DIRSIZ(FSFMT(vdp), ep) > dp->i_size) { + if (entryoffsetinblock + DIRSIZ(OFSFMT(vdp), ep) > dp->i_size) { ufs_dirbad(dp, dp->i_offset, "i_size too small"); - dp->i_size = entryoffsetinblock + DIRSIZ(FSFMT(vdp), ep); + dp->i_size = entryoffsetinblock + DIRSIZ(OFSFMT(vdp), ep); dp->i_flag |= IN_CHANGE | IN_UPDATE; } @@ -604,16 +604,16 @@ ufs_dirbadentry(dp, ep, entryoffsetinblock) int namlen; # if (BYTE_ORDER == LITTLE_ENDIAN) - if (dp->v_mount->mnt_maxsymlinklen > 0) - namlen = ep->d_namlen; - else + if (OFSFMT(dp)) namlen = ep->d_type; + else + namlen = ep->d_namlen; # else namlen = ep->d_namlen; # endif if ((ep->d_reclen & 0x3) != 0 || ep->d_reclen > DIRBLKSIZ - (entryoffsetinblock & (DIRBLKSIZ - 1)) || - ep->d_reclen < DIRSIZ(FSFMT(dp), ep) || namlen > MAXNAMLEN) { + ep->d_reclen < DIRSIZ(OFSFMT(dp), ep) || namlen > MAXNAMLEN) { /*return (1); */ printf("First bad\n"); goto bad; @@ -663,7 +663,7 @@ ufs_direnter(ip, dvp, cnp) newdir.d_ino = ip->i_number; newdir.d_namlen = cnp->cn_namelen; bcopy(cnp->cn_nameptr, newdir.d_name, (unsigned)cnp->cn_namelen + 1); - if (dvp->v_mount->mnt_maxsymlinklen > 0) + if (!OFSFMT(dvp)) newdir.d_type = IFTODT(ip->i_mode); else { newdir.d_type = 0; @@ -673,7 +673,7 @@ ufs_direnter(ip, dvp, cnp) newdir.d_type = tmp; } # endif } - newentrysize = DIRSIZ(FSFMT(dvp), &newdir); + newentrysize = DIRSIZ(OFSFMT(dvp), &newdir); if (dp->i_count == 0) { /* * If dp->i_count is 0, then namei could find no @@ -737,7 +737,7 @@ ufs_direnter(ip, dvp, cnp) * space. */ ep = (struct direct *)dirbuf; - dsize = DIRSIZ(FSFMT(dvp), ep); + dsize = DIRSIZ(OFSFMT(dvp), ep); spacefree = ep->d_reclen - dsize; for (loc = ep->d_reclen; loc < dp->i_count; ) { nep = (struct direct *)(dirbuf + loc); @@ -749,7 +749,7 @@ ufs_direnter(ip, dvp, cnp) /* overwrite; nothing there; header is ours */ spacefree += dsize; } - dsize = DIRSIZ(FSFMT(dvp), nep); + dsize = DIRSIZ(OFSFMT(dvp), nep); spacefree += nep->d_reclen - dsize; loc += nep->d_reclen; bcopy((caddr_t)nep, (caddr_t)ep, dsize); @@ -846,7 +846,7 @@ ufs_dirrewrite(dp, ip, cnp) if (error) return (error); ep->d_ino = ip->i_number; - if (vdp->v_mount->mnt_maxsymlinklen > 0) + if (!OFSFMT(vdp)) ep->d_type = IFTODT(ip->i_mode); error = VOP_BWRITE(bp); dp->i_flag |= IN_CHANGE | IN_UPDATE; @@ -891,10 +891,10 @@ ufs_dirempty(ip, parentino, cred) continue; /* accept only "." and ".." */ # if (BYTE_ORDER == LITTLE_ENDIAN) - if (ITOV(ip)->v_mount->mnt_maxsymlinklen > 0) - namlen = dp->d_namlen; - else + if (OFSFMT(ITOV(ip))) namlen = dp->d_type; + else + namlen = dp->d_namlen; # else namlen = dp->d_namlen; # endif @@ -951,10 +951,10 @@ ufs_checkpath(source, target, cred) if (error != 0) break; # if (BYTE_ORDER == LITTLE_ENDIAN) - if (vp->v_mount->mnt_maxsymlinklen > 0) - namlen = dirbuf.dotdot_namlen; - else + if (OFSFMT(vp)) namlen = dirbuf.dotdot_type; + else + namlen = dirbuf.dotdot_namlen; # else namlen = dirbuf.dotdot_namlen; # endif diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index 37000ccbb132..371cd06a01bf 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)ufs_vnops.c 8.10 (Berkeley) 4/1/94 - * $Id: ufs_vnops.c,v 1.25 1995/06/28 07:06:55 davidg Exp $ + * $Id: ufs_vnops.c,v 1.26 1995/08/01 18:51:02 davidg Exp $ */ #include @@ -1123,12 +1123,12 @@ ufs_rename(ap) * A virgin directory (no blushing please). */ static struct dirtemplate mastertemplate = { - 0, 12, DT_DIR, 1, ".", - 0, DIRBLKSIZ - 12, DT_DIR, 2, ".." + 0, 12, DT_DIR, 1, { '.', 0 }, + 0, DIRBLKSIZ - 12, DT_DIR, 2, { '.', '.', 0 } }; static struct odirtemplate omastertemplate = { - 0, 12, 1, ".", - 0, DIRBLKSIZ - 12, 2, ".." + 0, 12, 1, { '.', 0 }, + 0, DIRBLKSIZ - 12, 2, { '.', '.', 0 } }; /* diff --git a/sys/vm/vm_extern.h b/sys/vm/vm_extern.h index 71c518058e3c..b6c089774ace 100644 --- a/sys/vm/vm_extern.h +++ b/sys/vm/vm_extern.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)vm_extern.h 8.2 (Berkeley) 1/12/94 - * $Id: vm_extern.h,v 1.16 1995/07/10 08:53:16 davidg Exp $ + * $Id: vm_extern.h,v 1.17 1995/07/13 08:48:19 davidg Exp $ */ #ifndef _VM_EXTERN_H_ @@ -91,8 +91,6 @@ void vm_fault_copy_entry __P((vm_map_t, vm_map_t, vm_map_entry_t, vm_map_entry_t void vm_fault_unwire __P((vm_map_t, vm_offset_t, vm_offset_t)); int vm_fault_wire __P((vm_map_t, vm_offset_t, vm_offset_t)); int vm_fork __P((struct proc *, struct proc *, int)); -void vm_init_limits __P((struct proc *)); -void vm_mem_init __P((void)); int vm_mmap __P((vm_map_t, vm_offset_t *, vm_size_t, vm_prot_t, vm_prot_t, int, caddr_t, vm_offset_t)); vm_offset_t vm_page_alloc_contig __P((vm_offset_t, vm_offset_t, vm_offset_t, vm_offset_t)); void vm_set_page_size __P((void)); diff --git a/sys/vm/vm_glue.c b/sys/vm/vm_glue.c index cd4feac0bcc0..b570aa0f5841 100644 --- a/sys/vm/vm_glue.c +++ b/sys/vm/vm_glue.c @@ -59,7 +59,7 @@ * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. * - * $Id: vm_glue.c,v 1.22 1995/07/10 08:53:20 davidg Exp $ + * $Id: vm_glue.c,v 1.23 1995/07/13 08:48:21 davidg Exp $ */ #include @@ -81,6 +81,24 @@ #include #include +/* + * System initialization + * + * Note: proc0 from proc.h + */ + +static void vm_init_limits __P((caddr_t)); +SYSINIT(vm_limits, SI_SUB_VM_CONF, SI_ORDER_FIRST, vm_init_limits, (caddr_t)&proc0) + +/* + * THIS MUST BE THE LAST INITIALIZATION ITEM!!! + * + * Note: run scheduling should be divorced from the vm system. + */ +static void scheduler __P((caddr_t)); +SYSINIT(scheduler, SI_SUB_RUN_SCHEDULER, SI_ORDER_FIRST, scheduler, NULL) + + extern char kstack[]; /* vm_map_t upages_map; */ @@ -264,11 +282,14 @@ vm_fork(p1, p2, isvfork) /* * Set default limits for VM system. * Called for proc 0, and then inherited by all others. + * + * XXX should probably act directly on proc0. */ -void -vm_init_limits(p) - register struct proc *p; +static void +vm_init_limits( udata) +caddr_t udata; { + register struct proc *p = (struct proc *)udata; int rss_limit; /* @@ -341,8 +362,10 @@ faultin(p) * is enough space for them. Of course, if a process waits for a long * time, it will be swapped in anyway. */ -void -scheduler() +/* ARGSUSED*/ +static void +scheduler( udata) +caddr_t udata; /* not used*/ { register struct proc *p; register int pri; diff --git a/sys/vm/vm_init.c b/sys/vm/vm_init.c index 51fcf305d1f9..ea41d949809b 100644 --- a/sys/vm/vm_init.c +++ b/sys/vm/vm_init.c @@ -61,7 +61,7 @@ * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. * - * $Id: vm_init.c,v 1.6 1995/03/16 18:17:11 bde Exp $ + * $Id: vm_init.c,v 1.7 1995/07/13 08:48:24 davidg Exp $ */ /* @@ -69,6 +69,7 @@ */ #include +#include #include #include @@ -76,6 +77,13 @@ #include #include +/* + * System initialization + */ + +static void vm_mem_init __P((caddr_t)); +SYSINIT(vm_mem, SI_SUB_VM, SI_ORDER_FIRST, vm_mem_init, NULL) + /* * vm_init initializes the virtual memory system. * This is done only by the first cpu up. @@ -83,8 +91,10 @@ * The start and end address of physical memory is passed in. */ -void -vm_mem_init() +/* ARGSUSED*/ +static void +vm_mem_init( udata) +caddr_t udata; /* not used*/ { /* * Initializes resident memory structures. From here on, all physical diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c index 92e5713f8cc6..e7ba4083c4e1 100644 --- a/sys/vm/vm_pageout.c +++ b/sys/vm/vm_pageout.c @@ -65,7 +65,7 @@ * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. * - * $Id: vm_pageout.c,v 1.52 1995/07/10 08:53:22 davidg Exp $ + * $Id: vm_pageout.c,v 1.53 1995/07/13 08:48:40 davidg Exp $ */ /* @@ -89,6 +89,33 @@ #include #include +/* + * System initialization + */ + +/* the kernel process "vm_pageout"*/ +static void vm_pageout __P((void)); +struct proc *pageproc; + +static struct kproc_desc page_kp = { + "pagedaemon", + vm_pageout, + &pageproc +}; +SYSINIT_KT(pagedaemon, SI_SUB_KTHREAD_PAGE, SI_ORDER_FIRST, kproc_start, (caddr_t)&page_kp) + +/* the kernel process "vm_daemon"*/ +static void vm_daemon __P((void)); +struct proc *vmproc; + +static struct kproc_desc vm_kp = { + "vmdaemon", + vm_daemon, + &vmproc +}; +SYSINIT_KT(vmdaemon, SI_SUB_KTHREAD_VM, SI_ORDER_FIRST, kproc_start, (caddr_t)&vm_kp) + + int vm_pages_needed; /* Event on which pageout daemon sleeps */ int vm_pageout_pages_needed; /* flag saying that the pageout daemon needs pages */ @@ -789,7 +816,7 @@ vm_pageout_scan() /* * vm_pageout is the high level pageout daemon. */ -void +static void vm_pageout() { (void) spl0(); @@ -853,7 +880,7 @@ vm_pageout() } } -void +static void vm_daemon() { vm_object_t object; diff --git a/sys/vm/vm_pageout.h b/sys/vm/vm_pageout.h index b9084978728f..b1ef37c9ad16 100644 --- a/sys/vm/vm_pageout.h +++ b/sys/vm/vm_pageout.h @@ -61,7 +61,7 @@ * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. * - * $Id: vm_pageout.h,v 1.12 1995/05/30 08:16:20 rgrimes Exp $ + * $Id: vm_pageout.h,v 1.13 1995/07/13 08:48:41 davidg Exp $ */ #ifndef _VM_VM_PAGEOUT_H_ @@ -123,7 +123,6 @@ vm_wait() #ifdef KERNEL -void vm_daemon __P((void)); int vm_pageout_scan __P((void)); void vm_pageout_page __P((vm_page_t, vm_object_t)); void vm_pageout_cluster __P((vm_page_t, vm_object_t));