Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F145930326
D3467.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D3467.id.diff
View Options
Index: head/sys/kern/vfs_mount.c
===================================================================
--- head/sys/kern/vfs_mount.c
+++ head/sys/kern/vfs_mount.c
@@ -1359,6 +1359,8 @@
vput(coveredvp);
}
vfs_event_signal(NULL, VQ_UNMOUNT, 0);
+ if (mp == rootdevmp)
+ rootdevmp = NULL;
vfs_mount_destroy(mp);
return (0);
}
Index: head/sys/kern/vfs_mountroot.c
===================================================================
--- head/sys/kern/vfs_mountroot.c
+++ head/sys/kern/vfs_mountroot.c
@@ -95,6 +95,11 @@
*/
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 @@
mtx_unlock(&mountlist_mtx);
*mpp = mp;
+ rootdevmp = mp;
set_rootvnode();
error = kern_symlinkat(td, "/", AT_FDCWD, "dev", UIO_SYSSPACE);
Index: head/sys/kern/vfs_subr.c
===================================================================
--- head/sys/kern/vfs_subr.c
+++ head/sys/kern/vfs_subr.c
@@ -3543,6 +3543,21 @@
"");
#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 @@
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);
}
/*
Index: head/sys/sys/vnode.h
===================================================================
--- head/sys/sys/vnode.h
+++ head/sys/sys/vnode.h
@@ -420,6 +420,7 @@
* 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;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Feb 27, 6:51 AM (18 h, 15 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29019537
Default Alt Text
D3467.id.diff (3 KB)
Attached To
Mode
D3467: Unmount /dev after /.
Attached
Detach File
Event Timeline
Log In to Comment