VFS: fix reboot panic with mounted FUSE FS
Upon reboot VFS semi-exits all processes and unmounts the file system. However, upon unmount, exiting FUSE file systems might need service from the file system (due to libc). As the FUSE process is halfway the exit procedure, it doesn't have a valid root directory and working directory. Trying to do system calls then triggers a sanity check in VFS. This fix first exits normal processes which should then allow for unmounting FUSE file systems. Then VFS exits all processes including File Servers and unmounts the rest of the file system.
This commit is contained in:
parent
badec36b33
commit
ed23a7a7d2
3 changed files with 27 additions and 7 deletions
|
@ -348,19 +348,36 @@ int do_fsync()
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
void pm_reboot()
|
void pm_reboot()
|
||||||
{
|
{
|
||||||
/* Perform the VFS side of the reboot call. */
|
/* Perform the VFS side of the reboot call. */
|
||||||
int i;
|
int i;
|
||||||
struct fproc *rfp;
|
struct fproc *rfp;
|
||||||
|
|
||||||
do_sync();
|
do_sync();
|
||||||
|
|
||||||
/* Do exit processing for all leftover processes and servers,
|
/* Do exit processing for all leftover processes and servers, but don't
|
||||||
* but don't actually exit them (if they were really gone, PM
|
* actually exit them (if they were really gone, PM will tell us about it).
|
||||||
* 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++) {
|
for (i = 0; i < NR_PROCS; i++) {
|
||||||
rfp = &fproc[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
|
/* Don't just free the proc right away, but let it finish what it was
|
||||||
* doing first */
|
* doing first */
|
||||||
lock_proc(rfp, 0);
|
lock_proc(rfp, 0);
|
||||||
|
@ -370,7 +387,8 @@ void pm_reboot()
|
||||||
}
|
}
|
||||||
|
|
||||||
do_sync();
|
do_sync();
|
||||||
unmount_all();
|
unmount_all(1 /* Force */);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
|
|
|
@ -533,7 +533,7 @@ int unmount(
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* unmount_all *
|
* unmount_all *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
void unmount_all(void)
|
void unmount_all(int force)
|
||||||
{
|
{
|
||||||
/* Unmount all filesystems. File systems are mounted on other file systems,
|
/* 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.
|
* 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 */
|
/* Verify nothing is locked anymore */
|
||||||
check_vnode_locks();
|
check_vnode_locks();
|
||||||
check_vmnt_locks();
|
check_vmnt_locks();
|
||||||
|
|
|
@ -154,7 +154,7 @@ void mount_pfs(void);
|
||||||
int mount_fs(dev_t dev, char fullpath[PATH_MAX+1], endpoint_t fs_e, int
|
int mount_fs(dev_t dev, char fullpath[PATH_MAX+1], endpoint_t fs_e, int
|
||||||
rdonly, char mount_label[LABEL_MAX]);
|
rdonly, char mount_label[LABEL_MAX]);
|
||||||
int unmount(dev_t dev, char label[LABEL_MAX]);
|
int unmount(dev_t dev, char label[LABEL_MAX]);
|
||||||
void unmount_all(void);
|
void unmount_all(int force);
|
||||||
|
|
||||||
/* open.c */
|
/* open.c */
|
||||||
int do_close(void);
|
int do_close(void);
|
||||||
|
|
Loading…
Reference in a new issue