diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index 51fb178c48bd..8557739b8738 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.53 1994/08/18 22:34:40 wollman Exp $ + * $Id: machdep.c,v 1.54 1994/08/19 11:45:15 davidg Exp $ */ #include "npx.h" @@ -676,7 +676,6 @@ boot(arghowto) register int howto; /* r11 == how to boot */ register int devtype; /* r10 == major of root dev */ extern int cold; - int nomsg = 1; if (cold) { printf("hit reset please"); @@ -689,20 +688,13 @@ boot(arghowto) waittime = 0; (void) splnet(); - printf("syncing disks... "); + printf("\nsyncing disks... "); /* * Release inodes held by texts before update. */ if (panicstr == 0) vnode_pager_umount(NULL); sync(curproc, NULL, NULL); - /* - * Unmount filesystems - */ -#if 0 - if (panicstr == 0) - vfs_unmountall(); -#endif for (iter = 0; iter < 20; iter++) { nbusy = 0; @@ -711,18 +703,24 @@ boot(arghowto) nbusy++; if (nbusy == 0) break; - if (nomsg) { - printf("updating disks before rebooting... "); - nomsg = 0; - } printf("%d ", nbusy); DELAY(40000 * iter); } - if (nbusy) + if (nbusy) { + /* + * Failed to sync all blocks. Indicate this and don't + * unmount filesystems (thus forcing an fsck on reboot). + */ printf("giving up\n"); - else + } else { printf("done\n"); - DELAY(10000); /* wait for printf to finish */ + /* + * Unmount filesystems + */ + if (panicstr == 0) + vfs_unmountall(); + } + DELAY(100000); /* wait for console output to finish */ } splhigh(); devtype = major(rootdev); diff --git a/sys/fs/cd9660/cd9660_vfsops.c b/sys/fs/cd9660/cd9660_vfsops.c index 90e26796876b..7f2d1c3dc153 100644 --- a/sys/fs/cd9660/cd9660_vfsops.c +++ b/sys/fs/cd9660/cd9660_vfsops.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)cd9660_vfsops.c 8.3 (Berkeley) 1/31/94 - * $Id: cd9660_vfsops.c,v 1.3 1994/08/02 07:41:33 davidg Exp $ + * $Id: cd9660_vfsops.c,v 1.4 1994/08/20 03:48:45 davidg Exp $ */ #include @@ -403,7 +403,7 @@ cd9660_unmount(mp, mntflags, p) int i, error, ronly, flags = 0; if (mntflags & MNT_FORCE) { - if (!iso_doforce || (mp->mnt_flag & MNT_ROOTFS)) + if (!iso_doforce) return (EINVAL); flags |= FORCECLOSE; } diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index 51fb178c48bd..8557739b8738 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.53 1994/08/18 22:34:40 wollman Exp $ + * $Id: machdep.c,v 1.54 1994/08/19 11:45:15 davidg Exp $ */ #include "npx.h" @@ -676,7 +676,6 @@ boot(arghowto) register int howto; /* r11 == how to boot */ register int devtype; /* r10 == major of root dev */ extern int cold; - int nomsg = 1; if (cold) { printf("hit reset please"); @@ -689,20 +688,13 @@ boot(arghowto) waittime = 0; (void) splnet(); - printf("syncing disks... "); + printf("\nsyncing disks... "); /* * Release inodes held by texts before update. */ if (panicstr == 0) vnode_pager_umount(NULL); sync(curproc, NULL, NULL); - /* - * Unmount filesystems - */ -#if 0 - if (panicstr == 0) - vfs_unmountall(); -#endif for (iter = 0; iter < 20; iter++) { nbusy = 0; @@ -711,18 +703,24 @@ boot(arghowto) nbusy++; if (nbusy == 0) break; - if (nomsg) { - printf("updating disks before rebooting... "); - nomsg = 0; - } printf("%d ", nbusy); DELAY(40000 * iter); } - if (nbusy) + if (nbusy) { + /* + * Failed to sync all blocks. Indicate this and don't + * unmount filesystems (thus forcing an fsck on reboot). + */ printf("giving up\n"); - else + } else { printf("done\n"); - DELAY(10000); /* wait for printf to finish */ + /* + * Unmount filesystems + */ + if (panicstr == 0) + vfs_unmountall(); + } + DELAY(100000); /* wait for console output to finish */ } splhigh(); devtype = major(rootdev); diff --git a/sys/isofs/cd9660/cd9660_vfsops.c b/sys/isofs/cd9660/cd9660_vfsops.c index 90e26796876b..7f2d1c3dc153 100644 --- a/sys/isofs/cd9660/cd9660_vfsops.c +++ b/sys/isofs/cd9660/cd9660_vfsops.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)cd9660_vfsops.c 8.3 (Berkeley) 1/31/94 - * $Id: cd9660_vfsops.c,v 1.3 1994/08/02 07:41:33 davidg Exp $ + * $Id: cd9660_vfsops.c,v 1.4 1994/08/20 03:48:45 davidg Exp $ */ #include @@ -403,7 +403,7 @@ cd9660_unmount(mp, mntflags, p) int i, error, ronly, flags = 0; if (mntflags & MNT_FORCE) { - if (!iso_doforce || (mp->mnt_flag & MNT_ROOTFS)) + if (!iso_doforce) return (EINVAL); flags |= FORCECLOSE; } diff --git a/sys/kern/vfs_conf.c b/sys/kern/vfs_conf.c index 70acd9b8b5ef..70377ed45cb5 100644 --- a/sys/kern/vfs_conf.c +++ b/sys/kern/vfs_conf.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)vfs_conf.c 8.8 (Berkeley) 3/31/94 - * $Id$ + * $Id: vfs_conf.c,v 1.2 1994/08/02 07:43:19 davidg Exp $ */ #include @@ -48,10 +48,6 @@ int (*mountroot)() = ffs_mountroot; #endif -/* - * These define the root filesystem and device. - */ -struct mount *rootfs; struct vnode *rootvnode; /* diff --git a/sys/kern/vfs_export.c b/sys/kern/vfs_export.c index d088b28bf317..e26b0303f20b 100644 --- a/sys/kern/vfs_export.c +++ b/sys/kern/vfs_export.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_subr.c 8.13 (Berkeley) 4/18/94 - * $Id: vfs_subr.c,v 1.3 1994/08/02 07:43:27 davidg Exp $ + * $Id: vfs_subr.c,v 1.4 1994/08/18 22:35:09 wollman Exp $ */ /* @@ -169,6 +169,70 @@ vfs_unbusy(mp) } } +void +vfs_unmountroot(rootfs) + struct mount *rootfs; +{ + struct mount *mp = rootfs; + int error; + + if (vfs_busy(mp)) { + printf("failed to unmount root\n"); + return; + } + + mp->mnt_flag |= MNT_UNMOUNT; + if (error = vfs_lock(mp)) { + printf("lock of root filesystem failed (%d)\n", error); + return; + } + + vnode_pager_umount(mp); /* release cached vnodes */ + cache_purgevfs(mp); /* remove cache entries for this file sys */ + + if (error = VFS_SYNC(mp, MNT_WAIT, initproc->p_ucred, initproc)) + printf("sync of root filesystem failed (%d)\n", error); + + if (error = VFS_UNMOUNT(mp, MNT_FORCE, initproc)) + printf("unmount of root filesystem failed (%d)\n", error); + + mp->mnt_flag &= ~MNT_UNMOUNT; + vfs_unbusy(mp); +} + +/* + * Unmount all filesystems. Should only be called by halt(). + */ +void +vfs_unmountall() +{ + struct mount *mp, *mp_next, *rootfs = NULL; + int error; + + /* unmount all but rootfs */ + for (mp = mountlist.tqh_first; mp != NULL; mp = mp_next) { + mp_next = mp->mnt_list.tqe_next; + + if (mp->mnt_flag & MNT_ROOTFS) { + rootfs = mp; + continue; + } + + error = dounmount(mp, MNT_FORCE, initproc); + if (error) { + printf("unmount of %s failed (%d)\n", + mp->mnt_stat.f_mntonname, error); + } + } + + /* and finally... */ + if (rootfs) { + vfs_unmountroot(rootfs); + } else { + printf("no root filesystem\n"); + } +} + /* * Lookup a mount point by filesystem identifier. */ diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c index 7c35066ac4bd..ae2fd9cf6276 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$ + * $Id: vfs_syscalls.c,v 1.3 1994/08/02 07:43:31 davidg Exp $ */ #include @@ -238,6 +238,13 @@ unmount(p, uap, retval) } mp = vp->v_mount; vput(vp); + + /* + * Don't allow unmount of the root filesystem + */ + if (mp->mnt_flag & MNT_ROOTFS) + return (EINVAL); + return (dounmount(mp, uap->flags, p)); } diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c index 70acd9b8b5ef..70377ed45cb5 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)vfs_conf.c 8.8 (Berkeley) 3/31/94 - * $Id$ + * $Id: vfs_conf.c,v 1.2 1994/08/02 07:43:19 davidg Exp $ */ #include @@ -48,10 +48,6 @@ int (*mountroot)() = ffs_mountroot; #endif -/* - * These define the root filesystem and device. - */ -struct mount *rootfs; struct vnode *rootvnode; /* diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index d088b28bf317..e26b0303f20b 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_subr.c 8.13 (Berkeley) 4/18/94 - * $Id: vfs_subr.c,v 1.3 1994/08/02 07:43:27 davidg Exp $ + * $Id: vfs_subr.c,v 1.4 1994/08/18 22:35:09 wollman Exp $ */ /* @@ -169,6 +169,70 @@ vfs_unbusy(mp) } } +void +vfs_unmountroot(rootfs) + struct mount *rootfs; +{ + struct mount *mp = rootfs; + int error; + + if (vfs_busy(mp)) { + printf("failed to unmount root\n"); + return; + } + + mp->mnt_flag |= MNT_UNMOUNT; + if (error = vfs_lock(mp)) { + printf("lock of root filesystem failed (%d)\n", error); + return; + } + + vnode_pager_umount(mp); /* release cached vnodes */ + cache_purgevfs(mp); /* remove cache entries for this file sys */ + + if (error = VFS_SYNC(mp, MNT_WAIT, initproc->p_ucred, initproc)) + printf("sync of root filesystem failed (%d)\n", error); + + if (error = VFS_UNMOUNT(mp, MNT_FORCE, initproc)) + printf("unmount of root filesystem failed (%d)\n", error); + + mp->mnt_flag &= ~MNT_UNMOUNT; + vfs_unbusy(mp); +} + +/* + * Unmount all filesystems. Should only be called by halt(). + */ +void +vfs_unmountall() +{ + struct mount *mp, *mp_next, *rootfs = NULL; + int error; + + /* unmount all but rootfs */ + for (mp = mountlist.tqh_first; mp != NULL; mp = mp_next) { + mp_next = mp->mnt_list.tqe_next; + + if (mp->mnt_flag & MNT_ROOTFS) { + rootfs = mp; + continue; + } + + error = dounmount(mp, MNT_FORCE, initproc); + if (error) { + printf("unmount of %s failed (%d)\n", + mp->mnt_stat.f_mntonname, error); + } + } + + /* and finally... */ + if (rootfs) { + vfs_unmountroot(rootfs); + } else { + printf("no root filesystem\n"); + } +} + /* * Lookup a mount point by filesystem identifier. */ diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 7c35066ac4bd..ae2fd9cf6276 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$ + * $Id: vfs_syscalls.c,v 1.3 1994/08/02 07:43:31 davidg Exp $ */ #include @@ -238,6 +238,13 @@ unmount(p, uap, retval) } mp = vp->v_mount; vput(vp); + + /* + * Don't allow unmount of the root filesystem + */ + if (mp->mnt_flag & MNT_ROOTFS) + return (EINVAL); + return (dounmount(mp, uap->flags, p)); } diff --git a/sys/nfs/nfs_vfsops.c b/sys/nfs/nfs_vfsops.c index d806e26a5330..1d373ce5ebde 100644 --- a/sys/nfs/nfs_vfsops.c +++ b/sys/nfs/nfs_vfsops.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_vfsops.c 8.3 (Berkeley) 1/4/94 - * $Id$ + * $Id: nfs_vfsops.c,v 1.2 1994/08/02 07:52:16 davidg Exp $ */ #include @@ -542,7 +542,7 @@ nfs_unmount(mp, mntflags, p) extern int doforce; if (mntflags & MNT_FORCE) { - if (!doforce || (mp->mnt_flag & MNT_ROOTFS)) + if (!doforce) return (EINVAL); flags |= FORCECLOSE; } diff --git a/sys/nfsclient/nfs_vfsops.c b/sys/nfsclient/nfs_vfsops.c index d806e26a5330..1d373ce5ebde 100644 --- a/sys/nfsclient/nfs_vfsops.c +++ b/sys/nfsclient/nfs_vfsops.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_vfsops.c 8.3 (Berkeley) 1/4/94 - * $Id$ + * $Id: nfs_vfsops.c,v 1.2 1994/08/02 07:52:16 davidg Exp $ */ #include @@ -542,7 +542,7 @@ nfs_unmount(mp, mntflags, p) extern int doforce; if (mntflags & MNT_FORCE) { - if (!doforce || (mp->mnt_flag & MNT_ROOTFS)) + if (!doforce) return (EINVAL); flags |= FORCECLOSE; } diff --git a/sys/sys/mount.h b/sys/sys/mount.h index aec0f43cd8bf..5b3743d12118 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$ + * $Id: mount.h,v 1.2 1994/08/02 07:53:15 davidg Exp $ */ #ifndef KERNEL @@ -407,6 +407,7 @@ extern struct vfsops *vfssw[]; /* filesystem type table */ #include __BEGIN_DECLS +int dounmount __P((struct mount *, int, struct proc *)); int fstatfs __P((int, struct statfs *)); int getfh __P((const char *, fhandle_t *)); int getfsstat __P((struct statfs *, long, int)); diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c index bd1ad2bb6ba0..8fd8ca114d4a 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.3 1994/08/02 07:54:24 davidg Exp $ + * $Id: ffs_vfsops.c,v 1.4 1994/08/18 22:35:54 wollman Exp $ */ #include @@ -177,6 +177,10 @@ ffs_mount(mp, path, data, ndp, p) return (error); if (fs->fs_ronly && (mp->mnt_flag & MNT_WANTRDWR)) fs->fs_ronly = 0; + if (fs->fs_ronly == 0) { + fs->fs_clean = 0; + ffs_sbupdate(ump, MNT_WAIT); + } if (args.fspec == 0) { /* * Process export requests. @@ -394,8 +398,13 @@ ffs_mountfs(devvp, mp, p) bp = NULL; fs = ump->um_fs; fs->fs_ronly = ronly; - if (ronly == 0) + if (!fs->fs_clean) { + printf("WARNING: %s was not properly dismounted\n",fs->fs_fsmnt); + } + if (ronly == 0) { fs->fs_fmod = 1; + fs->fs_clean = 0; + } blks = howmany(fs->fs_cssize, fs->fs_fsize); base = space = malloc((u_long)fs->fs_cssize, M_UFSMNT, M_WAITOK); @@ -430,6 +439,8 @@ ffs_mountfs(devvp, mp, p) ump->um_quotas[i] = NULLVP; devvp->v_specflags |= SI_MOUNTEDON; ffs_oldfscompat(fs); + if (ronly == 0) + ffs_sbupdate(ump, MNT_WAIT); return (0); out: if (bp) @@ -487,15 +498,17 @@ ffs_unmount(mp, mntflags, p) flags = 0; if (mntflags & MNT_FORCE) { - if (mp->mnt_flag & MNT_ROOTFS) - return (EINVAL); flags |= FORCECLOSE; } if (error = ffs_flushfiles(mp, flags, p)) return (error); ump = VFSTOUFS(mp); fs = ump->um_fs; - ronly = !fs->fs_ronly; + ronly = fs->fs_ronly; + if (!ronly) { + fs->fs_clean = 1; + ffs_sbupdate(ump, MNT_WAIT); + } ump->um_devvp->v_specflags &= ~SI_MOUNTEDON; error = VOP_CLOSE(ump->um_devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p); diff --git a/sys/ufs/lfs/lfs_vfsops.c b/sys/ufs/lfs/lfs_vfsops.c index 02986661496e..72556d24c980 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.3 1994/08/02 07:54:38 davidg Exp $ + * $Id: lfs_vfsops.c,v 1.4 1994/08/20 03:49:02 davidg Exp $ */ #include @@ -326,7 +326,7 @@ lfs_unmount(mp, mntflags, p) flags = 0; if (mntflags & MNT_FORCE) { - if (!doforce || (mp->mnt_flag & MNT_ROOTFS)) + if (!doforce) return (EINVAL); flags |= FORCECLOSE; } @@ -358,7 +358,7 @@ lfs_unmount(mp, mntflags, p) vrele(fs->lfs_ivnode); vgone(fs->lfs_ivnode); - ronly = !fs->lfs_ronly; + ronly = fs->lfs_ronly; ump->um_devvp->v_specflags &= ~SI_MOUNTEDON; error = VOP_CLOSE(ump->um_devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p);