| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: vfs_mount.c,v 1.70 2019/02/20 10:08:37 hannken Exp $ */ | | 1 | /* $NetBSD: vfs_mount.c,v 1.70.4.1 2020/04/22 18:05:11 martin Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 1997-2011 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 1997-2011 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, | | 8 | * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, |
9 | * NASA Ames Research Center, by Charles M. Hannum, and by Andrew Doran. | | 9 | * NASA Ames Research Center, by Charles M. Hannum, and by Andrew Doran. |
10 | * | | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | | 11 | * Redistribution and use in source and binary forms, with or without |
12 | * modification, are permitted provided that the following conditions | | 12 | * modification, are permitted provided that the following conditions |
13 | * are met: | | 13 | * are met: |
14 | * 1. Redistributions of source code must retain the above copyright | | 14 | * 1. Redistributions of source code must retain the above copyright |
| @@ -57,27 +57,27 @@ | | | @@ -57,27 +57,27 @@ |
57 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | | 57 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
58 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 58 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
59 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 59 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
60 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 60 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
61 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 61 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
62 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 62 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
63 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 63 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
64 | * SUCH DAMAGE. | | 64 | * SUCH DAMAGE. |
65 | * | | 65 | * |
66 | * @(#)vfs_subr.c 8.13 (Berkeley) 4/18/94 | | 66 | * @(#)vfs_subr.c 8.13 (Berkeley) 4/18/94 |
67 | */ | | 67 | */ |
68 | | | 68 | |
69 | #include <sys/cdefs.h> | | 69 | #include <sys/cdefs.h> |
70 | __KERNEL_RCSID(0, "$NetBSD: vfs_mount.c,v 1.70 2019/02/20 10:08:37 hannken Exp $"); | | 70 | __KERNEL_RCSID(0, "$NetBSD: vfs_mount.c,v 1.70.4.1 2020/04/22 18:05:11 martin Exp $"); |
71 | | | 71 | |
72 | #include <sys/param.h> | | 72 | #include <sys/param.h> |
73 | #include <sys/kernel.h> | | 73 | #include <sys/kernel.h> |
74 | | | 74 | |
75 | #include <sys/atomic.h> | | 75 | #include <sys/atomic.h> |
76 | #include <sys/buf.h> | | 76 | #include <sys/buf.h> |
77 | #include <sys/conf.h> | | 77 | #include <sys/conf.h> |
78 | #include <sys/fcntl.h> | | 78 | #include <sys/fcntl.h> |
79 | #include <sys/filedesc.h> | | 79 | #include <sys/filedesc.h> |
80 | #include <sys/device.h> | | 80 | #include <sys/device.h> |
81 | #include <sys/kauth.h> | | 81 | #include <sys/kauth.h> |
82 | #include <sys/kmem.h> | | 82 | #include <sys/kmem.h> |
83 | #include <sys/module.h> | | 83 | #include <sys/module.h> |
| @@ -104,26 +104,28 @@ struct mountlist_entry { | | | @@ -104,26 +104,28 @@ struct mountlist_entry { |
104 | current mount else. */ | | 104 | current mount else. */ |
105 | enum mountlist_type me_type; /* Mount or marker. */ | | 105 | enum mountlist_type me_type; /* Mount or marker. */ |
106 | }; | | 106 | }; |
107 | struct mount_iterator { | | 107 | struct mount_iterator { |
108 | struct mountlist_entry mi_entry; | | 108 | struct mountlist_entry mi_entry; |
109 | }; | | 109 | }; |
110 | | | 110 | |
111 | static struct vnode *vfs_vnode_iterator_next1(struct vnode_iterator *, | | 111 | static struct vnode *vfs_vnode_iterator_next1(struct vnode_iterator *, |
112 | bool (*)(void *, struct vnode *), void *, bool); | | 112 | bool (*)(void *, struct vnode *), void *, bool); |
113 | | | 113 | |
114 | /* Root filesystem. */ | | 114 | /* Root filesystem. */ |
115 | vnode_t * rootvnode; | | 115 | vnode_t * rootvnode; |
116 | | | 116 | |
| | | 117 | extern struct mount *dead_rootmount; |
| | | 118 | |
117 | /* Mounted filesystem list. */ | | 119 | /* Mounted filesystem list. */ |
118 | static TAILQ_HEAD(mountlist, mountlist_entry) mountlist; | | 120 | static TAILQ_HEAD(mountlist, mountlist_entry) mountlist; |
119 | static kmutex_t mountlist_lock; | | 121 | static kmutex_t mountlist_lock; |
120 | int vnode_offset_next_by_lru /* XXX: ugly hack for pstat.c */ | | 122 | int vnode_offset_next_by_lru /* XXX: ugly hack for pstat.c */ |
121 | = offsetof(vnode_impl_t, vi_lrulist.tqe_next); | | 123 | = offsetof(vnode_impl_t, vi_lrulist.tqe_next); |
122 | | | 124 | |
123 | kmutex_t mntvnode_lock; | | 125 | kmutex_t mntvnode_lock; |
124 | kmutex_t vfs_list_lock; | | 126 | kmutex_t vfs_list_lock; |
125 | | | 127 | |
126 | static specificdata_domain_t mount_specificdata_domain; | | 128 | static specificdata_domain_t mount_specificdata_domain; |
127 | static kmutex_t mntid_lock; | | 129 | static kmutex_t mntid_lock; |
128 | | | 130 | |
129 | static kmutex_t mountgen_lock; | | 131 | static kmutex_t mountgen_lock; |
| @@ -990,26 +992,27 @@ vfs_unmount_forceone(struct lwp *l) | | | @@ -990,26 +992,27 @@ vfs_unmount_forceone(struct lwp *l) |
990 | | | 992 | |
991 | #ifdef DEBUG | | 993 | #ifdef DEBUG |
992 | printf("forceful unmount of %s failed with error %d\n", | | 994 | printf("forceful unmount of %s failed with error %d\n", |
993 | mp->mnt_stat.f_mntonname, error); | | 995 | mp->mnt_stat.f_mntonname, error); |
994 | #endif | | 996 | #endif |
995 | | | 997 | |
996 | return false; | | 998 | return false; |
997 | } | | 999 | } |
998 | | | 1000 | |
999 | bool | | 1001 | bool |
1000 | vfs_unmountall1(struct lwp *l, bool force, bool verbose) | | 1002 | vfs_unmountall1(struct lwp *l, bool force, bool verbose) |
1001 | { | | 1003 | { |
1002 | struct mount *mp; | | 1004 | struct mount *mp; |
| | | 1005 | mount_iterator_t *iter; |
1003 | bool any_error = false, progress = false; | | 1006 | bool any_error = false, progress = false; |
1004 | uint64_t gen; | | 1007 | uint64_t gen; |
1005 | int error; | | 1008 | int error; |
1006 | | | 1009 | |
1007 | gen = mountgen; | | 1010 | gen = mountgen; |
1008 | for (;;) { | | 1011 | for (;;) { |
1009 | mp = vfs_unmount_next(gen); | | 1012 | mp = vfs_unmount_next(gen); |
1010 | if (mp == NULL) | | 1013 | if (mp == NULL) |
1011 | break; | | 1014 | break; |
1012 | gen = mp->mnt_gen; | | 1015 | gen = mp->mnt_gen; |
1013 | | | 1016 | |
1014 | #ifdef DEBUG | | 1017 | #ifdef DEBUG |
1015 | printf("unmounting %p %s (%s)...\n", | | 1018 | printf("unmounting %p %s (%s)...\n", |
| @@ -1024,26 +1027,44 @@ vfs_unmountall1(struct lwp *l, bool forc | | | @@ -1024,26 +1027,44 @@ vfs_unmountall1(struct lwp *l, bool forc |
1024 | if (verbose) { | | 1027 | if (verbose) { |
1025 | printf("unmount of %s failed with error %d\n", | | 1028 | printf("unmount of %s failed with error %d\n", |
1026 | mp->mnt_stat.f_mntonname, error); | | 1029 | mp->mnt_stat.f_mntonname, error); |
1027 | } | | 1030 | } |
1028 | any_error = true; | | 1031 | any_error = true; |
1029 | } | | 1032 | } |
1030 | } | | 1033 | } |
1031 | if (verbose) { | | 1034 | if (verbose) { |
1032 | printf("unmounting done\n"); | | 1035 | printf("unmounting done\n"); |
1033 | } | | 1036 | } |
1034 | if (any_error && verbose) { | | 1037 | if (any_error && verbose) { |
1035 | printf("WARNING: some file systems would not unmount\n"); | | 1038 | printf("WARNING: some file systems would not unmount\n"); |
1036 | } | | 1039 | } |
| | | 1040 | |
| | | 1041 | /* If the mountlist is empty destroy anonymous device vnodes. */ |
| | | 1042 | mountlist_iterator_init(&iter); |
| | | 1043 | if (mountlist_iterator_next(iter) == NULL) { |
| | | 1044 | struct vnode_iterator *marker; |
| | | 1045 | vnode_t *vp; |
| | | 1046 | |
| | | 1047 | vfs_vnode_iterator_init(dead_rootmount, &marker); |
| | | 1048 | while ((vp = vfs_vnode_iterator_next(marker, NULL, NULL))) { |
| | | 1049 | if (vp->v_type == VCHR || vp->v_type == VBLK) |
| | | 1050 | vgone(vp); |
| | | 1051 | else |
| | | 1052 | vrele(vp); |
| | | 1053 | } |
| | | 1054 | vfs_vnode_iterator_destroy(marker); |
| | | 1055 | } |
| | | 1056 | mountlist_iterator_destroy(iter); |
| | | 1057 | |
1037 | return progress; | | 1058 | return progress; |
1038 | } | | 1059 | } |
1039 | | | 1060 | |
1040 | void | | 1061 | void |
1041 | vfs_sync_all(struct lwp *l) | | 1062 | vfs_sync_all(struct lwp *l) |
1042 | { | | 1063 | { |
1043 | printf("syncing disks... "); | | 1064 | printf("syncing disks... "); |
1044 | | | 1065 | |
1045 | /* remove user processes from run queue */ | | 1066 | /* remove user processes from run queue */ |
1046 | suspendsched(); | | 1067 | suspendsched(); |
1047 | (void)spl0(); | | 1068 | (void)spl0(); |
1048 | | | 1069 | |
1049 | /* avoid coming back this way again if we panic. */ | | 1070 | /* avoid coming back this way again if we panic. */ |