diff --git a/servers/vfs/misc.c b/servers/vfs/misc.c index 04c799f71..f32ec88e2 100644 --- a/servers/vfs/misc.c +++ b/servers/vfs/misc.c @@ -348,19 +348,36 @@ int do_fsync() *===========================================================================*/ void pm_reboot() { - /* Perform the VFS side of the reboot call. */ +/* Perform the VFS side of the reboot call. */ int i; struct fproc *rfp; do_sync(); - /* Do exit processing for all leftover processes and servers, - * but don't actually exit them (if they were really gone, PM - * will tell us about it). + /* Do exit processing for all leftover processes and servers, but don't + * actually exit them (if they were really gone, PM will tell us about it). + * Skip processes that handle parts of the file system; we first need to give + * them the chance to unmount (which should be possible as all normal + * processes have no open files anymore). */ for (i = 0; i < NR_PROCS; i++) { rfp = &fproc[i]; + /* Don't just free the proc right away, but let it finish what it was + * doing first */ + lock_proc(rfp, 0); + if (rfp->fp_endpoint != NONE && find_vmnt(rfp->fp_endpoint) == NULL) + free_proc(rfp, 0); + unlock_proc(rfp); + } + + do_sync(); + unmount_all(0 /* Don't force */); + + /* Try to exit all processes again including File Servers */ + for (i = 0; i < NR_PROCS; i++) { + rfp = &fproc[i]; + /* Don't just free the proc right away, but let it finish what it was * doing first */ lock_proc(rfp, 0); @@ -370,7 +387,8 @@ void pm_reboot() } do_sync(); - unmount_all(); + unmount_all(1 /* Force */); + } /*===========================================================================* diff --git a/servers/vfs/mount.c b/servers/vfs/mount.c index 7956c24fb..7b14b865b 100644 --- a/servers/vfs/mount.c +++ b/servers/vfs/mount.c @@ -533,7 +533,7 @@ int unmount( /*===========================================================================* * unmount_all * *===========================================================================*/ -void unmount_all(void) +void unmount_all(int force) { /* Unmount all filesystems. File systems are mounted on other file systems, * so you have to pull off the loose bits repeatedly to get it all undone. @@ -551,6 +551,8 @@ void unmount_all(void) } } + if (!force) return; + /* Verify nothing is locked anymore */ check_vnode_locks(); check_vmnt_locks(); diff --git a/servers/vfs/proto.h b/servers/vfs/proto.h index 74b4b8ab8..281200514 100644 --- a/servers/vfs/proto.h +++ b/servers/vfs/proto.h @@ -154,7 +154,7 @@ void mount_pfs(void); int mount_fs(dev_t dev, char fullpath[PATH_MAX+1], endpoint_t fs_e, int rdonly, char mount_label[LABEL_MAX]); int unmount(dev_t dev, char label[LABEL_MAX]); -void unmount_all(void); +void unmount_all(int force); /* open.c */ int do_close(void);