mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-18 10:35:55 +00:00
Make vfs_unmountall() unmount /dev after /, not before. The only
reason this didn't result in an unclean shutdown is that devfs ignores MNT_FORCE flag. Reviewed by: kib@ MFC after: 1 month Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D3467
This commit is contained in:
parent
e3c074a017
commit
c9ba65040f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=287107
@ -1359,6 +1359,8 @@ dounmount(struct mount *mp, int flags, struct thread *td)
|
||||
vput(coveredvp);
|
||||
}
|
||||
vfs_event_signal(NULL, VQ_UNMOUNT, 0);
|
||||
if (mp == rootdevmp)
|
||||
rootdevmp = NULL;
|
||||
vfs_mount_destroy(mp);
|
||||
return (0);
|
||||
}
|
||||
|
@ -95,6 +95,11 @@ static struct mntarg *parse_mountroot_options(struct mntarg *, const char *);
|
||||
*/
|
||||
struct vnode *rootvnode;
|
||||
|
||||
/*
|
||||
* Mount of the system's /dev.
|
||||
*/
|
||||
struct mount *rootdevmp;
|
||||
|
||||
char *rootdevnames[2] = {NULL, NULL};
|
||||
|
||||
struct mtx root_holds_mtx;
|
||||
@ -236,6 +241,7 @@ vfs_mountroot_devfs(struct thread *td, struct mount **mpp)
|
||||
mtx_unlock(&mountlist_mtx);
|
||||
|
||||
*mpp = mp;
|
||||
rootdevmp = mp;
|
||||
set_rootvnode();
|
||||
|
||||
error = kern_symlinkat(td, "/", AT_FDCWD, "dev", UIO_SYSSPACE);
|
||||
|
@ -3543,6 +3543,21 @@ SYSCTL_PROC(_kern, KERN_VNODE, vnode, CTLTYPE_OPAQUE | CTLFLAG_RD |
|
||||
"");
|
||||
#endif
|
||||
|
||||
static void
|
||||
unmount_or_warn(struct mount *mp)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = dounmount(mp, MNT_FORCE, curthread);
|
||||
if (error != 0) {
|
||||
printf("unmount of %s failed (", mp->mnt_stat.f_mntonname);
|
||||
if (error == EBUSY)
|
||||
printf("BUSY)\n");
|
||||
else
|
||||
printf("%d)\n", error);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Unmount all filesystems. The list is traversed in reverse order
|
||||
* of mounting to avoid dependencies.
|
||||
@ -3550,42 +3565,28 @@ SYSCTL_PROC(_kern, KERN_VNODE, vnode, CTLTYPE_OPAQUE | CTLFLAG_RD |
|
||||
void
|
||||
vfs_unmountall(void)
|
||||
{
|
||||
struct mount *mp;
|
||||
struct thread *td;
|
||||
int error;
|
||||
struct mount *mp, *tmp;
|
||||
|
||||
CTR1(KTR_VFS, "%s: unmounting all filesystems", __func__);
|
||||
td = curthread;
|
||||
|
||||
/*
|
||||
* Since this only runs when rebooting, it is not interlocked.
|
||||
*/
|
||||
while(!TAILQ_EMPTY(&mountlist)) {
|
||||
mp = TAILQ_LAST(&mountlist, mntlist);
|
||||
TAILQ_FOREACH_REVERSE_SAFE(mp, &mountlist, mntlist, mnt_list, tmp) {
|
||||
vfs_ref(mp);
|
||||
error = dounmount(mp, MNT_FORCE, td);
|
||||
if (error != 0) {
|
||||
TAILQ_REMOVE(&mountlist, mp, mnt_list);
|
||||
/*
|
||||
* XXX: Due to the way in which we mount the root
|
||||
* file system off of devfs, devfs will generate a
|
||||
* "busy" warning when we try to unmount it before
|
||||
* the root. Don't print a warning as a result in
|
||||
* order to avoid false positive errors that may
|
||||
* cause needless upset.
|
||||
*/
|
||||
if (strcmp(mp->mnt_vfc->vfc_name, "devfs") != 0) {
|
||||
printf("unmount of %s failed (",
|
||||
mp->mnt_stat.f_mntonname);
|
||||
if (error == EBUSY)
|
||||
printf("BUSY)\n");
|
||||
else
|
||||
printf("%d)\n", error);
|
||||
}
|
||||
} else {
|
||||
/* The unmount has removed mp from the mountlist */
|
||||
}
|
||||
|
||||
/*
|
||||
* Forcibly unmounting "/dev" before "/" would prevent clean
|
||||
* unmount of the latter.
|
||||
*/
|
||||
if (mp == rootdevmp)
|
||||
continue;
|
||||
|
||||
unmount_or_warn(mp);
|
||||
}
|
||||
|
||||
if (rootdevmp != NULL)
|
||||
unmount_or_warn(rootdevmp);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -420,6 +420,7 @@ extern int vttoif_tab[];
|
||||
* Global vnode data.
|
||||
*/
|
||||
extern struct vnode *rootvnode; /* root (i.e. "/") vnode */
|
||||
extern struct mount *rootdevmp; /* "/dev" mount */
|
||||
extern int async_io_version; /* 0 or POSIX version of AIO i'face */
|
||||
extern int desiredvnodes; /* number of vnodes desired */
|
||||
extern struct uma_zone *namei_zone;
|
||||
|
Loading…
Reference in New Issue
Block a user