Sun Sep 21 23:22:01 2008 UTC ()
Revert previous, pooka@ points out it's wrong.


(freza)
diff -r1.235 -r1.236 src/sys/ufs/ffs/ffs_vfsops.c

cvs diff -r1.235 -r1.236 src/sys/ufs/ffs/ffs_vfsops.c (switch to unified diff)

--- src/sys/ufs/ffs/ffs_vfsops.c 2008/09/21 21:08:22 1.235
+++ src/sys/ufs/ffs/ffs_vfsops.c 2008/09/21 23:22:00 1.236
@@ -1,2073 +1,2073 @@ @@ -1,2073 +1,2073 @@
1/* $NetBSD: ffs_vfsops.c,v 1.235 2008/09/21 21:08:22 freza Exp $ */ 1/* $NetBSD: ffs_vfsops.c,v 1.236 2008/09/21 23:22:00 freza Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 2008 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 Wasabi Systems, Inc. 8 * by Wasabi Systems, Inc.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * Copyright (c) 1989, 1991, 1993, 1994 33 * Copyright (c) 1989, 1991, 1993, 1994
34 * The Regents of the University of California. All rights reserved. 34 * The Regents of the University of California. All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions 37 * modification, are permitted provided that the following conditions
38 * are met: 38 * are met:
39 * 1. Redistributions of source code must retain the above copyright 39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer. 40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright 41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the 42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution. 43 * documentation and/or other materials provided with the distribution.
44 * 3. Neither the name of the University nor the names of its contributors 44 * 3. Neither the name of the University nor the names of its contributors
45 * may be used to endorse or promote products derived from this software 45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission. 46 * without specific prior written permission.
47 * 47 *
48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE. 58 * SUCH DAMAGE.
59 * 59 *
60 * @(#)ffs_vfsops.c 8.31 (Berkeley) 5/20/95 60 * @(#)ffs_vfsops.c 8.31 (Berkeley) 5/20/95
61 */ 61 */
62 62
63#include <sys/cdefs.h> 63#include <sys/cdefs.h>
64__KERNEL_RCSID(0, "$NetBSD: ffs_vfsops.c,v 1.235 2008/09/21 21:08:22 freza Exp $"); 64__KERNEL_RCSID(0, "$NetBSD: ffs_vfsops.c,v 1.236 2008/09/21 23:22:00 freza Exp $");
65 65
66#if defined(_KERNEL_OPT) 66#if defined(_KERNEL_OPT)
67#include "opt_ffs.h" 67#include "opt_ffs.h"
68#include "opt_quota.h" 68#include "opt_quota.h"
69#include "opt_softdep.h" 69#include "opt_softdep.h"
70#include "opt_wapbl.h" 70#include "opt_wapbl.h"
71#endif 71#endif
72 72
73#include <sys/param.h> 73#include <sys/param.h>
74#include <sys/systm.h> 74#include <sys/systm.h>
75#include <sys/namei.h> 75#include <sys/namei.h>
76#include <sys/proc.h> 76#include <sys/proc.h>
77#include <sys/kernel.h> 77#include <sys/kernel.h>
78#include <sys/vnode.h> 78#include <sys/vnode.h>
79#include <sys/socket.h> 79#include <sys/socket.h>
80#include <sys/mount.h> 80#include <sys/mount.h>
81#include <sys/buf.h> 81#include <sys/buf.h>
82#include <sys/device.h> 82#include <sys/device.h>
83#include <sys/mbuf.h> 83#include <sys/mbuf.h>
84#include <sys/file.h> 84#include <sys/file.h>
85#include <sys/disklabel.h> 85#include <sys/disklabel.h>
86#include <sys/ioctl.h> 86#include <sys/ioctl.h>
87#include <sys/errno.h> 87#include <sys/errno.h>
88#include <sys/malloc.h> 88#include <sys/malloc.h>
89#include <sys/pool.h> 89#include <sys/pool.h>
90#include <sys/lock.h> 90#include <sys/lock.h>
91#include <sys/sysctl.h> 91#include <sys/sysctl.h>
92#include <sys/conf.h> 92#include <sys/conf.h>
93#include <sys/kauth.h> 93#include <sys/kauth.h>
94#include <sys/wapbl.h> 94#include <sys/wapbl.h>
95#include <sys/fstrans.h> 95#include <sys/fstrans.h>
96#include <sys/module.h> 96#include <sys/module.h>
97 97
98#include <miscfs/genfs/genfs.h> 98#include <miscfs/genfs/genfs.h>
99#include <miscfs/specfs/specdev.h> 99#include <miscfs/specfs/specdev.h>
100 100
101#include <ufs/ufs/quota.h> 101#include <ufs/ufs/quota.h>
102#include <ufs/ufs/ufsmount.h> 102#include <ufs/ufs/ufsmount.h>
103#include <ufs/ufs/inode.h> 103#include <ufs/ufs/inode.h>
104#include <ufs/ufs/dir.h> 104#include <ufs/ufs/dir.h>
105#include <ufs/ufs/ufs_extern.h> 105#include <ufs/ufs/ufs_extern.h>
106#include <ufs/ufs/ufs_bswap.h> 106#include <ufs/ufs/ufs_bswap.h>
107#include <ufs/ufs/ufs_wapbl.h> 107#include <ufs/ufs/ufs_wapbl.h>
108 108
109#include <ufs/ffs/fs.h> 109#include <ufs/ffs/fs.h>
110#include <ufs/ffs/ffs_extern.h> 110#include <ufs/ffs/ffs_extern.h>
111 111
112MODULE(MODULE_CLASS_VFS, ffs, NULL); 112MODULE(MODULE_CLASS_VFS, ffs, NULL);
113 113
114static struct sysctllog *ffs_sysctl_log; 114static struct sysctllog *ffs_sysctl_log;
115 115
116/* how many times ffs_init() was called */ 116/* how many times ffs_init() was called */
117int ffs_initcount = 0; 117int ffs_initcount = 0;
118 118
119extern kmutex_t ufs_hashlock; 119extern kmutex_t ufs_hashlock;
120 120
121extern const struct vnodeopv_desc ffs_vnodeop_opv_desc; 121extern const struct vnodeopv_desc ffs_vnodeop_opv_desc;
122extern const struct vnodeopv_desc ffs_specop_opv_desc; 122extern const struct vnodeopv_desc ffs_specop_opv_desc;
123extern const struct vnodeopv_desc ffs_fifoop_opv_desc; 123extern const struct vnodeopv_desc ffs_fifoop_opv_desc;
124 124
125const struct vnodeopv_desc * const ffs_vnodeopv_descs[] = { 125const struct vnodeopv_desc * const ffs_vnodeopv_descs[] = {
126 &ffs_vnodeop_opv_desc, 126 &ffs_vnodeop_opv_desc,
127 &ffs_specop_opv_desc, 127 &ffs_specop_opv_desc,
128 &ffs_fifoop_opv_desc, 128 &ffs_fifoop_opv_desc,
129 NULL, 129 NULL,
130}; 130};
131 131
132struct vfsops ffs_vfsops = { 132struct vfsops ffs_vfsops = {
133 MOUNT_FFS, 133 MOUNT_FFS,
134 sizeof (struct ufs_args), 134 sizeof (struct ufs_args),
135 ffs_mount, 135 ffs_mount,
136 ufs_start, 136 ufs_start,
137 ffs_unmount, 137 ffs_unmount,
138 ufs_root, 138 ufs_root,
139 ufs_quotactl, 139 ufs_quotactl,
140 ffs_statvfs, 140 ffs_statvfs,
141 ffs_sync, 141 ffs_sync,
142 ffs_vget, 142 ffs_vget,
143 ffs_fhtovp, 143 ffs_fhtovp,
144 ffs_vptofh, 144 ffs_vptofh,
145 ffs_init, 145 ffs_init,
146 ffs_reinit, 146 ffs_reinit,
147 ffs_done, 147 ffs_done,
148 ffs_mountroot, 148 ffs_mountroot,
149 ffs_snapshot, 149 ffs_snapshot,
150 ffs_extattrctl, 150 ffs_extattrctl,
151 ffs_suspendctl, 151 ffs_suspendctl,
152 genfs_renamelock_enter, 152 genfs_renamelock_enter,
153 genfs_renamelock_exit, 153 genfs_renamelock_exit,
154 ffs_full_fsync, 154 ffs_full_fsync,
155 ffs_vnodeopv_descs, 155 ffs_vnodeopv_descs,
156 0, 156 0,
157 { NULL, NULL }, 157 { NULL, NULL },
158}; 158};
159 159
160static const struct genfs_ops ffs_genfsops = { 160static const struct genfs_ops ffs_genfsops = {
161 .gop_size = ffs_gop_size, 161 .gop_size = ffs_gop_size,
162 .gop_alloc = ufs_gop_alloc, 162 .gop_alloc = ufs_gop_alloc,
163 .gop_write = ffs_gop_write, 163 .gop_write = ffs_gop_write,
164 .gop_markupdate = ufs_gop_markupdate, 164 .gop_markupdate = ufs_gop_markupdate,
165}; 165};
166 166
167static const struct ufs_ops ffs_ufsops = { 167static const struct ufs_ops ffs_ufsops = {
168 .uo_itimes = ffs_itimes, 168 .uo_itimes = ffs_itimes,
169 .uo_update = ffs_update, 169 .uo_update = ffs_update,
170 .uo_truncate = ffs_truncate, 170 .uo_truncate = ffs_truncate,
171 .uo_valloc = ffs_valloc, 171 .uo_valloc = ffs_valloc,
172 .uo_vfree = ffs_vfree, 172 .uo_vfree = ffs_vfree,
173 .uo_balloc = ffs_balloc, 173 .uo_balloc = ffs_balloc,
174}; 174};
175 175
176static int 176static int
177ffs_modcmd(modcmd_t cmd, void *arg) 177ffs_modcmd(modcmd_t cmd, void *arg)
178{ 178{
179 int error; 179 int error;
180 180
181#if 0 181#if 0
182 extern int doasyncfree; 182 extern int doasyncfree;
183#endif 183#endif
184 extern int ffs_log_changeopt; 184 extern int ffs_log_changeopt;
185 185
186 switch (cmd) { 186 switch (cmd) {
187 case MODULE_CMD_INIT: 187 case MODULE_CMD_INIT:
188 error = vfs_attach(&ffs_vfsops); 188 error = vfs_attach(&ffs_vfsops);
189 if (error != 0) 189 if (error != 0)
190 break; 190 break;
191 191
192 sysctl_createv(&ffs_sysctl_log, 0, NULL, NULL, 192 sysctl_createv(&ffs_sysctl_log, 0, NULL, NULL,
193 CTLFLAG_PERMANENT, 193 CTLFLAG_PERMANENT,
194 CTLTYPE_NODE, "vfs", NULL, 194 CTLTYPE_NODE, "vfs", NULL,
195 NULL, 0, NULL, 0, 195 NULL, 0, NULL, 0,
196 CTL_VFS, CTL_EOL); 196 CTL_VFS, CTL_EOL);
197 sysctl_createv(&ffs_sysctl_log, 0, NULL, NULL, 197 sysctl_createv(&ffs_sysctl_log, 0, NULL, NULL,
198 CTLFLAG_PERMANENT, 198 CTLFLAG_PERMANENT,
199 CTLTYPE_NODE, "ffs", 199 CTLTYPE_NODE, "ffs",
200 SYSCTL_DESCR("Berkeley Fast File System"), 200 SYSCTL_DESCR("Berkeley Fast File System"),
201 NULL, 0, NULL, 0, 201 NULL, 0, NULL, 0,
202 CTL_VFS, 1, CTL_EOL); 202 CTL_VFS, 1, CTL_EOL);
203 203
204 /* 204 /*
205 * @@@ should we even bother with these first three? 205 * @@@ should we even bother with these first three?
206 */ 206 */
207 sysctl_createv(&ffs_sysctl_log, 0, NULL, NULL, 207 sysctl_createv(&ffs_sysctl_log, 0, NULL, NULL,
208 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 208 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
209 CTLTYPE_INT, "doclusterread", NULL, 209 CTLTYPE_INT, "doclusterread", NULL,
210 sysctl_notavail, 0, NULL, 0, 210 sysctl_notavail, 0, NULL, 0,
211 CTL_VFS, 1, FFS_CLUSTERREAD, CTL_EOL); 211 CTL_VFS, 1, FFS_CLUSTERREAD, CTL_EOL);
212 sysctl_createv(&ffs_sysctl_log, 0, NULL, NULL, 212 sysctl_createv(&ffs_sysctl_log, 0, NULL, NULL,
213 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 213 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
214 CTLTYPE_INT, "doclusterwrite", NULL, 214 CTLTYPE_INT, "doclusterwrite", NULL,
215 sysctl_notavail, 0, NULL, 0, 215 sysctl_notavail, 0, NULL, 0,
216 CTL_VFS, 1, FFS_CLUSTERWRITE, CTL_EOL); 216 CTL_VFS, 1, FFS_CLUSTERWRITE, CTL_EOL);
217 sysctl_createv(&ffs_sysctl_log, 0, NULL, NULL, 217 sysctl_createv(&ffs_sysctl_log, 0, NULL, NULL,
218 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 218 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
219 CTLTYPE_INT, "doreallocblks", NULL, 219 CTLTYPE_INT, "doreallocblks", NULL,
220 sysctl_notavail, 0, NULL, 0, 220 sysctl_notavail, 0, NULL, 0,
221 CTL_VFS, 1, FFS_REALLOCBLKS, CTL_EOL); 221 CTL_VFS, 1, FFS_REALLOCBLKS, CTL_EOL);
222#if 0 222#if 0
223 sysctl_createv(&ffs_sysctl_log, 0, NULL, NULL, 223 sysctl_createv(&ffs_sysctl_log, 0, NULL, NULL,
224 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 224 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
225 CTLTYPE_INT, "doasyncfree", 225 CTLTYPE_INT, "doasyncfree",
226 SYSCTL_DESCR("Release dirty blocks asynchronously"), 226 SYSCTL_DESCR("Release dirty blocks asynchronously"),
227 NULL, 0, &doasyncfree, 0, 227 NULL, 0, &doasyncfree, 0,
228 CTL_VFS, 1, FFS_ASYNCFREE, CTL_EOL); 228 CTL_VFS, 1, FFS_ASYNCFREE, CTL_EOL);
229#endif 229#endif
230 sysctl_createv(&ffs_sysctl_log, 0, NULL, NULL, 230 sysctl_createv(&ffs_sysctl_log, 0, NULL, NULL,
231 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 231 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
232 CTLTYPE_INT, "log_changeopt", 232 CTLTYPE_INT, "log_changeopt",
233 SYSCTL_DESCR("Log changes in optimization strategy"), 233 SYSCTL_DESCR("Log changes in optimization strategy"),
234 NULL, 0, &ffs_log_changeopt, 0, 234 NULL, 0, &ffs_log_changeopt, 0,
235 CTL_VFS, 1, FFS_LOG_CHANGEOPT, CTL_EOL); 235 CTL_VFS, 1, FFS_LOG_CHANGEOPT, CTL_EOL);
236 break; 236 break;
237 case MODULE_CMD_FINI: 237 case MODULE_CMD_FINI:
238 error = vfs_detach(&ffs_vfsops); 238 error = vfs_detach(&ffs_vfsops);
239 if (error != 0) 239 if (error != 0)
240 break; 240 break;
241 sysctl_teardown(&ffs_sysctl_log); 241 sysctl_teardown(&ffs_sysctl_log);
242 break; 242 break;
243 default: 243 default:
244 error = ENOTTY; 244 error = ENOTTY;
245 break; 245 break;
246 } 246 }
247 247
248 return (error); 248 return (error);
249} 249}
250 250
251pool_cache_t ffs_inode_cache; 251pool_cache_t ffs_inode_cache;
252pool_cache_t ffs_dinode1_cache; 252pool_cache_t ffs_dinode1_cache;
253pool_cache_t ffs_dinode2_cache; 253pool_cache_t ffs_dinode2_cache;
254 254
255static void ffs_oldfscompat_read(struct fs *, struct ufsmount *, daddr_t); 255static void ffs_oldfscompat_read(struct fs *, struct ufsmount *, daddr_t);
256static void ffs_oldfscompat_write(struct fs *, struct ufsmount *); 256static void ffs_oldfscompat_write(struct fs *, struct ufsmount *);
257 257
258/* 258/*
259 * Called by main() when ffs is going to be mounted as root. 259 * Called by main() when ffs is going to be mounted as root.
260 */ 260 */
261 261
262int 262int
263ffs_mountroot(void) 263ffs_mountroot(void)
264{ 264{
265 struct fs *fs; 265 struct fs *fs;
266 struct mount *mp; 266 struct mount *mp;
267 struct lwp *l = curlwp; /* XXX */ 267 struct lwp *l = curlwp; /* XXX */
268 struct ufsmount *ump; 268 struct ufsmount *ump;
269 int error; 269 int error;
270 270
271 if (device_class(root_device) != DV_DISK) 271 if (device_class(root_device) != DV_DISK)
272 return (ENODEV); 272 return (ENODEV);
273 273
274 if ((error = vfs_rootmountalloc(MOUNT_FFS, "root_device", &mp))) { 274 if ((error = vfs_rootmountalloc(MOUNT_FFS, "root_device", &mp))) {
275 vrele(rootvp); 275 vrele(rootvp);
276 return (error); 276 return (error);
277 } 277 }
278 278
279 /* 279 /*
280 * We always need to be able to mount the root file system. 280 * We always need to be able to mount the root file system.
281 */ 281 */
282 mp->mnt_flag |= MNT_FORCE; 282 mp->mnt_flag |= MNT_FORCE;
283 if ((error = ffs_mountfs(rootvp, mp, l)) != 0) { 283 if ((error = ffs_mountfs(rootvp, mp, l)) != 0) {
284 vfs_unbusy(mp, false, NULL); 284 vfs_unbusy(mp, false, NULL);
285 vfs_destroy(mp); 285 vfs_destroy(mp);
286 return (error); 286 return (error);
287 } 287 }
288 mp->mnt_flag &= ~MNT_FORCE; 288 mp->mnt_flag &= ~MNT_FORCE;
289 mutex_enter(&mountlist_lock); 289 mutex_enter(&mountlist_lock);
290 CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list); 290 CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
291 mutex_exit(&mountlist_lock); 291 mutex_exit(&mountlist_lock);
292 ump = VFSTOUFS(mp); 292 ump = VFSTOUFS(mp);
293 fs = ump->um_fs; 293 fs = ump->um_fs;
294 memset(fs->fs_fsmnt, 0, sizeof(fs->fs_fsmnt)); 294 memset(fs->fs_fsmnt, 0, sizeof(fs->fs_fsmnt));
295 (void)copystr(mp->mnt_stat.f_mntonname, fs->fs_fsmnt, MNAMELEN - 1, 0); 295 (void)copystr(mp->mnt_stat.f_mntonname, fs->fs_fsmnt, MNAMELEN - 1, 0);
296 (void)ffs_statvfs(mp, &mp->mnt_stat); 296 (void)ffs_statvfs(mp, &mp->mnt_stat);
297 vfs_unbusy(mp, false, NULL); 297 vfs_unbusy(mp, false, NULL);
298 setrootfstime((time_t)fs->fs_time); 298 setrootfstime((time_t)fs->fs_time);
299 return (0); 299 return (0);
300} 300}
301 301
302static int dolog; 302static int dolog;
303 303
304/* 304/*
305 * VFS Operations. 305 * VFS Operations.
306 * 306 *
307 * mount system call 307 * mount system call
308 */ 308 */
309int 309int
310ffs_mount(struct mount *mp, const char *path, void *data, size_t *data_len) 310ffs_mount(struct mount *mp, const char *path, void *data, size_t *data_len)
311{ 311{
312 struct lwp *l = curlwp; 312 struct lwp *l = curlwp;
313 struct nameidata nd; 313 struct nameidata nd;
314 struct vnode *vp, *devvp = NULL; 314 struct vnode *vp, *devvp = NULL;
315 struct ufs_args *args = data; 315 struct ufs_args *args = data;
316 struct ufsmount *ump = NULL; 316 struct ufsmount *ump = NULL;
317 struct fs *fs; 317 struct fs *fs;
318 int error = 0, flags, update; 318 int error = 0, flags, update;
319 mode_t accessmode; 319 mode_t accessmode;
320 320
321 if (dolog) 321 if (dolog)
322 mp->mnt_flag |= MNT_LOG; 322 mp->mnt_flag |= MNT_LOG;
323 323
324 if (*data_len < sizeof *args) 324 if (*data_len < sizeof *args)
325 return EINVAL; 325 return EINVAL;
326 326
327 if (mp->mnt_flag & MNT_GETARGS) { 327 if (mp->mnt_flag & MNT_GETARGS) {
328 ump = VFSTOUFS(mp); 328 ump = VFSTOUFS(mp);
329 if (ump == NULL) 329 if (ump == NULL)
330 return EIO; 330 return EIO;
331 args->fspec = NULL; 331 args->fspec = NULL;
332 *data_len = sizeof *args; 332 *data_len = sizeof *args;
333 return 0; 333 return 0;
334 } 334 }
335 335
336#if !defined(SOFTDEP) 336#if !defined(SOFTDEP)
337 mp->mnt_flag &= ~MNT_SOFTDEP; 337 mp->mnt_flag &= ~MNT_SOFTDEP;
338#endif 338#endif
339 339
340 update = mp->mnt_flag & MNT_UPDATE; 340 update = mp->mnt_flag & MNT_UPDATE;
341 341
342 /* Check arguments */ 342 /* Check arguments */
343 if (args->fspec != NULL) { 343 if (args->fspec != NULL) {
344 /* 344 /*
345 * Look up the name and verify that it's sane. 345 * Look up the name and verify that it's sane.
346 */ 346 */
347 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, args->fspec); 347 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, args->fspec);
348 if ((error = namei(&nd)) != 0) 348 if ((error = namei(&nd)) != 0)
349 return (error); 349 return (error);
350 devvp = nd.ni_vp; 350 devvp = nd.ni_vp;
351 351
352 if (!update) { 352 if (!update) {
353 /* 353 /*
354 * Be sure this is a valid block device 354 * Be sure this is a valid block device
355 */ 355 */
356 if (devvp->v_type != VBLK) 356 if (devvp->v_type != VBLK)
357 error = ENOTBLK; 357 error = ENOTBLK;
358 else if (bdevsw_lookup(devvp->v_rdev) == NULL) 358 else if (bdevsw_lookup(devvp->v_rdev) == NULL)
359 error = ENXIO; 359 error = ENXIO;
360 } else { 360 } else {
361 /* 361 /*
362 * Be sure we're still naming the same device 362 * Be sure we're still naming the same device
363 * used for our initial mount 363 * used for our initial mount
364 */ 364 */
365 ump = VFSTOUFS(mp); 365 ump = VFSTOUFS(mp);
366 if (devvp != ump->um_devvp) { 366 if (devvp != ump->um_devvp) {
367 if (devvp->v_rdev != ump->um_devvp->v_rdev) 367 if (devvp->v_rdev != ump->um_devvp->v_rdev)
368 error = EINVAL; 368 error = EINVAL;
369 else { 369 else {
370 vrele(devvp); 370 vrele(devvp);
371 devvp = ump->um_devvp; 371 devvp = ump->um_devvp;
372 vref(devvp); 372 vref(devvp);
373 } 373 }
374 } 374 }
375 } 375 }
376 } else { 376 } else {
377 if (!update) { 377 if (!update) {
378 /* New mounts must have a filename for the device */ 378 /* New mounts must have a filename for the device */
379 return (EINVAL); 379 return (EINVAL);
380 } else { 380 } else {
381 /* Use the extant mount */ 381 /* Use the extant mount */
382 ump = VFSTOUFS(mp); 382 ump = VFSTOUFS(mp);
383 devvp = ump->um_devvp; 383 devvp = ump->um_devvp;
384 vref(devvp); 384 vref(devvp);
385 } 385 }
386 } 386 }
387 387
388 /* 388 /*
389 * Mark the device and any existing vnodes as involved in 389 * Mark the device and any existing vnodes as involved in
390 * softdep processing. 390 * softdep processing.
391 */ 391 */
392 if ((mp->mnt_flag & MNT_SOFTDEP) != 0) { 392 if ((mp->mnt_flag & MNT_SOFTDEP) != 0) {
393 devvp->v_uflag |= VU_SOFTDEP; 393 devvp->v_uflag |= VU_SOFTDEP;
394 mutex_enter(&mntvnode_lock); 394 mutex_enter(&mntvnode_lock);
395 TAILQ_FOREACH(vp, &mp->mnt_vnodelist, v_mntvnodes) { 395 TAILQ_FOREACH(vp, &mp->mnt_vnodelist, v_mntvnodes) {
396 if (vp->v_mount != mp || vismarker(vp)) 396 if (vp->v_mount != mp || vismarker(vp))
397 continue; 397 continue;
398 vp->v_uflag |= VU_SOFTDEP; 398 vp->v_uflag |= VU_SOFTDEP;
399 } 399 }
400 mutex_exit(&mntvnode_lock); 400 mutex_exit(&mntvnode_lock);
401 } 401 }
402 402
403 /* 403 /*
404 * If mount by non-root, then verify that user has necessary 404 * If mount by non-root, then verify that user has necessary
405 * permissions on the device. 405 * permissions on the device.
406 */ 406 */
407 if (error == 0 && kauth_authorize_generic(l->l_cred, 407 if (error == 0 && kauth_authorize_generic(l->l_cred,
408 KAUTH_GENERIC_ISSUSER, NULL) != 0) { 408 KAUTH_GENERIC_ISSUSER, NULL) != 0) {
409 accessmode = VREAD; 409 accessmode = VREAD;
410 if (update ? 410 if (update ?
411 (mp->mnt_iflag & IMNT_WANTRDWR) != 0 : 411 (mp->mnt_iflag & IMNT_WANTRDWR) != 0 :
412 (mp->mnt_flag & MNT_RDONLY) == 0) 412 (mp->mnt_flag & MNT_RDONLY) == 0)
413 accessmode |= VWRITE; 413 accessmode |= VWRITE;
414 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); 414 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
415 error = VOP_ACCESS(devvp, accessmode, l->l_cred); 415 error = VOP_ACCESS(devvp, accessmode, l->l_cred);
416 VOP_UNLOCK(devvp, 0); 416 VOP_UNLOCK(devvp, 0);
417 } 417 }
418 418
419 if (error) { 419 if (error) {
420 vrele(devvp); 420 vrele(devvp);
421 return (error); 421 return (error);
422 } 422 }
423 423
424#ifdef WAPBL 424#ifdef WAPBL
425 /* 425 /*
426 * WAPBL can only be enabled on a r/w mount 426 * WAPBL can only be enabled on a r/w mount
427 * that does not use softdep. 427 * that does not use softdep.
428 */ 428 */
429 if ((mp->mnt_flag & MNT_RDONLY) && !(mp->mnt_iflag & IMNT_WANTRDWR)) { 429 if ((mp->mnt_flag & MNT_RDONLY) && !(mp->mnt_iflag & IMNT_WANTRDWR)) {
430 mp->mnt_flag &= ~MNT_LOG; 430 mp->mnt_flag &= ~MNT_LOG;
431 } 431 }
432 if ((mp->mnt_flag & (MNT_SOFTDEP | MNT_LOG)) == 432 if ((mp->mnt_flag & (MNT_SOFTDEP | MNT_LOG)) ==
433 (MNT_SOFTDEP | MNT_LOG)) { 433 (MNT_SOFTDEP | MNT_LOG)) {
434 printf("%s fs is journalled, ignoring soft update mode\n", 434 printf("%s fs is journalled, ignoring soft update mode\n",
435 VFSTOUFS(mp)->um_fs->fs_fsmnt); 435 VFSTOUFS(mp)->um_fs->fs_fsmnt);
436 mp->mnt_flag &= ~MNT_SOFTDEP; 436 mp->mnt_flag &= ~MNT_SOFTDEP;
437 } 437 }
438#else /* !WAPBL */ 438#else /* !WAPBL */
439 mp->mnt_flag &= ~MNT_LOG; 439 mp->mnt_flag &= ~MNT_LOG;
440#endif /* !WAPBL */ 440#endif /* !WAPBL */
441 441
442 if (!update) { 442 if (!update) {
443 int xflags; 443 int xflags;
444 444
445 if (mp->mnt_flag & MNT_RDONLY) 445 if (mp->mnt_flag & MNT_RDONLY)
446 xflags = FREAD; 446 xflags = FREAD;
447 else 447 else
448 xflags = FREAD | FWRITE; 448 xflags = FREAD | FWRITE;
449 error = VOP_OPEN(devvp, xflags, FSCRED); 449 error = VOP_OPEN(devvp, xflags, FSCRED);
450 if (error) 450 if (error)
451 goto fail; 451 goto fail;
452 error = ffs_mountfs(devvp, mp, l); 452 error = ffs_mountfs(devvp, mp, l);
453 if (error) { 453 if (error) {
454 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); 454 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
455 (void)VOP_CLOSE(devvp, xflags, NOCRED); 455 (void)VOP_CLOSE(devvp, xflags, NOCRED);
456 VOP_UNLOCK(devvp, 0); 456 VOP_UNLOCK(devvp, 0);
457 goto fail; 457 goto fail;
458 } 458 }
459 459
460 ump = VFSTOUFS(mp); 460 ump = VFSTOUFS(mp);
461 fs = ump->um_fs; 461 fs = ump->um_fs;
462 if ((mp->mnt_flag & (MNT_SOFTDEP | MNT_ASYNC)) == 462 if ((mp->mnt_flag & (MNT_SOFTDEP | MNT_ASYNC)) ==
463 (MNT_SOFTDEP | MNT_ASYNC)) { 463 (MNT_SOFTDEP | MNT_ASYNC)) {
464 printf("%s fs uses soft updates, " 464 printf("%s fs uses soft updates, "
465 "ignoring async mode\n", 465 "ignoring async mode\n",
466 fs->fs_fsmnt); 466 fs->fs_fsmnt);
467 mp->mnt_flag &= ~MNT_ASYNC; 467 mp->mnt_flag &= ~MNT_ASYNC;
468 } 468 }
469 } else { 469 } else {
470 /* 470 /*
471 * Update the mount. 471 * Update the mount.
472 */ 472 */
473 473
474 /* 474 /*
475 * The initial mount got a reference on this 475 * The initial mount got a reference on this
476 * device, so drop the one obtained via 476 * device, so drop the one obtained via
477 * namei(), above. 477 * namei(), above.
478 */ 478 */
479 vrele(devvp); 479 vrele(devvp);
480 480
481 ump = VFSTOUFS(mp); 481 ump = VFSTOUFS(mp);
482 fs = ump->um_fs; 482 fs = ump->um_fs;
483 if (fs->fs_ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) { 483 if (fs->fs_ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) {
484 /* 484 /*
485 * Changing from r/w to r/o 485 * Changing from r/w to r/o
486 */ 486 */
487 flags = WRITECLOSE; 487 flags = WRITECLOSE;
488 if (mp->mnt_flag & MNT_FORCE) 488 if (mp->mnt_flag & MNT_FORCE)
489 flags |= FORCECLOSE; 489 flags |= FORCECLOSE;
490 if (mp->mnt_flag & MNT_SOFTDEP) 490 if (mp->mnt_flag & MNT_SOFTDEP)
491 error = softdep_flushfiles(mp, flags, l); 491 error = softdep_flushfiles(mp, flags, l);
492 else 492 else
493 error = ffs_flushfiles(mp, flags, l); 493 error = ffs_flushfiles(mp, flags, l);
494 if (fs->fs_pendingblocks != 0 || 494 if (fs->fs_pendingblocks != 0 ||
495 fs->fs_pendinginodes != 0) { 495 fs->fs_pendinginodes != 0) {
496 printf("%s: update error: blocks %" PRId64 496 printf("%s: update error: blocks %" PRId64
497 " files %d\n", 497 " files %d\n",
498 fs->fs_fsmnt, fs->fs_pendingblocks, 498 fs->fs_fsmnt, fs->fs_pendingblocks,
499 fs->fs_pendinginodes); 499 fs->fs_pendinginodes);
500 fs->fs_pendingblocks = 0; 500 fs->fs_pendingblocks = 0;
501 fs->fs_pendinginodes = 0; 501 fs->fs_pendinginodes = 0;
502 } 502 }
503 if (error == 0) 503 if (error == 0)
504 error = UFS_WAPBL_BEGIN(mp); 504 error = UFS_WAPBL_BEGIN(mp);
505 if (error == 0 && 505 if (error == 0 &&
506 ffs_cgupdate(ump, MNT_WAIT) == 0 && 506 ffs_cgupdate(ump, MNT_WAIT) == 0 &&
507 fs->fs_clean & FS_WASCLEAN) { 507 fs->fs_clean & FS_WASCLEAN) {
508 if (mp->mnt_flag & MNT_SOFTDEP) 508 if (mp->mnt_flag & MNT_SOFTDEP)
509 fs->fs_flags &= ~FS_DOSOFTDEP; 509 fs->fs_flags &= ~FS_DOSOFTDEP;
510 fs->fs_clean = FS_ISCLEAN; 510 fs->fs_clean = FS_ISCLEAN;
511 (void) ffs_sbupdate(ump, MNT_WAIT); 511 (void) ffs_sbupdate(ump, MNT_WAIT);
512 } 512 }
513 if (error == 0) 513 if (error == 0)
514 UFS_WAPBL_END(mp); 514 UFS_WAPBL_END(mp);
515 if (error) 515 if (error)
516 return (error); 516 return (error);
517 } 517 }
518 518
519#ifdef WAPBL 519#ifdef WAPBL
520 if ((mp->mnt_flag & MNT_LOG) == 0) { 520 if ((mp->mnt_flag & MNT_LOG) == 0) {
521 error = ffs_wapbl_stop(mp, mp->mnt_flag & MNT_FORCE); 521 error = ffs_wapbl_stop(mp, mp->mnt_flag & MNT_FORCE);
522 if (error) 522 if (error)
523 return error; 523 return error;
524 } 524 }
525#endif /* WAPBL */ 525#endif /* WAPBL */
526 526
527 if (fs->fs_ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) { 527 if (fs->fs_ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) {
528 /* 528 /*
529 * Finish change from r/w to r/o 529 * Finish change from r/w to r/o
530 */ 530 */
531 fs->fs_ronly = 1; 531 fs->fs_ronly = 1;
532 fs->fs_fmod = 0; 532 fs->fs_fmod = 0;
533 } 533 }
534 534
535 /* 535 /*
536 * Flush soft dependencies if disabling it via an update 536 * Flush soft dependencies if disabling it via an update
537 * mount. This may leave some items to be processed, 537 * mount. This may leave some items to be processed,
538 * so don't do this yet XXX. 538 * so don't do this yet XXX.
539 */ 539 */
540 if ((fs->fs_flags & FS_DOSOFTDEP) && 540 if ((fs->fs_flags & FS_DOSOFTDEP) &&
541 !(mp->mnt_flag & MNT_SOFTDEP) && fs->fs_ronly == 0) { 541 !(mp->mnt_flag & MNT_SOFTDEP) && fs->fs_ronly == 0) {
542#ifdef notyet 542#ifdef notyet
543 flags = WRITECLOSE; 543 flags = WRITECLOSE;
544 if (mp->mnt_flag & MNT_FORCE) 544 if (mp->mnt_flag & MNT_FORCE)
545 flags |= FORCECLOSE; 545 flags |= FORCECLOSE;
546 error = softdep_flushfiles(mp, flags, l); 546 error = softdep_flushfiles(mp, flags, l);
547 if (error == 0 && ffs_cgupdate(ump, MNT_WAIT) == 0) 547 if (error == 0 && ffs_cgupdate(ump, MNT_WAIT) == 0)
548 fs->fs_flags &= ~FS_DOSOFTDEP; 548 fs->fs_flags &= ~FS_DOSOFTDEP;
549 (void) ffs_sbupdate(ump, MNT_WAIT); 549 (void) ffs_sbupdate(ump, MNT_WAIT);
550#elif defined(SOFTDEP) 550#elif defined(SOFTDEP)
551 mp->mnt_flag |= MNT_SOFTDEP; 551 mp->mnt_flag |= MNT_SOFTDEP;
552#endif 552#endif
553 } 553 }
554 554
555 /* 555 /*
556 * When upgrading to a softdep mount, we must first flush 556 * When upgrading to a softdep mount, we must first flush
557 * all vnodes. (not done yet -- see above) 557 * all vnodes. (not done yet -- see above)
558 */ 558 */
559 if (!(fs->fs_flags & FS_DOSOFTDEP) && 559 if (!(fs->fs_flags & FS_DOSOFTDEP) &&
560 (mp->mnt_flag & MNT_SOFTDEP) && fs->fs_ronly == 0) { 560 (mp->mnt_flag & MNT_SOFTDEP) && fs->fs_ronly == 0) {
561#ifdef notyet 561#ifdef notyet
562 flags = WRITECLOSE; 562 flags = WRITECLOSE;
563 if (mp->mnt_flag & MNT_FORCE) 563 if (mp->mnt_flag & MNT_FORCE)
564 flags |= FORCECLOSE; 564 flags |= FORCECLOSE;
565 error = ffs_flushfiles(mp, flags, l); 565 error = ffs_flushfiles(mp, flags, l);
566#else 566#else
567 mp->mnt_flag &= ~MNT_SOFTDEP; 567 mp->mnt_flag &= ~MNT_SOFTDEP;
568#endif 568#endif
569 } 569 }
570 570
571 if (mp->mnt_flag & MNT_RELOAD) { 571 if (mp->mnt_flag & MNT_RELOAD) {
572 error = ffs_reload(mp, l->l_cred, l); 572 error = ffs_reload(mp, l->l_cred, l);
573 if (error) 573 if (error)
574 return (error); 574 return (error);
575 } 575 }
576 576
577 if (fs->fs_ronly && (mp->mnt_iflag & IMNT_WANTRDWR)) { 577 if (fs->fs_ronly && (mp->mnt_iflag & IMNT_WANTRDWR)) {
578 /* 578 /*
579 * Changing from read-only to read/write 579 * Changing from read-only to read/write
580 */ 580 */
581 fs->fs_ronly = 0; 581 fs->fs_ronly = 0;
582 fs->fs_clean <<= 1; 582 fs->fs_clean <<= 1;
583 fs->fs_fmod = 1; 583 fs->fs_fmod = 1;
584 if ((fs->fs_flags & FS_DOSOFTDEP)) { 584 if ((fs->fs_flags & FS_DOSOFTDEP)) {
585 error = softdep_mount(devvp, mp, fs, 585 error = softdep_mount(devvp, mp, fs,
586 l->l_cred); 586 l->l_cred);
587 if (error) 587 if (error)
588 return (error); 588 return (error);
589 } 589 }
590#ifdef WAPBL 590#ifdef WAPBL
591 if (fs->fs_flags & FS_DOWAPBL) { 591 if (fs->fs_flags & FS_DOWAPBL) {
592 printf("%s: replaying log to disk\n", 592 printf("%s: replaying log to disk\n",
593 path); 593 fs->fs_fsmnt);
594 KDASSERT(mp->mnt_wapbl_replay); 594 KDASSERT(mp->mnt_wapbl_replay);
595 error = wapbl_replay_write(mp->mnt_wapbl_replay, 595 error = wapbl_replay_write(mp->mnt_wapbl_replay,
596 devvp); 596 devvp);
597 if (error) { 597 if (error) {
598 return error; 598 return error;
599 } 599 }
600 wapbl_replay_stop(mp->mnt_wapbl_replay); 600 wapbl_replay_stop(mp->mnt_wapbl_replay);
601 fs->fs_clean = FS_WASCLEAN; 601 fs->fs_clean = FS_WASCLEAN;
602 } 602 }
603#endif /* WAPBL */ 603#endif /* WAPBL */
604 if (fs->fs_snapinum[0] != 0) 604 if (fs->fs_snapinum[0] != 0)
605 ffs_snapshot_mount(mp); 605 ffs_snapshot_mount(mp);
606 } 606 }
607 607
608#ifdef WAPBL 608#ifdef WAPBL
609 error = ffs_wapbl_start(mp); 609 error = ffs_wapbl_start(mp);
610 if (error) 610 if (error)
611 return error; 611 return error;
612#endif /* WAPBL */ 612#endif /* WAPBL */
613 613
614 if (args->fspec == NULL) 614 if (args->fspec == NULL)
615 return EINVAL; 615 return EINVAL;
616 if ((mp->mnt_flag & (MNT_SOFTDEP | MNT_ASYNC)) == 616 if ((mp->mnt_flag & (MNT_SOFTDEP | MNT_ASYNC)) ==
617 (MNT_SOFTDEP | MNT_ASYNC)) { 617 (MNT_SOFTDEP | MNT_ASYNC)) {
618 printf("%s fs uses soft updates, ignoring async mode\n", 618 printf("%s fs uses soft updates, ignoring async mode\n",
619 fs->fs_fsmnt); 619 fs->fs_fsmnt);
620 mp->mnt_flag &= ~MNT_ASYNC; 620 mp->mnt_flag &= ~MNT_ASYNC;
621 } 621 }
622 } 622 }
623 623
624 error = set_statvfs_info(path, UIO_USERSPACE, args->fspec, 624 error = set_statvfs_info(path, UIO_USERSPACE, args->fspec,
625 UIO_USERSPACE, mp->mnt_op->vfs_name, mp, l); 625 UIO_USERSPACE, mp->mnt_op->vfs_name, mp, l);
626 if (error == 0) 626 if (error == 0)
627 (void)strncpy(fs->fs_fsmnt, mp->mnt_stat.f_mntonname, 627 (void)strncpy(fs->fs_fsmnt, mp->mnt_stat.f_mntonname,
628 sizeof(fs->fs_fsmnt)); 628 sizeof(fs->fs_fsmnt));
629 if (mp->mnt_flag & MNT_SOFTDEP) 629 if (mp->mnt_flag & MNT_SOFTDEP)
630 fs->fs_flags |= FS_DOSOFTDEP; 630 fs->fs_flags |= FS_DOSOFTDEP;
631 else 631 else
632 fs->fs_flags &= ~FS_DOSOFTDEP; 632 fs->fs_flags &= ~FS_DOSOFTDEP;
633 if (fs->fs_fmod != 0) { /* XXX */ 633 if (fs->fs_fmod != 0) { /* XXX */
634 int err; 634 int err;
635 635
636 fs->fs_fmod = 0; 636 fs->fs_fmod = 0;
637 if (fs->fs_clean & FS_WASCLEAN) 637 if (fs->fs_clean & FS_WASCLEAN)
638 fs->fs_time = time_second; 638 fs->fs_time = time_second;
639 else { 639 else {
640 printf("%s: file system not clean (fs_clean=%#x); " 640 printf("%s: file system not clean (fs_clean=%#x); "
641 "please fsck(8)\n", mp->mnt_stat.f_mntfromname, 641 "please fsck(8)\n", mp->mnt_stat.f_mntfromname,
642 fs->fs_clean); 642 fs->fs_clean);
643 printf("%s: lost blocks %" PRId64 " files %d\n", 643 printf("%s: lost blocks %" PRId64 " files %d\n",
644 mp->mnt_stat.f_mntfromname, fs->fs_pendingblocks, 644 mp->mnt_stat.f_mntfromname, fs->fs_pendingblocks,
645 fs->fs_pendinginodes); 645 fs->fs_pendinginodes);
646 } 646 }
647 err = UFS_WAPBL_BEGIN(mp); 647 err = UFS_WAPBL_BEGIN(mp);
648 if (err == 0) { 648 if (err == 0) {
649 (void) ffs_cgupdate(ump, MNT_WAIT); 649 (void) ffs_cgupdate(ump, MNT_WAIT);
650 UFS_WAPBL_END(mp); 650 UFS_WAPBL_END(mp);
651 } 651 }
652 } 652 }
653 return (error); 653 return (error);
654 654
655fail: 655fail:
656 vrele(devvp); 656 vrele(devvp);
657 return (error); 657 return (error);
658} 658}
659 659
660/* 660/*
661 * Reload all incore data for a filesystem (used after running fsck on 661 * Reload all incore data for a filesystem (used after running fsck on
662 * the root filesystem and finding things to fix). The filesystem must 662 * the root filesystem and finding things to fix). The filesystem must
663 * be mounted read-only. 663 * be mounted read-only.
664 * 664 *
665 * Things to do to update the mount: 665 * Things to do to update the mount:
666 * 1) invalidate all cached meta-data. 666 * 1) invalidate all cached meta-data.
667 * 2) re-read superblock from disk. 667 * 2) re-read superblock from disk.
668 * 3) re-read summary information from disk. 668 * 3) re-read summary information from disk.
669 * 4) invalidate all inactive vnodes. 669 * 4) invalidate all inactive vnodes.
670 * 5) invalidate all cached file data. 670 * 5) invalidate all cached file data.
671 * 6) re-read inode data for all active vnodes. 671 * 6) re-read inode data for all active vnodes.
672 */ 672 */
673int 673int
674ffs_reload(struct mount *mp, kauth_cred_t cred, struct lwp *l) 674ffs_reload(struct mount *mp, kauth_cred_t cred, struct lwp *l)
675{ 675{
676 struct vnode *vp, *mvp, *devvp; 676 struct vnode *vp, *mvp, *devvp;
677 struct inode *ip; 677 struct inode *ip;
678 void *space; 678 void *space;
679 struct buf *bp; 679 struct buf *bp;
680 struct fs *fs, *newfs; 680 struct fs *fs, *newfs;
681 struct partinfo dpart; 681 struct partinfo dpart;
682 int i, blks, size, error; 682 int i, blks, size, error;
683 int32_t *lp; 683 int32_t *lp;
684 struct ufsmount *ump; 684 struct ufsmount *ump;
685 daddr_t sblockloc; 685 daddr_t sblockloc;
686 686
687 if ((mp->mnt_flag & MNT_RDONLY) == 0) 687 if ((mp->mnt_flag & MNT_RDONLY) == 0)
688 return (EINVAL); 688 return (EINVAL);
689 689
690 ump = VFSTOUFS(mp); 690 ump = VFSTOUFS(mp);
691 /* 691 /*
692 * Step 1: invalidate all cached meta-data. 692 * Step 1: invalidate all cached meta-data.
693 */ 693 */
694 devvp = ump->um_devvp; 694 devvp = ump->um_devvp;
695 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); 695 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
696 error = vinvalbuf(devvp, 0, cred, l, 0, 0); 696 error = vinvalbuf(devvp, 0, cred, l, 0, 0);
697 VOP_UNLOCK(devvp, 0); 697 VOP_UNLOCK(devvp, 0);
698 if (error) 698 if (error)
699 panic("ffs_reload: dirty1"); 699 panic("ffs_reload: dirty1");
700 /* 700 /*
701 * Step 2: re-read superblock from disk. 701 * Step 2: re-read superblock from disk.
702 */ 702 */
703 fs = ump->um_fs; 703 fs = ump->um_fs;
704 if (VOP_IOCTL(devvp, DIOCGPART, &dpart, FREAD, NOCRED) != 0) 704 if (VOP_IOCTL(devvp, DIOCGPART, &dpart, FREAD, NOCRED) != 0)
705 size = DEV_BSIZE; 705 size = DEV_BSIZE;
706 else 706 else
707 size = dpart.disklab->d_secsize; 707 size = dpart.disklab->d_secsize;
708 /* XXX we don't handle possibility that superblock moved. */ 708 /* XXX we don't handle possibility that superblock moved. */
709 error = bread(devvp, fs->fs_sblockloc / size, fs->fs_sbsize, 709 error = bread(devvp, fs->fs_sblockloc / size, fs->fs_sbsize,
710 NOCRED, 0, &bp); 710 NOCRED, 0, &bp);
711 if (error) { 711 if (error) {
712 brelse(bp, 0); 712 brelse(bp, 0);
713 return (error); 713 return (error);
714 } 714 }
715 newfs = malloc(fs->fs_sbsize, M_UFSMNT, M_WAITOK); 715 newfs = malloc(fs->fs_sbsize, M_UFSMNT, M_WAITOK);
716 memcpy(newfs, bp->b_data, fs->fs_sbsize); 716 memcpy(newfs, bp->b_data, fs->fs_sbsize);
717#ifdef FFS_EI 717#ifdef FFS_EI
718 if (ump->um_flags & UFS_NEEDSWAP) { 718 if (ump->um_flags & UFS_NEEDSWAP) {
719 ffs_sb_swap((struct fs*)bp->b_data, newfs); 719 ffs_sb_swap((struct fs*)bp->b_data, newfs);
720 fs->fs_flags |= FS_SWAPPED; 720 fs->fs_flags |= FS_SWAPPED;
721 } else 721 } else
722#endif 722#endif
723 fs->fs_flags &= ~FS_SWAPPED; 723 fs->fs_flags &= ~FS_SWAPPED;
724 if ((newfs->fs_magic != FS_UFS1_MAGIC && 724 if ((newfs->fs_magic != FS_UFS1_MAGIC &&
725 newfs->fs_magic != FS_UFS2_MAGIC)|| 725 newfs->fs_magic != FS_UFS2_MAGIC)||
726 newfs->fs_bsize > MAXBSIZE || 726 newfs->fs_bsize > MAXBSIZE ||
727 newfs->fs_bsize < sizeof(struct fs)) { 727 newfs->fs_bsize < sizeof(struct fs)) {
728 brelse(bp, 0); 728 brelse(bp, 0);
729 free(newfs, M_UFSMNT); 729 free(newfs, M_UFSMNT);
730 return (EIO); /* XXX needs translation */ 730 return (EIO); /* XXX needs translation */
731 } 731 }
732 /* Store off old fs_sblockloc for fs_oldfscompat_read. */ 732 /* Store off old fs_sblockloc for fs_oldfscompat_read. */
733 sblockloc = fs->fs_sblockloc; 733 sblockloc = fs->fs_sblockloc;
734 /* 734 /*
735 * Copy pointer fields back into superblock before copying in XXX 735 * Copy pointer fields back into superblock before copying in XXX
736 * new superblock. These should really be in the ufsmount. XXX 736 * new superblock. These should really be in the ufsmount. XXX
737 * Note that important parameters (eg fs_ncg) are unchanged. 737 * Note that important parameters (eg fs_ncg) are unchanged.
738 */ 738 */
739 newfs->fs_csp = fs->fs_csp; 739 newfs->fs_csp = fs->fs_csp;
740 newfs->fs_maxcluster = fs->fs_maxcluster; 740 newfs->fs_maxcluster = fs->fs_maxcluster;
741 newfs->fs_contigdirs = fs->fs_contigdirs; 741 newfs->fs_contigdirs = fs->fs_contigdirs;
742 newfs->fs_ronly = fs->fs_ronly; 742 newfs->fs_ronly = fs->fs_ronly;
743 newfs->fs_active = fs->fs_active; 743 newfs->fs_active = fs->fs_active;
744 memcpy(fs, newfs, (u_int)fs->fs_sbsize); 744 memcpy(fs, newfs, (u_int)fs->fs_sbsize);
745 brelse(bp, 0); 745 brelse(bp, 0);
746 free(newfs, M_UFSMNT); 746 free(newfs, M_UFSMNT);
747 747
748 /* Recheck for apple UFS filesystem */ 748 /* Recheck for apple UFS filesystem */
749 ump->um_flags &= ~UFS_ISAPPLEUFS; 749 ump->um_flags &= ~UFS_ISAPPLEUFS;
750 /* First check to see if this is tagged as an Apple UFS filesystem 750 /* First check to see if this is tagged as an Apple UFS filesystem
751 * in the disklabel 751 * in the disklabel
752 */ 752 */
753 if ((VOP_IOCTL(devvp, DIOCGPART, &dpart, FREAD, cred) == 0) && 753 if ((VOP_IOCTL(devvp, DIOCGPART, &dpart, FREAD, cred) == 0) &&
754 (dpart.part->p_fstype == FS_APPLEUFS)) { 754 (dpart.part->p_fstype == FS_APPLEUFS)) {
755 ump->um_flags |= UFS_ISAPPLEUFS; 755 ump->um_flags |= UFS_ISAPPLEUFS;
756 } 756 }
757#ifdef APPLE_UFS 757#ifdef APPLE_UFS
758 else { 758 else {
759 /* Manually look for an apple ufs label, and if a valid one 759 /* Manually look for an apple ufs label, and if a valid one
760 * is found, then treat it like an Apple UFS filesystem anyway 760 * is found, then treat it like an Apple UFS filesystem anyway
761 */ 761 */
762 error = bread(devvp, (daddr_t)(APPLEUFS_LABEL_OFFSET / size), 762 error = bread(devvp, (daddr_t)(APPLEUFS_LABEL_OFFSET / size),
763 APPLEUFS_LABEL_SIZE, cred, 0, &bp); 763 APPLEUFS_LABEL_SIZE, cred, 0, &bp);
764 if (error) { 764 if (error) {
765 brelse(bp, 0); 765 brelse(bp, 0);
766 return (error); 766 return (error);
767 } 767 }
768 error = ffs_appleufs_validate(fs->fs_fsmnt, 768 error = ffs_appleufs_validate(fs->fs_fsmnt,
769 (struct appleufslabel *)bp->b_data, NULL); 769 (struct appleufslabel *)bp->b_data, NULL);
770 if (error == 0) 770 if (error == 0)
771 ump->um_flags |= UFS_ISAPPLEUFS; 771 ump->um_flags |= UFS_ISAPPLEUFS;
772 brelse(bp, 0); 772 brelse(bp, 0);
773 bp = NULL; 773 bp = NULL;
774 } 774 }
775#else 775#else
776 if (ump->um_flags & UFS_ISAPPLEUFS) 776 if (ump->um_flags & UFS_ISAPPLEUFS)
777 return (EIO); 777 return (EIO);
778#endif 778#endif
779 779
780 if (UFS_MPISAPPLEUFS(ump)) { 780 if (UFS_MPISAPPLEUFS(ump)) {
781 /* see comment about NeXT below */ 781 /* see comment about NeXT below */
782 ump->um_maxsymlinklen = APPLEUFS_MAXSYMLINKLEN; 782 ump->um_maxsymlinklen = APPLEUFS_MAXSYMLINKLEN;
783 ump->um_dirblksiz = APPLEUFS_DIRBLKSIZ; 783 ump->um_dirblksiz = APPLEUFS_DIRBLKSIZ;
784 mp->mnt_iflag |= IMNT_DTYPE; 784 mp->mnt_iflag |= IMNT_DTYPE;
785 } else { 785 } else {
786 ump->um_maxsymlinklen = fs->fs_maxsymlinklen; 786 ump->um_maxsymlinklen = fs->fs_maxsymlinklen;
787 ump->um_dirblksiz = DIRBLKSIZ; 787 ump->um_dirblksiz = DIRBLKSIZ;
788 if (ump->um_maxsymlinklen > 0) 788 if (ump->um_maxsymlinklen > 0)
789 mp->mnt_iflag |= IMNT_DTYPE; 789 mp->mnt_iflag |= IMNT_DTYPE;
790 else 790 else
791 mp->mnt_iflag &= ~IMNT_DTYPE; 791 mp->mnt_iflag &= ~IMNT_DTYPE;
792 } 792 }
793 ffs_oldfscompat_read(fs, ump, sblockloc); 793 ffs_oldfscompat_read(fs, ump, sblockloc);
794 mutex_enter(&ump->um_lock); 794 mutex_enter(&ump->um_lock);
795 ump->um_maxfilesize = fs->fs_maxfilesize; 795 ump->um_maxfilesize = fs->fs_maxfilesize;
796 796
797 if (fs->fs_flags & ~(FS_KNOWN_FLAGS | FS_INTERNAL)) { 797 if (fs->fs_flags & ~(FS_KNOWN_FLAGS | FS_INTERNAL)) {
798 uprintf("%s: unknown ufs flags: 0x%08"PRIx32"%s\n", 798 uprintf("%s: unknown ufs flags: 0x%08"PRIx32"%s\n",
799 mp->mnt_stat.f_mntonname, fs->fs_flags, 799 mp->mnt_stat.f_mntonname, fs->fs_flags,
800 (mp->mnt_flag & MNT_FORCE) ? "" : ", not mounting"); 800 (mp->mnt_flag & MNT_FORCE) ? "" : ", not mounting");
801 if ((mp->mnt_flag & MNT_FORCE) == 0) { 801 if ((mp->mnt_flag & MNT_FORCE) == 0) {
802 mutex_exit(&ump->um_lock); 802 mutex_exit(&ump->um_lock);
803 return (EINVAL); 803 return (EINVAL);
804 } 804 }
805 } 805 }
806 806
807 if (fs->fs_pendingblocks != 0 || fs->fs_pendinginodes != 0) { 807 if (fs->fs_pendingblocks != 0 || fs->fs_pendinginodes != 0) {
808 fs->fs_pendingblocks = 0; 808 fs->fs_pendingblocks = 0;
809 fs->fs_pendinginodes = 0; 809 fs->fs_pendinginodes = 0;
810 } 810 }
811 mutex_exit(&ump->um_lock); 811 mutex_exit(&ump->um_lock);
812 812
813 ffs_statvfs(mp, &mp->mnt_stat); 813 ffs_statvfs(mp, &mp->mnt_stat);
814 /* 814 /*
815 * Step 3: re-read summary information from disk. 815 * Step 3: re-read summary information from disk.
816 */ 816 */
817 blks = howmany(fs->fs_cssize, fs->fs_fsize); 817 blks = howmany(fs->fs_cssize, fs->fs_fsize);
818 space = fs->fs_csp; 818 space = fs->fs_csp;
819 for (i = 0; i < blks; i += fs->fs_frag) { 819 for (i = 0; i < blks; i += fs->fs_frag) {
820 size = fs->fs_bsize; 820 size = fs->fs_bsize;
821 if (i + fs->fs_frag > blks) 821 if (i + fs->fs_frag > blks)
822 size = (blks - i) * fs->fs_fsize; 822 size = (blks - i) * fs->fs_fsize;
823 error = bread(devvp, fsbtodb(fs, fs->fs_csaddr + i), size, 823 error = bread(devvp, fsbtodb(fs, fs->fs_csaddr + i), size,
824 NOCRED, 0, &bp); 824 NOCRED, 0, &bp);
825 if (error) { 825 if (error) {
826 brelse(bp, 0); 826 brelse(bp, 0);
827 return (error); 827 return (error);
828 } 828 }
829#ifdef FFS_EI 829#ifdef FFS_EI
830 if (UFS_FSNEEDSWAP(fs)) 830 if (UFS_FSNEEDSWAP(fs))
831 ffs_csum_swap((struct csum *)bp->b_data, 831 ffs_csum_swap((struct csum *)bp->b_data,
832 (struct csum *)space, size); 832 (struct csum *)space, size);
833 else 833 else
834#endif 834#endif
835 memcpy(space, bp->b_data, (size_t)size); 835 memcpy(space, bp->b_data, (size_t)size);
836 space = (char *)space + size; 836 space = (char *)space + size;
837 brelse(bp, 0); 837 brelse(bp, 0);
838 } 838 }
839 if ((fs->fs_flags & FS_DOSOFTDEP)) 839 if ((fs->fs_flags & FS_DOSOFTDEP))
840 softdep_mount(devvp, mp, fs, cred); 840 softdep_mount(devvp, mp, fs, cred);
841 if (fs->fs_snapinum[0] != 0) 841 if (fs->fs_snapinum[0] != 0)
842 ffs_snapshot_mount(mp); 842 ffs_snapshot_mount(mp);
843 /* 843 /*
844 * We no longer know anything about clusters per cylinder group. 844 * We no longer know anything about clusters per cylinder group.
845 */ 845 */
846 if (fs->fs_contigsumsize > 0) { 846 if (fs->fs_contigsumsize > 0) {
847 lp = fs->fs_maxcluster; 847 lp = fs->fs_maxcluster;
848 for (i = 0; i < fs->fs_ncg; i++) 848 for (i = 0; i < fs->fs_ncg; i++)
849 *lp++ = fs->fs_contigsumsize; 849 *lp++ = fs->fs_contigsumsize;
850 } 850 }
851 851
852 /* Allocate a marker vnode. */ 852 /* Allocate a marker vnode. */
853 if ((mvp = vnalloc(mp)) == NULL) 853 if ((mvp = vnalloc(mp)) == NULL)
854 return ENOMEM; 854 return ENOMEM;
855 /* 855 /*
856 * NOTE: not using the TAILQ_FOREACH here since in this loop vgone() 856 * NOTE: not using the TAILQ_FOREACH here since in this loop vgone()
857 * and vclean() can be called indirectly 857 * and vclean() can be called indirectly
858 */ 858 */
859 mutex_enter(&mntvnode_lock); 859 mutex_enter(&mntvnode_lock);
860 loop: 860 loop:
861 for (vp = TAILQ_FIRST(&mp->mnt_vnodelist); vp; vp = vunmark(mvp)) { 861 for (vp = TAILQ_FIRST(&mp->mnt_vnodelist); vp; vp = vunmark(mvp)) {
862 vmark(mvp, vp); 862 vmark(mvp, vp);
863 if (vp->v_mount != mp || vismarker(vp)) 863 if (vp->v_mount != mp || vismarker(vp))
864 continue; 864 continue;
865 /* 865 /*
866 * Step 4: invalidate all inactive vnodes. 866 * Step 4: invalidate all inactive vnodes.
867 */ 867 */
868 if (vrecycle(vp, &mntvnode_lock, l)) { 868 if (vrecycle(vp, &mntvnode_lock, l)) {
869 mutex_enter(&mntvnode_lock); 869 mutex_enter(&mntvnode_lock);
870 (void)vunmark(mvp); 870 (void)vunmark(mvp);
871 goto loop; 871 goto loop;
872 } 872 }
873 /* 873 /*
874 * Step 5: invalidate all cached file data. 874 * Step 5: invalidate all cached file data.
875 */ 875 */
876 mutex_enter(&vp->v_interlock); 876 mutex_enter(&vp->v_interlock);
877 mutex_exit(&mntvnode_lock); 877 mutex_exit(&mntvnode_lock);
878 if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK)) { 878 if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK)) {
879 (void)vunmark(mvp); 879 (void)vunmark(mvp);
880 goto loop; 880 goto loop;
881 } 881 }
882 if (vinvalbuf(vp, 0, cred, l, 0, 0)) 882 if (vinvalbuf(vp, 0, cred, l, 0, 0))
883 panic("ffs_reload: dirty2"); 883 panic("ffs_reload: dirty2");
884 /* 884 /*
885 * Step 6: re-read inode data for all active vnodes. 885 * Step 6: re-read inode data for all active vnodes.
886 */ 886 */
887 ip = VTOI(vp); 887 ip = VTOI(vp);
888 error = bread(devvp, fsbtodb(fs, ino_to_fsba(fs, ip->i_number)), 888 error = bread(devvp, fsbtodb(fs, ino_to_fsba(fs, ip->i_number)),
889 (int)fs->fs_bsize, NOCRED, 0, &bp); 889 (int)fs->fs_bsize, NOCRED, 0, &bp);
890 if (error) { 890 if (error) {
891 brelse(bp, 0); 891 brelse(bp, 0);
892 vput(vp); 892 vput(vp);
893 (void)vunmark(mvp); 893 (void)vunmark(mvp);
894 break; 894 break;
895 } 895 }
896 ffs_load_inode(bp, ip, fs, ip->i_number); 896 ffs_load_inode(bp, ip, fs, ip->i_number);
897 ip->i_ffs_effnlink = ip->i_nlink; 897 ip->i_ffs_effnlink = ip->i_nlink;
898 brelse(bp, 0); 898 brelse(bp, 0);
899 vput(vp); 899 vput(vp);
900 mutex_enter(&mntvnode_lock); 900 mutex_enter(&mntvnode_lock);
901 } 901 }
902 mutex_exit(&mntvnode_lock); 902 mutex_exit(&mntvnode_lock);
903 vnfree(mvp); 903 vnfree(mvp);
904 return (error); 904 return (error);
905} 905}
906 906
907/* 907/*
908 * Possible superblock locations ordered from most to least likely. 908 * Possible superblock locations ordered from most to least likely.
909 */ 909 */
910static const int sblock_try[] = SBLOCKSEARCH; 910static const int sblock_try[] = SBLOCKSEARCH;
911 911
912/* 912/*
913 * Common code for mount and mountroot 913 * Common code for mount and mountroot
914 */ 914 */
915int 915int
916ffs_mountfs(struct vnode *devvp, struct mount *mp, struct lwp *l) 916ffs_mountfs(struct vnode *devvp, struct mount *mp, struct lwp *l)
917{ 917{
918 struct ufsmount *ump; 918 struct ufsmount *ump;
919 struct buf *bp; 919 struct buf *bp;
920 struct fs *fs; 920 struct fs *fs;
921 dev_t dev; 921 dev_t dev;
922 struct partinfo dpart; 922 struct partinfo dpart;
923 void *space; 923 void *space;
924 daddr_t sblockloc, fsblockloc; 924 daddr_t sblockloc, fsblockloc;
925 int blks, fstype; 925 int blks, fstype;
926 int error, i, size, ronly, bset = 0; 926 int error, i, size, ronly, bset = 0;
927#ifdef FFS_EI 927#ifdef FFS_EI
928 int needswap = 0; /* keep gcc happy */ 928 int needswap = 0; /* keep gcc happy */
929#endif 929#endif
930 int32_t *lp; 930 int32_t *lp;
931 kauth_cred_t cred; 931 kauth_cred_t cred;
932 u_int32_t sbsize = 8192; /* keep gcc happy*/ 932 u_int32_t sbsize = 8192; /* keep gcc happy*/
933 933
934 dev = devvp->v_rdev; 934 dev = devvp->v_rdev;
935 cred = l ? l->l_cred : NOCRED; 935 cred = l ? l->l_cred : NOCRED;
936 936
937 /* Flush out any old buffers remaining from a previous use. */ 937 /* Flush out any old buffers remaining from a previous use. */
938 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); 938 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
939 error = vinvalbuf(devvp, V_SAVE, cred, l, 0, 0); 939 error = vinvalbuf(devvp, V_SAVE, cred, l, 0, 0);
940 VOP_UNLOCK(devvp, 0); 940 VOP_UNLOCK(devvp, 0);
941 if (error) 941 if (error)
942 return (error); 942 return (error);
943 943
944 ronly = (mp->mnt_flag & MNT_RDONLY) != 0; 944 ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
945 if (VOP_IOCTL(devvp, DIOCGPART, &dpart, FREAD, cred) != 0) 945 if (VOP_IOCTL(devvp, DIOCGPART, &dpart, FREAD, cred) != 0)
946 size = DEV_BSIZE; 946 size = DEV_BSIZE;
947 else 947 else
948 size = dpart.disklab->d_secsize; 948 size = dpart.disklab->d_secsize;
949 949
950 bp = NULL; 950 bp = NULL;
951 ump = NULL; 951 ump = NULL;
952 fs = NULL; 952 fs = NULL;
953 sblockloc = 0; 953 sblockloc = 0;
954 fstype = 0; 954 fstype = 0;
955 955
956 error = fstrans_mount(mp); 956 error = fstrans_mount(mp);
957 if (error) 957 if (error)
958 return error; 958 return error;
959 959
960 ump = malloc(sizeof *ump, M_UFSMNT, M_WAITOK); 960 ump = malloc(sizeof *ump, M_UFSMNT, M_WAITOK);
961 memset(ump, 0, sizeof *ump); 961 memset(ump, 0, sizeof *ump);
962 mutex_init(&ump->um_lock, MUTEX_DEFAULT, IPL_NONE); 962 mutex_init(&ump->um_lock, MUTEX_DEFAULT, IPL_NONE);
963 error = ffs_snapshot_init(ump); 963 error = ffs_snapshot_init(ump);
964 if (error) 964 if (error)
965 goto out; 965 goto out;
966 ump->um_ops = &ffs_ufsops; 966 ump->um_ops = &ffs_ufsops;
967 967
968#ifdef WAPBL 968#ifdef WAPBL
969 sbagain: 969 sbagain:
970#endif 970#endif
971 /* 971 /*
972 * Try reading the superblock in each of its possible locations. 972 * Try reading the superblock in each of its possible locations.
973 */ 973 */
974 for (i = 0; ; i++) { 974 for (i = 0; ; i++) {
975 if (bp != NULL) { 975 if (bp != NULL) {
976 brelse(bp, BC_NOCACHE); 976 brelse(bp, BC_NOCACHE);
977 bp = NULL; 977 bp = NULL;
978 } 978 }
979 if (sblock_try[i] == -1) { 979 if (sblock_try[i] == -1) {
980 error = EINVAL; 980 error = EINVAL;
981 fs = NULL; 981 fs = NULL;
982 goto out; 982 goto out;
983 } 983 }
984 error = bread(devvp, sblock_try[i] / size, SBLOCKSIZE, cred, 984 error = bread(devvp, sblock_try[i] / size, SBLOCKSIZE, cred,
985 0, &bp); 985 0, &bp);
986 if (error) { 986 if (error) {
987 fs = NULL; 987 fs = NULL;
988 goto out; 988 goto out;
989 } 989 }
990 fs = (struct fs*)bp->b_data; 990 fs = (struct fs*)bp->b_data;
991 fsblockloc = sblockloc = sblock_try[i]; 991 fsblockloc = sblockloc = sblock_try[i];
992 if (fs->fs_magic == FS_UFS1_MAGIC) { 992 if (fs->fs_magic == FS_UFS1_MAGIC) {
993 sbsize = fs->fs_sbsize; 993 sbsize = fs->fs_sbsize;
994 fstype = UFS1; 994 fstype = UFS1;
995#ifdef FFS_EI 995#ifdef FFS_EI
996 needswap = 0; 996 needswap = 0;
997 } else if (fs->fs_magic == bswap32(FS_UFS1_MAGIC)) { 997 } else if (fs->fs_magic == bswap32(FS_UFS1_MAGIC)) {
998 sbsize = bswap32(fs->fs_sbsize); 998 sbsize = bswap32(fs->fs_sbsize);
999 fstype = UFS1; 999 fstype = UFS1;
1000 needswap = 1; 1000 needswap = 1;
1001#endif 1001#endif
1002 } else if (fs->fs_magic == FS_UFS2_MAGIC) { 1002 } else if (fs->fs_magic == FS_UFS2_MAGIC) {
1003 sbsize = fs->fs_sbsize; 1003 sbsize = fs->fs_sbsize;
1004 fstype = UFS2; 1004 fstype = UFS2;
1005#ifdef FFS_EI 1005#ifdef FFS_EI
1006 needswap = 0; 1006 needswap = 0;
1007 } else if (fs->fs_magic == bswap32(FS_UFS2_MAGIC)) { 1007 } else if (fs->fs_magic == bswap32(FS_UFS2_MAGIC)) {
1008 sbsize = bswap32(fs->fs_sbsize); 1008 sbsize = bswap32(fs->fs_sbsize);
1009 fstype = UFS2; 1009 fstype = UFS2;
1010 needswap = 1; 1010 needswap = 1;
1011#endif 1011#endif
1012 } else 1012 } else
1013 continue; 1013 continue;
1014 1014
1015 1015
1016 /* fs->fs_sblockloc isn't defined for old filesystems */ 1016 /* fs->fs_sblockloc isn't defined for old filesystems */
1017 if (fstype == UFS1 && !(fs->fs_old_flags & FS_FLAGS_UPDATED)) { 1017 if (fstype == UFS1 && !(fs->fs_old_flags & FS_FLAGS_UPDATED)) {
1018 if (sblockloc == SBLOCK_UFS2) 1018 if (sblockloc == SBLOCK_UFS2)
1019 /* 1019 /*
1020 * This is likely to be the first alternate 1020 * This is likely to be the first alternate
1021 * in a filesystem with 64k blocks. 1021 * in a filesystem with 64k blocks.
1022 * Don't use it. 1022 * Don't use it.
1023 */ 1023 */
1024 continue; 1024 continue;
1025 fsblockloc = sblockloc; 1025 fsblockloc = sblockloc;
1026 } else { 1026 } else {
1027 fsblockloc = fs->fs_sblockloc; 1027 fsblockloc = fs->fs_sblockloc;
1028#ifdef FFS_EI 1028#ifdef FFS_EI
1029 if (needswap) 1029 if (needswap)
1030 fsblockloc = bswap64(fsblockloc); 1030 fsblockloc = bswap64(fsblockloc);
1031#endif 1031#endif
1032 } 1032 }
1033 1033
1034 /* Check we haven't found an alternate superblock */ 1034 /* Check we haven't found an alternate superblock */
1035 if (fsblockloc != sblockloc) 1035 if (fsblockloc != sblockloc)
1036 continue; 1036 continue;
1037 1037
1038 /* Validate size of superblock */ 1038 /* Validate size of superblock */
1039 if (sbsize > MAXBSIZE || sbsize < sizeof(struct fs)) 1039 if (sbsize > MAXBSIZE || sbsize < sizeof(struct fs))
1040 continue; 1040 continue;
1041 1041
1042 /* Ok seems to be a good superblock */ 1042 /* Ok seems to be a good superblock */
1043 break; 1043 break;
1044 } 1044 }
1045 1045
1046 fs = malloc((u_long)sbsize, M_UFSMNT, M_WAITOK); 1046 fs = malloc((u_long)sbsize, M_UFSMNT, M_WAITOK);
1047 memcpy(fs, bp->b_data, sbsize); 1047 memcpy(fs, bp->b_data, sbsize);
1048 ump->um_fs = fs; 1048 ump->um_fs = fs;
1049 1049
1050#ifdef FFS_EI 1050#ifdef FFS_EI
1051 if (needswap) { 1051 if (needswap) {
1052 ffs_sb_swap((struct fs*)bp->b_data, fs); 1052 ffs_sb_swap((struct fs*)bp->b_data, fs);
1053 fs->fs_flags |= FS_SWAPPED; 1053 fs->fs_flags |= FS_SWAPPED;
1054 } else 1054 } else
1055#endif 1055#endif
1056 fs->fs_flags &= ~FS_SWAPPED; 1056 fs->fs_flags &= ~FS_SWAPPED;
1057 1057
1058#ifdef WAPBL 1058#ifdef WAPBL
1059 if ((mp->mnt_wapbl_replay == 0) && (fs->fs_flags & FS_DOWAPBL)) { 1059 if ((mp->mnt_wapbl_replay == 0) && (fs->fs_flags & FS_DOWAPBL)) {
1060 error = ffs_wapbl_replay_start(mp, fs, devvp); 1060 error = ffs_wapbl_replay_start(mp, fs, devvp);
1061 if (error) 1061 if (error)
1062 goto out; 1062 goto out;
1063 1063
1064 if (!ronly) { 1064 if (!ronly) {
1065 printf("%s: replaying log to disk\n", 1065 /* XXX fsmnt may be stale. */
1066 mp->mnt_stat.f_mntonname); 1066 printf("%s: replaying log to disk\n", fs->fs_fsmnt);
1067 error = wapbl_replay_write(mp->mnt_wapbl_replay, devvp); 1067 error = wapbl_replay_write(mp->mnt_wapbl_replay, devvp);
1068 if (error) 1068 if (error)
1069 goto out; 1069 goto out;
1070 wapbl_replay_stop(mp->mnt_wapbl_replay); 1070 wapbl_replay_stop(mp->mnt_wapbl_replay);
1071 fs->fs_clean = FS_WASCLEAN; 1071 fs->fs_clean = FS_WASCLEAN;
1072 } else { 1072 } else {
1073 printf("%s: replaying log to memory\n", 1073 /* XXX fsmnt may be stale */
1074 mp->mnt_stat.f_mntonname); 1074 printf("%s: replaying log to memory\n", fs->fs_fsmnt);
1075 } 1075 }
1076 1076
1077 /* Force a re-read of the superblock */ 1077 /* Force a re-read of the superblock */
1078 brelse(bp, BC_INVAL); 1078 brelse(bp, BC_INVAL);
1079 bp = NULL; 1079 bp = NULL;
1080 free(fs, M_UFSMNT); 1080 free(fs, M_UFSMNT);
1081 fs = NULL; 1081 fs = NULL;
1082 goto sbagain; 1082 goto sbagain;
1083 } 1083 }
1084#else /* !WAPBL */ 1084#else /* !WAPBL */
1085 if ((fs->fs_flags & FS_DOWAPBL) && (mp->mnt_flag & MNT_FORCE) == 0) { 1085 if ((fs->fs_flags & FS_DOWAPBL) && (mp->mnt_flag & MNT_FORCE) == 0) {
1086 error = EPERM; 1086 error = EPERM;
1087 goto out; 1087 goto out;
1088 } 1088 }
1089#endif /* !WAPBL */ 1089#endif /* !WAPBL */
1090 1090
1091 ffs_oldfscompat_read(fs, ump, sblockloc); 1091 ffs_oldfscompat_read(fs, ump, sblockloc);
1092 ump->um_maxfilesize = fs->fs_maxfilesize; 1092 ump->um_maxfilesize = fs->fs_maxfilesize;
1093 1093
1094 if (fs->fs_flags & ~(FS_KNOWN_FLAGS | FS_INTERNAL)) { 1094 if (fs->fs_flags & ~(FS_KNOWN_FLAGS | FS_INTERNAL)) {
1095 uprintf("%s: unknown ufs flags: 0x%08"PRIx32"%s\n", 1095 uprintf("%s: unknown ufs flags: 0x%08"PRIx32"%s\n",
1096 mp->mnt_stat.f_mntonname, fs->fs_flags, 1096 mp->mnt_stat.f_mntonname, fs->fs_flags,
1097 (mp->mnt_flag & MNT_FORCE) ? "" : ", not mounting"); 1097 (mp->mnt_flag & MNT_FORCE) ? "" : ", not mounting");
1098 if ((mp->mnt_flag & MNT_FORCE) == 0) { 1098 if ((mp->mnt_flag & MNT_FORCE) == 0) {
1099 error = EINVAL; 1099 error = EINVAL;
1100 goto out; 1100 goto out;
1101 } 1101 }
1102 } 1102 }
1103 1103
1104 if (fs->fs_pendingblocks != 0 || fs->fs_pendinginodes != 0) { 1104 if (fs->fs_pendingblocks != 0 || fs->fs_pendinginodes != 0) {
1105 fs->fs_pendingblocks = 0; 1105 fs->fs_pendingblocks = 0;
1106 fs->fs_pendinginodes = 0; 1106 fs->fs_pendinginodes = 0;
1107 } 1107 }
1108 1108
1109 ump->um_fstype = fstype; 1109 ump->um_fstype = fstype;
1110 if (fs->fs_sbsize < SBLOCKSIZE) 1110 if (fs->fs_sbsize < SBLOCKSIZE)
1111 brelse(bp, BC_INVAL); 1111 brelse(bp, BC_INVAL);
1112 else 1112 else
1113 brelse(bp, 0); 1113 brelse(bp, 0);
1114 bp = NULL; 1114 bp = NULL;
1115 1115
1116 /* First check to see if this is tagged as an Apple UFS filesystem 1116 /* First check to see if this is tagged as an Apple UFS filesystem
1117 * in the disklabel 1117 * in the disklabel
1118 */ 1118 */
1119 if ((VOP_IOCTL(devvp, DIOCGPART, &dpart, FREAD, cred) == 0) && 1119 if ((VOP_IOCTL(devvp, DIOCGPART, &dpart, FREAD, cred) == 0) &&
1120 (dpart.part->p_fstype == FS_APPLEUFS)) { 1120 (dpart.part->p_fstype == FS_APPLEUFS)) {
1121 ump->um_flags |= UFS_ISAPPLEUFS; 1121 ump->um_flags |= UFS_ISAPPLEUFS;
1122 } 1122 }
1123#ifdef APPLE_UFS 1123#ifdef APPLE_UFS
1124 else { 1124 else {
1125 /* Manually look for an apple ufs label, and if a valid one 1125 /* Manually look for an apple ufs label, and if a valid one
1126 * is found, then treat it like an Apple UFS filesystem anyway 1126 * is found, then treat it like an Apple UFS filesystem anyway
1127 */ 1127 */
1128 error = bread(devvp, (daddr_t)(APPLEUFS_LABEL_OFFSET / size), 1128 error = bread(devvp, (daddr_t)(APPLEUFS_LABEL_OFFSET / size),
1129 APPLEUFS_LABEL_SIZE, cred, 0, &bp); 1129 APPLEUFS_LABEL_SIZE, cred, 0, &bp);
1130 if (error) 1130 if (error)
1131 goto out; 1131 goto out;
1132 error = ffs_appleufs_validate(fs->fs_fsmnt, 1132 error = ffs_appleufs_validate(fs->fs_fsmnt,
1133 (struct appleufslabel *)bp->b_data, NULL); 1133 (struct appleufslabel *)bp->b_data, NULL);
1134 if (error == 0) { 1134 if (error == 0) {
1135 ump->um_flags |= UFS_ISAPPLEUFS; 1135 ump->um_flags |= UFS_ISAPPLEUFS;
1136 } 1136 }
1137 brelse(bp, 0); 1137 brelse(bp, 0);
1138 bp = NULL; 1138 bp = NULL;
1139 } 1139 }
1140#else 1140#else
1141 if (ump->um_flags & UFS_ISAPPLEUFS) { 1141 if (ump->um_flags & UFS_ISAPPLEUFS) {
1142 error = EINVAL; 1142 error = EINVAL;
1143 goto out; 1143 goto out;
1144 } 1144 }
1145#endif 1145#endif
1146 1146
1147#if 0 1147#if 0
1148/* 1148/*
1149 * XXX This code changes the behaviour of mounting dirty filesystems, to 1149 * XXX This code changes the behaviour of mounting dirty filesystems, to
1150 * XXX require "mount -f ..." to mount them. This doesn't match what 1150 * XXX require "mount -f ..." to mount them. This doesn't match what
1151 * XXX mount(8) describes and is disabled for now. 1151 * XXX mount(8) describes and is disabled for now.
1152 */ 1152 */
1153 /* 1153 /*
1154 * If the file system is not clean, don't allow it to be mounted 1154 * If the file system is not clean, don't allow it to be mounted
1155 * unless MNT_FORCE is specified. (Note: MNT_FORCE is always set 1155 * unless MNT_FORCE is specified. (Note: MNT_FORCE is always set
1156 * for the root file system.) 1156 * for the root file system.)
1157 */ 1157 */
1158 if (fs->fs_flags & FS_DOWAPBL) { 1158 if (fs->fs_flags & FS_DOWAPBL) {
1159 /* 1159 /*
1160 * wapbl normally expects to be FS_WASCLEAN when the FS_DOWAPBL 1160 * wapbl normally expects to be FS_WASCLEAN when the FS_DOWAPBL
1161 * bit is set, although there's a window in unmount where it 1161 * bit is set, although there's a window in unmount where it
1162 * could be FS_ISCLEAN 1162 * could be FS_ISCLEAN
1163 */ 1163 */
1164 if ((mp->mnt_flag & MNT_FORCE) == 0 && 1164 if ((mp->mnt_flag & MNT_FORCE) == 0 &&
1165 (fs->fs_clean & (FS_WASCLEAN | FS_ISCLEAN)) == 0) { 1165 (fs->fs_clean & (FS_WASCLEAN | FS_ISCLEAN)) == 0) {
1166 error = EPERM; 1166 error = EPERM;
1167 goto out; 1167 goto out;
1168 } 1168 }
1169 } else 1169 } else
1170 if ((fs->fs_clean & FS_ISCLEAN) == 0 && 1170 if ((fs->fs_clean & FS_ISCLEAN) == 0 &&
1171 (mp->mnt_flag & MNT_FORCE) == 0) { 1171 (mp->mnt_flag & MNT_FORCE) == 0) {
1172 error = EPERM; 1172 error = EPERM;
1173 goto out; 1173 goto out;
1174 } 1174 }
1175#endif 1175#endif
1176 1176
1177 /* 1177 /*
1178 * verify that we can access the last block in the fs 1178 * verify that we can access the last block in the fs
1179 * if we're mounting read/write. 1179 * if we're mounting read/write.
1180 */ 1180 */
1181 1181
1182 if (!ronly) { 1182 if (!ronly) {
1183 error = bread(devvp, fsbtodb(fs, fs->fs_size - 1), fs->fs_fsize, 1183 error = bread(devvp, fsbtodb(fs, fs->fs_size - 1), fs->fs_fsize,
1184 cred, 0, &bp); 1184 cred, 0, &bp);
1185 if (bp->b_bcount != fs->fs_fsize) 1185 if (bp->b_bcount != fs->fs_fsize)
1186 error = EINVAL; 1186 error = EINVAL;
1187 if (error) { 1187 if (error) {
1188 bset = BC_INVAL; 1188 bset = BC_INVAL;
1189 goto out; 1189 goto out;
1190 } 1190 }
1191 brelse(bp, BC_INVAL); 1191 brelse(bp, BC_INVAL);
1192 bp = NULL; 1192 bp = NULL;
1193 } 1193 }
1194 1194
1195 fs->fs_ronly = ronly; 1195 fs->fs_ronly = ronly;
1196 /* Don't bump fs_clean if we're replaying journal */ 1196 /* Don't bump fs_clean if we're replaying journal */
1197 if (!((fs->fs_flags & FS_DOWAPBL) && (fs->fs_clean & FS_WASCLEAN))) 1197 if (!((fs->fs_flags & FS_DOWAPBL) && (fs->fs_clean & FS_WASCLEAN)))
1198 if (ronly == 0) { 1198 if (ronly == 0) {
1199 fs->fs_clean <<= 1; 1199 fs->fs_clean <<= 1;
1200 fs->fs_fmod = 1; 1200 fs->fs_fmod = 1;
1201 } 1201 }
1202 size = fs->fs_cssize; 1202 size = fs->fs_cssize;
1203 blks = howmany(size, fs->fs_fsize); 1203 blks = howmany(size, fs->fs_fsize);
1204 if (fs->fs_contigsumsize > 0) 1204 if (fs->fs_contigsumsize > 0)
1205 size += fs->fs_ncg * sizeof(int32_t); 1205 size += fs->fs_ncg * sizeof(int32_t);
1206 size += fs->fs_ncg * sizeof(*fs->fs_contigdirs); 1206 size += fs->fs_ncg * sizeof(*fs->fs_contigdirs);
1207 space = malloc((u_long)size, M_UFSMNT, M_WAITOK); 1207 space = malloc((u_long)size, M_UFSMNT, M_WAITOK);
1208 fs->fs_csp = space; 1208 fs->fs_csp = space;
1209 for (i = 0; i < blks; i += fs->fs_frag) { 1209 for (i = 0; i < blks; i += fs->fs_frag) {
1210 size = fs->fs_bsize; 1210 size = fs->fs_bsize;
1211 if (i + fs->fs_frag > blks) 1211 if (i + fs->fs_frag > blks)
1212 size = (blks - i) * fs->fs_fsize; 1212 size = (blks - i) * fs->fs_fsize;
1213 error = bread(devvp, fsbtodb(fs, fs->fs_csaddr + i), size, 1213 error = bread(devvp, fsbtodb(fs, fs->fs_csaddr + i), size,
1214 cred, 0, &bp); 1214 cred, 0, &bp);
1215 if (error) { 1215 if (error) {
1216 free(fs->fs_csp, M_UFSMNT); 1216 free(fs->fs_csp, M_UFSMNT);
1217 goto out; 1217 goto out;
1218 } 1218 }
1219#ifdef FFS_EI 1219#ifdef FFS_EI
1220 if (needswap) 1220 if (needswap)
1221 ffs_csum_swap((struct csum *)bp->b_data, 1221 ffs_csum_swap((struct csum *)bp->b_data,
1222 (struct csum *)space, size); 1222 (struct csum *)space, size);
1223 else 1223 else
1224#endif 1224#endif
1225 memcpy(space, bp->b_data, (u_int)size); 1225 memcpy(space, bp->b_data, (u_int)size);
1226 1226
1227 space = (char *)space + size; 1227 space = (char *)space + size;
1228 brelse(bp, 0); 1228 brelse(bp, 0);
1229 bp = NULL; 1229 bp = NULL;
1230 } 1230 }
1231 if (fs->fs_contigsumsize > 0) { 1231 if (fs->fs_contigsumsize > 0) {
1232 fs->fs_maxcluster = lp = space; 1232 fs->fs_maxcluster = lp = space;
1233 for (i = 0; i < fs->fs_ncg; i++) 1233 for (i = 0; i < fs->fs_ncg; i++)
1234 *lp++ = fs->fs_contigsumsize; 1234 *lp++ = fs->fs_contigsumsize;
1235 space = lp; 1235 space = lp;
1236 } 1236 }
1237 size = fs->fs_ncg * sizeof(*fs->fs_contigdirs); 1237 size = fs->fs_ncg * sizeof(*fs->fs_contigdirs);
1238 fs->fs_contigdirs = space; 1238 fs->fs_contigdirs = space;
1239 space = (char *)space + size; 1239 space = (char *)space + size;
1240 memset(fs->fs_contigdirs, 0, size); 1240 memset(fs->fs_contigdirs, 0, size);
1241 /* Compatibility for old filesystems - XXX */ 1241 /* Compatibility for old filesystems - XXX */
1242 if (fs->fs_avgfilesize <= 0) 1242 if (fs->fs_avgfilesize <= 0)
1243 fs->fs_avgfilesize = AVFILESIZ; 1243 fs->fs_avgfilesize = AVFILESIZ;
1244 if (fs->fs_avgfpdir <= 0) 1244 if (fs->fs_avgfpdir <= 0)
1245 fs->fs_avgfpdir = AFPDIR; 1245 fs->fs_avgfpdir = AFPDIR;
1246 fs->fs_active = NULL; 1246 fs->fs_active = NULL;
1247 mp->mnt_data = ump; 1247 mp->mnt_data = ump;
1248 mp->mnt_stat.f_fsidx.__fsid_val[0] = (long)dev; 1248 mp->mnt_stat.f_fsidx.__fsid_val[0] = (long)dev;
1249 mp->mnt_stat.f_fsidx.__fsid_val[1] = makefstype(MOUNT_FFS); 1249 mp->mnt_stat.f_fsidx.__fsid_val[1] = makefstype(MOUNT_FFS);
1250 mp->mnt_stat.f_fsid = mp->mnt_stat.f_fsidx.__fsid_val[0]; 1250 mp->mnt_stat.f_fsid = mp->mnt_stat.f_fsidx.__fsid_val[0];
1251 mp->mnt_stat.f_namemax = FFS_MAXNAMLEN; 1251 mp->mnt_stat.f_namemax = FFS_MAXNAMLEN;
1252 if (UFS_MPISAPPLEUFS(ump)) { 1252 if (UFS_MPISAPPLEUFS(ump)) {
1253 /* NeXT used to keep short symlinks in the inode even 1253 /* NeXT used to keep short symlinks in the inode even
1254 * when using FS_42INODEFMT. In that case fs->fs_maxsymlinklen 1254 * when using FS_42INODEFMT. In that case fs->fs_maxsymlinklen
1255 * is probably -1, but we still need to be able to identify 1255 * is probably -1, but we still need to be able to identify
1256 * short symlinks. 1256 * short symlinks.
1257 */ 1257 */
1258 ump->um_maxsymlinklen = APPLEUFS_MAXSYMLINKLEN; 1258 ump->um_maxsymlinklen = APPLEUFS_MAXSYMLINKLEN;
1259 ump->um_dirblksiz = APPLEUFS_DIRBLKSIZ; 1259 ump->um_dirblksiz = APPLEUFS_DIRBLKSIZ;
1260 mp->mnt_iflag |= IMNT_DTYPE; 1260 mp->mnt_iflag |= IMNT_DTYPE;
1261 } else { 1261 } else {
1262 ump->um_maxsymlinklen = fs->fs_maxsymlinklen; 1262 ump->um_maxsymlinklen = fs->fs_maxsymlinklen;
1263 ump->um_dirblksiz = DIRBLKSIZ; 1263 ump->um_dirblksiz = DIRBLKSIZ;
1264 if (ump->um_maxsymlinklen > 0) 1264 if (ump->um_maxsymlinklen > 0)
1265 mp->mnt_iflag |= IMNT_DTYPE; 1265 mp->mnt_iflag |= IMNT_DTYPE;
1266 else 1266 else
1267 mp->mnt_iflag &= ~IMNT_DTYPE; 1267 mp->mnt_iflag &= ~IMNT_DTYPE;
1268 } 1268 }
1269 mp->mnt_fs_bshift = fs->fs_bshift; 1269 mp->mnt_fs_bshift = fs->fs_bshift;
1270 mp->mnt_dev_bshift = DEV_BSHIFT; /* XXX */ 1270 mp->mnt_dev_bshift = DEV_BSHIFT; /* XXX */
1271 mp->mnt_flag |= MNT_LOCAL; 1271 mp->mnt_flag |= MNT_LOCAL;
1272 mp->mnt_iflag |= IMNT_MPSAFE; 1272 mp->mnt_iflag |= IMNT_MPSAFE;
1273#ifdef FFS_EI 1273#ifdef FFS_EI
1274 if (needswap) 1274 if (needswap)
1275 ump->um_flags |= UFS_NEEDSWAP; 1275 ump->um_flags |= UFS_NEEDSWAP;
1276#endif 1276#endif
1277 ump->um_mountp = mp; 1277 ump->um_mountp = mp;
1278 ump->um_dev = dev; 1278 ump->um_dev = dev;
1279 ump->um_devvp = devvp; 1279 ump->um_devvp = devvp;
1280 ump->um_nindir = fs->fs_nindir; 1280 ump->um_nindir = fs->fs_nindir;
1281 ump->um_lognindir = ffs(fs->fs_nindir) - 1; 1281 ump->um_lognindir = ffs(fs->fs_nindir) - 1;
1282 ump->um_bptrtodb = fs->fs_fsbtodb; 1282 ump->um_bptrtodb = fs->fs_fsbtodb;
1283 ump->um_seqinc = fs->fs_frag; 1283 ump->um_seqinc = fs->fs_frag;
1284 for (i = 0; i < MAXQUOTAS; i++) 1284 for (i = 0; i < MAXQUOTAS; i++)
1285 ump->um_quotas[i] = NULLVP; 1285 ump->um_quotas[i] = NULLVP;
1286 devvp->v_specmountpoint = mp; 1286 devvp->v_specmountpoint = mp;
1287 if (ronly == 0 && (fs->fs_flags & FS_DOSOFTDEP)) { 1287 if (ronly == 0 && (fs->fs_flags & FS_DOSOFTDEP)) {
1288 error = softdep_mount(devvp, mp, fs, cred); 1288 error = softdep_mount(devvp, mp, fs, cred);
1289 if (error) { 1289 if (error) {
1290 free(fs->fs_csp, M_UFSMNT); 1290 free(fs->fs_csp, M_UFSMNT);
1291 goto out; 1291 goto out;
1292 } 1292 }
1293 } 1293 }
1294 if (ronly == 0 && fs->fs_snapinum[0] != 0) 1294 if (ronly == 0 && fs->fs_snapinum[0] != 0)
1295 ffs_snapshot_mount(mp); 1295 ffs_snapshot_mount(mp);
1296 1296
1297#ifdef WAPBL 1297#ifdef WAPBL
1298 if (!ronly) { 1298 if (!ronly) {
1299 KDASSERT(fs->fs_ronly == 0); 1299 KDASSERT(fs->fs_ronly == 0);
1300 /* 1300 /*
1301 * ffs_wapbl_start() needs mp->mnt_stat initialised if it 1301 * ffs_wapbl_start() needs mp->mnt_stat initialised if it
1302 * needs to create a new log file in-filesystem. 1302 * needs to create a new log file in-filesystem.
1303 */ 1303 */
1304 ffs_statvfs(mp, &mp->mnt_stat); 1304 ffs_statvfs(mp, &mp->mnt_stat);
1305 1305
1306 error = ffs_wapbl_start(mp); 1306 error = ffs_wapbl_start(mp);
1307 if (error) { 1307 if (error) {
1308 free(fs->fs_csp, M_UFSMNT); 1308 free(fs->fs_csp, M_UFSMNT);
1309 goto out; 1309 goto out;
1310 } 1310 }
1311 } 1311 }
1312#endif /* WAPBL */ 1312#endif /* WAPBL */
1313#ifdef UFS_EXTATTR 1313#ifdef UFS_EXTATTR
1314 /* 1314 /*
1315 * Initialize file-backed extended attributes on UFS1 file 1315 * Initialize file-backed extended attributes on UFS1 file
1316 * systems. 1316 * systems.
1317 */ 1317 */
1318 if (ump->um_fstype == UFS1) { 1318 if (ump->um_fstype == UFS1) {
1319 ufs_extattr_uepm_init(&ump->um_extattr); 1319 ufs_extattr_uepm_init(&ump->um_extattr);
1320#ifdef UFS_EXTATTR_AUTOSTART 1320#ifdef UFS_EXTATTR_AUTOSTART
1321 /* 1321 /*
1322 * XXX Just ignore errors. Not clear that we should 1322 * XXX Just ignore errors. Not clear that we should
1323 * XXX fail the mount in this case. 1323 * XXX fail the mount in this case.
1324 */ 1324 */
1325 (void) ufs_extattr_autostart(mp, l); 1325 (void) ufs_extattr_autostart(mp, l);
1326#endif 1326#endif
1327 } 1327 }
1328#endif /* UFS_EXTATTR */ 1328#endif /* UFS_EXTATTR */
1329 return (0); 1329 return (0);
1330out: 1330out:
1331#ifdef WAPBL 1331#ifdef WAPBL
1332 if (mp->mnt_wapbl_replay) { 1332 if (mp->mnt_wapbl_replay) {
1333 if (wapbl_replay_isopen(mp->mnt_wapbl_replay)) 1333 if (wapbl_replay_isopen(mp->mnt_wapbl_replay))
1334 wapbl_replay_stop(mp->mnt_wapbl_replay); 1334 wapbl_replay_stop(mp->mnt_wapbl_replay);
1335 wapbl_replay_free(mp->mnt_wapbl_replay); 1335 wapbl_replay_free(mp->mnt_wapbl_replay);
1336 mp->mnt_wapbl_replay = 0; 1336 mp->mnt_wapbl_replay = 0;
1337 } 1337 }
1338#endif 1338#endif
1339 1339
1340 fstrans_unmount(mp); 1340 fstrans_unmount(mp);
1341 if (fs) 1341 if (fs)
1342 free(fs, M_UFSMNT); 1342 free(fs, M_UFSMNT);
1343 devvp->v_specmountpoint = NULL; 1343 devvp->v_specmountpoint = NULL;
1344 if (bp) 1344 if (bp)
1345 brelse(bp, bset); 1345 brelse(bp, bset);
1346 if (ump) { 1346 if (ump) {
1347 if (ump->um_oldfscompat) 1347 if (ump->um_oldfscompat)
1348 free(ump->um_oldfscompat, M_UFSMNT); 1348 free(ump->um_oldfscompat, M_UFSMNT);
1349 mutex_destroy(&ump->um_lock); 1349 mutex_destroy(&ump->um_lock);
1350 free(ump, M_UFSMNT); 1350 free(ump, M_UFSMNT);
1351 mp->mnt_data = NULL; 1351 mp->mnt_data = NULL;
1352 } 1352 }
1353 return (error); 1353 return (error);
1354} 1354}
1355 1355
1356/* 1356/*
1357 * Sanity checks for loading old filesystem superblocks. 1357 * Sanity checks for loading old filesystem superblocks.
1358 * See ffs_oldfscompat_write below for unwound actions. 1358 * See ffs_oldfscompat_write below for unwound actions.
1359 * 1359 *
1360 * XXX - Parts get retired eventually. 1360 * XXX - Parts get retired eventually.
1361 * Unfortunately new bits get added. 1361 * Unfortunately new bits get added.
1362 */ 1362 */
1363static void 1363static void
1364ffs_oldfscompat_read(struct fs *fs, struct ufsmount *ump, daddr_t sblockloc) 1364ffs_oldfscompat_read(struct fs *fs, struct ufsmount *ump, daddr_t sblockloc)
1365{ 1365{
1366 off_t maxfilesize; 1366 off_t maxfilesize;
1367 int32_t *extrasave; 1367 int32_t *extrasave;
1368 1368
1369 if ((fs->fs_magic != FS_UFS1_MAGIC) || 1369 if ((fs->fs_magic != FS_UFS1_MAGIC) ||
1370 (fs->fs_old_flags & FS_FLAGS_UPDATED)) 1370 (fs->fs_old_flags & FS_FLAGS_UPDATED))
1371 return; 1371 return;
1372 1372
1373 if (!ump->um_oldfscompat) 1373 if (!ump->um_oldfscompat)
1374 ump->um_oldfscompat = malloc(512 + 3*sizeof(int32_t), 1374 ump->um_oldfscompat = malloc(512 + 3*sizeof(int32_t),
1375 M_UFSMNT, M_WAITOK); 1375 M_UFSMNT, M_WAITOK);
1376 1376
1377 memcpy(ump->um_oldfscompat, &fs->fs_old_postbl_start, 512); 1377 memcpy(ump->um_oldfscompat, &fs->fs_old_postbl_start, 512);
1378 extrasave = ump->um_oldfscompat; 1378 extrasave = ump->um_oldfscompat;
1379 extrasave += 512/sizeof(int32_t); 1379 extrasave += 512/sizeof(int32_t);
1380 extrasave[0] = fs->fs_old_npsect; 1380 extrasave[0] = fs->fs_old_npsect;
1381 extrasave[1] = fs->fs_old_interleave; 1381 extrasave[1] = fs->fs_old_interleave;
1382 extrasave[2] = fs->fs_old_trackskew; 1382 extrasave[2] = fs->fs_old_trackskew;
1383 1383
1384 /* These fields will be overwritten by their 1384 /* These fields will be overwritten by their
1385 * original values in fs_oldfscompat_write, so it is harmless 1385 * original values in fs_oldfscompat_write, so it is harmless
1386 * to modify them here. 1386 * to modify them here.
1387 */ 1387 */
1388 fs->fs_cstotal.cs_ndir = fs->fs_old_cstotal.cs_ndir; 1388 fs->fs_cstotal.cs_ndir = fs->fs_old_cstotal.cs_ndir;
1389 fs->fs_cstotal.cs_nbfree = fs->fs_old_cstotal.cs_nbfree; 1389 fs->fs_cstotal.cs_nbfree = fs->fs_old_cstotal.cs_nbfree;
1390 fs->fs_cstotal.cs_nifree = fs->fs_old_cstotal.cs_nifree; 1390 fs->fs_cstotal.cs_nifree = fs->fs_old_cstotal.cs_nifree;
1391 fs->fs_cstotal.cs_nffree = fs->fs_old_cstotal.cs_nffree; 1391 fs->fs_cstotal.cs_nffree = fs->fs_old_cstotal.cs_nffree;
1392 1392
1393 fs->fs_maxbsize = fs->fs_bsize; 1393 fs->fs_maxbsize = fs->fs_bsize;
1394 fs->fs_time = fs->fs_old_time; 1394 fs->fs_time = fs->fs_old_time;
1395 fs->fs_size = fs->fs_old_size; 1395 fs->fs_size = fs->fs_old_size;
1396 fs->fs_dsize = fs->fs_old_dsize; 1396 fs->fs_dsize = fs->fs_old_dsize;
1397 fs->fs_csaddr = fs->fs_old_csaddr; 1397 fs->fs_csaddr = fs->fs_old_csaddr;
1398 fs->fs_sblockloc = sblockloc; 1398 fs->fs_sblockloc = sblockloc;
1399 1399
1400 fs->fs_flags = fs->fs_old_flags | (fs->fs_flags & FS_INTERNAL); 1400 fs->fs_flags = fs->fs_old_flags | (fs->fs_flags & FS_INTERNAL);
1401 1401
1402 if (fs->fs_old_postblformat == FS_42POSTBLFMT) { 1402 if (fs->fs_old_postblformat == FS_42POSTBLFMT) {
1403 fs->fs_old_nrpos = 8; 1403 fs->fs_old_nrpos = 8;
1404 fs->fs_old_npsect = fs->fs_old_nsect; 1404 fs->fs_old_npsect = fs->fs_old_nsect;
1405 fs->fs_old_interleave = 1; 1405 fs->fs_old_interleave = 1;
1406 fs->fs_old_trackskew = 0; 1406 fs->fs_old_trackskew = 0;
1407 } 1407 }
1408 1408
1409 if (fs->fs_old_inodefmt < FS_44INODEFMT) { 1409 if (fs->fs_old_inodefmt < FS_44INODEFMT) {
1410 fs->fs_maxfilesize = (u_quad_t) 1LL << 39; 1410 fs->fs_maxfilesize = (u_quad_t) 1LL << 39;
1411 fs->fs_qbmask = ~fs->fs_bmask; 1411 fs->fs_qbmask = ~fs->fs_bmask;
1412 fs->fs_qfmask = ~fs->fs_fmask; 1412 fs->fs_qfmask = ~fs->fs_fmask;
1413 } 1413 }
1414 1414
1415 maxfilesize = (u_int64_t)0x80000000 * fs->fs_bsize - 1; 1415 maxfilesize = (u_int64_t)0x80000000 * fs->fs_bsize - 1;
1416 if (fs->fs_maxfilesize > maxfilesize) 1416 if (fs->fs_maxfilesize > maxfilesize)
1417 fs->fs_maxfilesize = maxfilesize; 1417 fs->fs_maxfilesize = maxfilesize;
1418 1418
1419 /* Compatibility for old filesystems */ 1419 /* Compatibility for old filesystems */
1420 if (fs->fs_avgfilesize <= 0) 1420 if (fs->fs_avgfilesize <= 0)
1421 fs->fs_avgfilesize = AVFILESIZ; 1421 fs->fs_avgfilesize = AVFILESIZ;
1422 if (fs->fs_avgfpdir <= 0) 1422 if (fs->fs_avgfpdir <= 0)
1423 fs->fs_avgfpdir = AFPDIR; 1423 fs->fs_avgfpdir = AFPDIR;
1424 1424
1425#if 0 1425#if 0
1426 if (bigcgs) { 1426 if (bigcgs) {
1427 fs->fs_save_cgsize = fs->fs_cgsize; 1427 fs->fs_save_cgsize = fs->fs_cgsize;
1428 fs->fs_cgsize = fs->fs_bsize; 1428 fs->fs_cgsize = fs->fs_bsize;
1429 } 1429 }
1430#endif 1430#endif
1431} 1431}
1432 1432
1433/* 1433/*
1434 * Unwinding superblock updates for old filesystems. 1434 * Unwinding superblock updates for old filesystems.
1435 * See ffs_oldfscompat_read above for details. 1435 * See ffs_oldfscompat_read above for details.
1436 * 1436 *
1437 * XXX - Parts get retired eventually. 1437 * XXX - Parts get retired eventually.
1438 * Unfortunately new bits get added. 1438 * Unfortunately new bits get added.
1439 */ 1439 */
1440static void 1440static void
1441ffs_oldfscompat_write(struct fs *fs, struct ufsmount *ump) 1441ffs_oldfscompat_write(struct fs *fs, struct ufsmount *ump)
1442{ 1442{
1443 int32_t *extrasave; 1443 int32_t *extrasave;
1444 1444
1445 if ((fs->fs_magic != FS_UFS1_MAGIC) || 1445 if ((fs->fs_magic != FS_UFS1_MAGIC) ||
1446 (fs->fs_old_flags & FS_FLAGS_UPDATED)) 1446 (fs->fs_old_flags & FS_FLAGS_UPDATED))
1447 return; 1447 return;
1448 1448
1449 fs->fs_old_time = fs->fs_time; 1449 fs->fs_old_time = fs->fs_time;
1450 fs->fs_old_cstotal.cs_ndir = fs->fs_cstotal.cs_ndir; 1450 fs->fs_old_cstotal.cs_ndir = fs->fs_cstotal.cs_ndir;
1451 fs->fs_old_cstotal.cs_nbfree = fs->fs_cstotal.cs_nbfree; 1451 fs->fs_old_cstotal.cs_nbfree = fs->fs_cstotal.cs_nbfree;
1452 fs->fs_old_cstotal.cs_nifree = fs->fs_cstotal.cs_nifree; 1452 fs->fs_old_cstotal.cs_nifree = fs->fs_cstotal.cs_nifree;
1453 fs->fs_old_cstotal.cs_nffree = fs->fs_cstotal.cs_nffree; 1453 fs->fs_old_cstotal.cs_nffree = fs->fs_cstotal.cs_nffree;
1454 fs->fs_old_flags = fs->fs_flags; 1454 fs->fs_old_flags = fs->fs_flags;
1455 1455
1456#if 0 1456#if 0
1457 if (bigcgs) { 1457 if (bigcgs) {
1458 fs->fs_cgsize = fs->fs_save_cgsize; 1458 fs->fs_cgsize = fs->fs_save_cgsize;
1459 } 1459 }
1460#endif 1460#endif
1461 1461
1462 memcpy(&fs->fs_old_postbl_start, ump->um_oldfscompat, 512); 1462 memcpy(&fs->fs_old_postbl_start, ump->um_oldfscompat, 512);
1463 extrasave = ump->um_oldfscompat; 1463 extrasave = ump->um_oldfscompat;
1464 extrasave += 512/sizeof(int32_t); 1464 extrasave += 512/sizeof(int32_t);
1465 fs->fs_old_npsect = extrasave[0]; 1465 fs->fs_old_npsect = extrasave[0];
1466 fs->fs_old_interleave = extrasave[1]; 1466 fs->fs_old_interleave = extrasave[1];
1467 fs->fs_old_trackskew = extrasave[2]; 1467 fs->fs_old_trackskew = extrasave[2];
1468 1468
1469} 1469}
1470 1470
1471/* 1471/*
1472 * unmount system call 1472 * unmount system call
1473 */ 1473 */
1474int 1474int
1475ffs_unmount(struct mount *mp, int mntflags) 1475ffs_unmount(struct mount *mp, int mntflags)
1476{ 1476{
1477 struct lwp *l = curlwp; 1477 struct lwp *l = curlwp;
1478 struct ufsmount *ump = VFSTOUFS(mp); 1478 struct ufsmount *ump = VFSTOUFS(mp);
1479 struct fs *fs = ump->um_fs; 1479 struct fs *fs = ump->um_fs;
1480 int error, flags, penderr; 1480 int error, flags, penderr;
1481#ifdef WAPBL 1481#ifdef WAPBL
1482 extern int doforce; 1482 extern int doforce;
1483#endif 1483#endif
1484 1484
1485 penderr = 0; 1485 penderr = 0;
1486 flags = 0; 1486 flags = 0;
1487 if (mntflags & MNT_FORCE) 1487 if (mntflags & MNT_FORCE)
1488 flags |= FORCECLOSE; 1488 flags |= FORCECLOSE;
1489#ifdef UFS_EXTATTR 1489#ifdef UFS_EXTATTR
1490 if (ump->um_fstype == UFS1) { 1490 if (ump->um_fstype == UFS1) {
1491 ufs_extattr_stop(mp, l); 1491 ufs_extattr_stop(mp, l);
1492 ufs_extattr_uepm_destroy(&ump->um_extattr); 1492 ufs_extattr_uepm_destroy(&ump->um_extattr);
1493 } 1493 }
1494#endif /* UFS_EXTATTR */ 1494#endif /* UFS_EXTATTR */
1495 if (mp->mnt_flag & MNT_SOFTDEP) { 1495 if (mp->mnt_flag & MNT_SOFTDEP) {
1496 if ((error = softdep_flushfiles(mp, flags, l)) != 0) 1496 if ((error = softdep_flushfiles(mp, flags, l)) != 0)
1497 return (error); 1497 return (error);
1498 } else { 1498 } else {
1499 if ((error = ffs_flushfiles(mp, flags, l)) != 0) 1499 if ((error = ffs_flushfiles(mp, flags, l)) != 0)
1500 return (error); 1500 return (error);
1501 } 1501 }
1502 mutex_enter(&ump->um_lock); 1502 mutex_enter(&ump->um_lock);
1503 if (fs->fs_pendingblocks != 0 || fs->fs_pendinginodes != 0) { 1503 if (fs->fs_pendingblocks != 0 || fs->fs_pendinginodes != 0) {
1504 printf("%s: unmount pending error: blocks %" PRId64 1504 printf("%s: unmount pending error: blocks %" PRId64
1505 " files %d\n", 1505 " files %d\n",
1506 fs->fs_fsmnt, fs->fs_pendingblocks, fs->fs_pendinginodes); 1506 fs->fs_fsmnt, fs->fs_pendingblocks, fs->fs_pendinginodes);
1507 fs->fs_pendingblocks = 0; 1507 fs->fs_pendingblocks = 0;
1508 fs->fs_pendinginodes = 0; 1508 fs->fs_pendinginodes = 0;
1509 penderr = 1; 1509 penderr = 1;
1510 } 1510 }
1511 mutex_exit(&ump->um_lock); 1511 mutex_exit(&ump->um_lock);
1512 error = UFS_WAPBL_BEGIN(mp); 1512 error = UFS_WAPBL_BEGIN(mp);
1513 if (error == 0) 1513 if (error == 0)
1514 if (fs->fs_ronly == 0 && 1514 if (fs->fs_ronly == 0 &&
1515 ffs_cgupdate(ump, MNT_WAIT) == 0 && 1515 ffs_cgupdate(ump, MNT_WAIT) == 0 &&
1516 fs->fs_clean & FS_WASCLEAN) { 1516 fs->fs_clean & FS_WASCLEAN) {
1517 /* 1517 /*
1518 * XXXX don't mark fs clean in the case of softdep 1518 * XXXX don't mark fs clean in the case of softdep
1519 * pending block errors, until they are fixed. 1519 * pending block errors, until they are fixed.
1520 */ 1520 */
1521 if (penderr == 0) { 1521 if (penderr == 0) {
1522 if (mp->mnt_flag & MNT_SOFTDEP) 1522 if (mp->mnt_flag & MNT_SOFTDEP)
1523 fs->fs_flags &= ~FS_DOSOFTDEP; 1523 fs->fs_flags &= ~FS_DOSOFTDEP;
1524 fs->fs_clean = FS_ISCLEAN; 1524 fs->fs_clean = FS_ISCLEAN;
1525 } 1525 }
1526 fs->fs_fmod = 0; 1526 fs->fs_fmod = 0;
1527 (void) ffs_sbupdate(ump, MNT_WAIT); 1527 (void) ffs_sbupdate(ump, MNT_WAIT);
1528 } 1528 }
1529 if (error == 0) 1529 if (error == 0)
1530 UFS_WAPBL_END(mp); 1530 UFS_WAPBL_END(mp);
1531#ifdef WAPBL 1531#ifdef WAPBL
1532 KASSERT(!(mp->mnt_wapbl_replay && mp->mnt_wapbl)); 1532 KASSERT(!(mp->mnt_wapbl_replay && mp->mnt_wapbl));
1533 if (mp->mnt_wapbl_replay) { 1533 if (mp->mnt_wapbl_replay) {
1534 KDASSERT(fs->fs_ronly); 1534 KDASSERT(fs->fs_ronly);
1535 wapbl_replay_stop(mp->mnt_wapbl_replay); 1535 wapbl_replay_stop(mp->mnt_wapbl_replay);
1536 wapbl_replay_free(mp->mnt_wapbl_replay); 1536 wapbl_replay_free(mp->mnt_wapbl_replay);
1537 mp->mnt_wapbl_replay = 0; 1537 mp->mnt_wapbl_replay = 0;
1538 } 1538 }
1539 error = ffs_wapbl_stop(mp, doforce && (mntflags & MNT_FORCE)); 1539 error = ffs_wapbl_stop(mp, doforce && (mntflags & MNT_FORCE));
1540 if (error) { 1540 if (error) {
1541 return error; 1541 return error;
1542 } 1542 }
1543#endif /* WAPBL */ 1543#endif /* WAPBL */
1544 if (ump->um_devvp->v_type != VBAD) 1544 if (ump->um_devvp->v_type != VBAD)
1545 ump->um_devvp->v_specmountpoint = NULL; 1545 ump->um_devvp->v_specmountpoint = NULL;
1546 vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY); 1546 vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY);
1547 (void)VOP_CLOSE(ump->um_devvp, fs->fs_ronly ? FREAD : FREAD | FWRITE, 1547 (void)VOP_CLOSE(ump->um_devvp, fs->fs_ronly ? FREAD : FREAD | FWRITE,
1548 NOCRED); 1548 NOCRED);
1549 vput(ump->um_devvp); 1549 vput(ump->um_devvp);
1550 free(fs->fs_csp, M_UFSMNT); 1550 free(fs->fs_csp, M_UFSMNT);
1551 free(fs, M_UFSMNT); 1551 free(fs, M_UFSMNT);
1552 if (ump->um_oldfscompat != NULL) 1552 if (ump->um_oldfscompat != NULL)
1553 free(ump->um_oldfscompat, M_UFSMNT); 1553 free(ump->um_oldfscompat, M_UFSMNT);
1554 softdep_unmount(mp); 1554 softdep_unmount(mp);
1555 mutex_destroy(&ump->um_lock); 1555 mutex_destroy(&ump->um_lock);
1556 ffs_snapshot_fini(ump); 1556 ffs_snapshot_fini(ump);
1557 free(ump, M_UFSMNT); 1557 free(ump, M_UFSMNT);
1558 mp->mnt_data = NULL; 1558 mp->mnt_data = NULL;
1559 mp->mnt_flag &= ~MNT_LOCAL; 1559 mp->mnt_flag &= ~MNT_LOCAL;
1560 fstrans_unmount(mp); 1560 fstrans_unmount(mp);
1561 return (0); 1561 return (0);
1562} 1562}
1563 1563
1564/* 1564/*
1565 * Flush out all the files in a filesystem. 1565 * Flush out all the files in a filesystem.
1566 */ 1566 */
1567int 1567int
1568ffs_flushfiles(struct mount *mp, int flags, struct lwp *l) 1568ffs_flushfiles(struct mount *mp, int flags, struct lwp *l)
1569{ 1569{
1570 extern int doforce; 1570 extern int doforce;
1571 struct ufsmount *ump; 1571 struct ufsmount *ump;
1572 int error; 1572 int error;
1573 1573
1574 if (!doforce) 1574 if (!doforce)
1575 flags &= ~FORCECLOSE; 1575 flags &= ~FORCECLOSE;
1576 ump = VFSTOUFS(mp); 1576 ump = VFSTOUFS(mp);
1577#ifdef QUOTA 1577#ifdef QUOTA
1578 if (mp->mnt_flag & MNT_QUOTA) { 1578 if (mp->mnt_flag & MNT_QUOTA) {
1579 int i; 1579 int i;
1580 if ((error = vflush(mp, NULLVP, SKIPSYSTEM | flags)) != 0) 1580 if ((error = vflush(mp, NULLVP, SKIPSYSTEM | flags)) != 0)
1581 return (error); 1581 return (error);
1582 for (i = 0; i < MAXQUOTAS; i++) { 1582 for (i = 0; i < MAXQUOTAS; i++) {
1583 if (ump->um_quotas[i] == NULLVP) 1583 if (ump->um_quotas[i] == NULLVP)
1584 continue; 1584 continue;
1585 quotaoff(l, mp, i); 1585 quotaoff(l, mp, i);
1586 } 1586 }
1587 /* 1587 /*
1588 * Here we fall through to vflush again to ensure 1588 * Here we fall through to vflush again to ensure
1589 * that we have gotten rid of all the system vnodes. 1589 * that we have gotten rid of all the system vnodes.
1590 */ 1590 */
1591 } 1591 }
1592#endif 1592#endif
1593 if ((error = vflush(mp, 0, SKIPSYSTEM | flags)) != 0) 1593 if ((error = vflush(mp, 0, SKIPSYSTEM | flags)) != 0)
1594 return (error); 1594 return (error);
1595 ffs_snapshot_unmount(mp); 1595 ffs_snapshot_unmount(mp);
1596 /* 1596 /*
1597 * Flush all the files. 1597 * Flush all the files.
1598 */ 1598 */
1599 error = vflush(mp, NULLVP, flags); 1599 error = vflush(mp, NULLVP, flags);
1600 if (error) 1600 if (error)
1601 return (error); 1601 return (error);
1602 /* 1602 /*
1603 * Flush filesystem metadata. 1603 * Flush filesystem metadata.
1604 */ 1604 */
1605 vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY); 1605 vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY);
1606 error = VOP_FSYNC(ump->um_devvp, l->l_cred, FSYNC_WAIT, 0, 0); 1606 error = VOP_FSYNC(ump->um_devvp, l->l_cred, FSYNC_WAIT, 0, 0);
1607 VOP_UNLOCK(ump->um_devvp, 0); 1607 VOP_UNLOCK(ump->um_devvp, 0);
1608 if (flags & FORCECLOSE) /* XXXDBJ */ 1608 if (flags & FORCECLOSE) /* XXXDBJ */
1609 error = 0; 1609 error = 0;
1610 1610
1611#ifdef WAPBL 1611#ifdef WAPBL
1612 if (error) 1612 if (error)
1613 return error; 1613 return error;
1614 if (mp->mnt_wapbl) { 1614 if (mp->mnt_wapbl) {
1615 error = wapbl_flush(mp->mnt_wapbl, 1); 1615 error = wapbl_flush(mp->mnt_wapbl, 1);
1616 if (flags & FORCECLOSE) 1616 if (flags & FORCECLOSE)
1617 error = 0; 1617 error = 0;
1618 } 1618 }
1619#endif 1619#endif
1620 1620
1621 return (error); 1621 return (error);
1622} 1622}
1623 1623
1624/* 1624/*
1625 * Get file system statistics. 1625 * Get file system statistics.
1626 */ 1626 */
1627int 1627int
1628ffs_statvfs(struct mount *mp, struct statvfs *sbp) 1628ffs_statvfs(struct mount *mp, struct statvfs *sbp)
1629{ 1629{
1630 struct ufsmount *ump; 1630 struct ufsmount *ump;
1631 struct fs *fs; 1631 struct fs *fs;
1632 1632
1633 ump = VFSTOUFS(mp); 1633 ump = VFSTOUFS(mp);
1634 fs = ump->um_fs; 1634 fs = ump->um_fs;
1635 mutex_enter(&ump->um_lock); 1635 mutex_enter(&ump->um_lock);
1636 sbp->f_bsize = fs->fs_bsize; 1636 sbp->f_bsize = fs->fs_bsize;
1637 sbp->f_frsize = fs->fs_fsize; 1637 sbp->f_frsize = fs->fs_fsize;
1638 sbp->f_iosize = fs->fs_bsize; 1638 sbp->f_iosize = fs->fs_bsize;
1639 sbp->f_blocks = fs->fs_dsize; 1639 sbp->f_blocks = fs->fs_dsize;
1640 sbp->f_bfree = blkstofrags(fs, fs->fs_cstotal.cs_nbfree) + 1640 sbp->f_bfree = blkstofrags(fs, fs->fs_cstotal.cs_nbfree) +
1641 fs->fs_cstotal.cs_nffree + dbtofsb(fs, fs->fs_pendingblocks); 1641 fs->fs_cstotal.cs_nffree + dbtofsb(fs, fs->fs_pendingblocks);
1642 sbp->f_bresvd = ((u_int64_t) fs->fs_dsize * (u_int64_t) 1642 sbp->f_bresvd = ((u_int64_t) fs->fs_dsize * (u_int64_t)
1643 fs->fs_minfree) / (u_int64_t) 100; 1643 fs->fs_minfree) / (u_int64_t) 100;
1644 if (sbp->f_bfree > sbp->f_bresvd) 1644 if (sbp->f_bfree > sbp->f_bresvd)
1645 sbp->f_bavail = sbp->f_bfree - sbp->f_bresvd; 1645 sbp->f_bavail = sbp->f_bfree - sbp->f_bresvd;
1646 else 1646 else
1647 sbp->f_bavail = 0; 1647 sbp->f_bavail = 0;
1648 sbp->f_files = fs->fs_ncg * fs->fs_ipg - ROOTINO; 1648 sbp->f_files = fs->fs_ncg * fs->fs_ipg - ROOTINO;
1649 sbp->f_ffree = fs->fs_cstotal.cs_nifree + fs->fs_pendinginodes; 1649 sbp->f_ffree = fs->fs_cstotal.cs_nifree + fs->fs_pendinginodes;
1650 sbp->f_favail = sbp->f_ffree; 1650 sbp->f_favail = sbp->f_ffree;
1651 sbp->f_fresvd = 0; 1651 sbp->f_fresvd = 0;
1652 mutex_exit(&ump->um_lock); 1652 mutex_exit(&ump->um_lock);
1653 copy_statvfs_info(sbp, mp); 1653 copy_statvfs_info(sbp, mp);
1654 1654
1655 return (0); 1655 return (0);
1656} 1656}
1657 1657
1658/* 1658/*
1659 * Go through the disk queues to initiate sandbagged IO; 1659 * Go through the disk queues to initiate sandbagged IO;
1660 * go through the inodes to write those that have been modified; 1660 * go through the inodes to write those that have been modified;
1661 * initiate the writing of the super block if it has been modified. 1661 * initiate the writing of the super block if it has been modified.
1662 * 1662 *
1663 * Note: we are always called with the filesystem marked `MPBUSY'. 1663 * Note: we are always called with the filesystem marked `MPBUSY'.
1664 */ 1664 */
1665int 1665int
1666ffs_sync(struct mount *mp, int waitfor, kauth_cred_t cred) 1666ffs_sync(struct mount *mp, int waitfor, kauth_cred_t cred)
1667{ 1667{
1668 struct lwp *l = curlwp; 1668 struct lwp *l = curlwp;
1669 struct vnode *vp, *mvp; 1669 struct vnode *vp, *mvp;
1670 struct inode *ip; 1670 struct inode *ip;
1671 struct ufsmount *ump = VFSTOUFS(mp); 1671 struct ufsmount *ump = VFSTOUFS(mp);
1672 struct fs *fs; 1672 struct fs *fs;
1673 int error, count, allerror = 0; 1673 int error, count, allerror = 0;
1674 1674
1675 fs = ump->um_fs; 1675 fs = ump->um_fs;
1676 if (fs->fs_fmod != 0 && fs->fs_ronly != 0) { /* XXX */ 1676 if (fs->fs_fmod != 0 && fs->fs_ronly != 0) { /* XXX */
1677 printf("fs = %s\n", fs->fs_fsmnt); 1677 printf("fs = %s\n", fs->fs_fsmnt);
1678 panic("update: rofs mod"); 1678 panic("update: rofs mod");
1679 } 1679 }
1680 1680
1681 /* Allocate a marker vnode. */ 1681 /* Allocate a marker vnode. */
1682 if ((mvp = vnalloc(mp)) == NULL) 1682 if ((mvp = vnalloc(mp)) == NULL)
1683 return (ENOMEM); 1683 return (ENOMEM);
1684 1684
1685 fstrans_start(mp, FSTRANS_SHARED); 1685 fstrans_start(mp, FSTRANS_SHARED);
1686 /* 1686 /*
1687 * Write back each (modified) inode. 1687 * Write back each (modified) inode.
1688 */ 1688 */
1689 mutex_enter(&mntvnode_lock); 1689 mutex_enter(&mntvnode_lock);
1690loop: 1690loop:
1691 /* 1691 /*
1692 * NOTE: not using the TAILQ_FOREACH here since in this loop vgone() 1692 * NOTE: not using the TAILQ_FOREACH here since in this loop vgone()
1693 * and vclean() can be called indirectly 1693 * and vclean() can be called indirectly
1694 */ 1694 */
1695 for (vp = TAILQ_FIRST(&mp->mnt_vnodelist); vp; vp = vunmark(mvp)) { 1695 for (vp = TAILQ_FIRST(&mp->mnt_vnodelist); vp; vp = vunmark(mvp)) {
1696 vmark(mvp, vp); 1696 vmark(mvp, vp);
1697 /* 1697 /*
1698 * If the vnode that we are about to sync is no longer 1698 * If the vnode that we are about to sync is no longer
1699 * associated with this mount point, start over. 1699 * associated with this mount point, start over.
1700 */ 1700 */
1701 if (vp->v_mount != mp || vismarker(vp)) 1701 if (vp->v_mount != mp || vismarker(vp))
1702 continue; 1702 continue;
1703 mutex_enter(&vp->v_interlock); 1703 mutex_enter(&vp->v_interlock);
1704 ip = VTOI(vp); 1704 ip = VTOI(vp);
1705 /* XXXpooka: why wapbl check? */ 1705 /* XXXpooka: why wapbl check? */
1706 if (ip == NULL || (vp->v_iflag & (VI_XLOCK | VI_CLEAN)) != 0 || 1706 if (ip == NULL || (vp->v_iflag & (VI_XLOCK | VI_CLEAN)) != 0 ||
1707 vp->v_type == VNON || ((ip->i_flag & 1707 vp->v_type == VNON || ((ip->i_flag &
1708 (IN_CHANGE | IN_UPDATE | IN_MODIFIED)) == 0 && 1708 (IN_CHANGE | IN_UPDATE | IN_MODIFIED)) == 0 &&
1709 (LIST_EMPTY(&vp->v_dirtyblkhd) || (mp->mnt_wapbl)) && 1709 (LIST_EMPTY(&vp->v_dirtyblkhd) || (mp->mnt_wapbl)) &&
1710 UVM_OBJ_IS_CLEAN(&vp->v_uobj))) 1710 UVM_OBJ_IS_CLEAN(&vp->v_uobj)))
1711 { 1711 {
1712 mutex_exit(&vp->v_interlock); 1712 mutex_exit(&vp->v_interlock);
1713 continue; 1713 continue;
1714 } 1714 }
1715 if (vp->v_type == VBLK && 1715 if (vp->v_type == VBLK &&
1716 fstrans_getstate(mp) == FSTRANS_SUSPENDING) { 1716 fstrans_getstate(mp) == FSTRANS_SUSPENDING) {
1717 mutex_exit(&vp->v_interlock); 1717 mutex_exit(&vp->v_interlock);
1718 continue; 1718 continue;
1719 } 1719 }
1720 mutex_exit(&mntvnode_lock); 1720 mutex_exit(&mntvnode_lock);
1721 error = vget(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK); 1721 error = vget(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK);
1722 if (error) { 1722 if (error) {
1723 mutex_enter(&mntvnode_lock); 1723 mutex_enter(&mntvnode_lock);
1724 if (error == ENOENT) { 1724 if (error == ENOENT) {
1725 (void)vunmark(mvp); 1725 (void)vunmark(mvp);
1726 goto loop; 1726 goto loop;
1727 } 1727 }
1728 continue; 1728 continue;
1729 } 1729 }
1730 if (vp->v_type == VREG && waitfor == MNT_LAZY) { 1730 if (vp->v_type == VREG && waitfor == MNT_LAZY) {
1731 error = UFS_WAPBL_BEGIN(vp->v_mount); 1731 error = UFS_WAPBL_BEGIN(vp->v_mount);
1732 if (!error) { 1732 if (!error) {
1733 error = ffs_update(vp, NULL, NULL, 0); 1733 error = ffs_update(vp, NULL, NULL, 0);
1734 UFS_WAPBL_END(vp->v_mount); 1734 UFS_WAPBL_END(vp->v_mount);
1735 } 1735 }
1736 } else { 1736 } else {
1737 error = VOP_FSYNC(vp, cred, FSYNC_NOLOG | 1737 error = VOP_FSYNC(vp, cred, FSYNC_NOLOG |
1738 (waitfor == MNT_WAIT ? FSYNC_WAIT : 0), 0, 0); 1738 (waitfor == MNT_WAIT ? FSYNC_WAIT : 0), 0, 0);
1739 } 1739 }
1740 if (error) 1740 if (error)
1741 allerror = error; 1741 allerror = error;
1742 vput(vp); 1742 vput(vp);
1743 mutex_enter(&mntvnode_lock); 1743 mutex_enter(&mntvnode_lock);
1744 } 1744 }
1745 mutex_exit(&mntvnode_lock); 1745 mutex_exit(&mntvnode_lock);
1746 /* 1746 /*
1747 * Force stale file system control information to be flushed. 1747 * Force stale file system control information to be flushed.
1748 */ 1748 */
1749 if (waitfor == MNT_WAIT && (ump->um_mountp->mnt_flag & MNT_SOFTDEP)) { 1749 if (waitfor == MNT_WAIT && (ump->um_mountp->mnt_flag & MNT_SOFTDEP)) {
1750 if ((error = softdep_flushworklist(ump->um_mountp, &count, l))) 1750 if ((error = softdep_flushworklist(ump->um_mountp, &count, l)))
1751 allerror = error; 1751 allerror = error;
1752 /* Flushed work items may create new vnodes to clean */ 1752 /* Flushed work items may create new vnodes to clean */
1753 if (allerror == 0 && count) { 1753 if (allerror == 0 && count) {
1754 mutex_enter(&mntvnode_lock); 1754 mutex_enter(&mntvnode_lock);
1755 goto loop; 1755 goto loop;
1756 } 1756 }
1757 } 1757 }
1758 if (waitfor != MNT_LAZY && (ump->um_devvp->v_numoutput > 0 || 1758 if (waitfor != MNT_LAZY && (ump->um_devvp->v_numoutput > 0 ||
1759 !LIST_EMPTY(&ump->um_devvp->v_dirtyblkhd))) { 1759 !LIST_EMPTY(&ump->um_devvp->v_dirtyblkhd))) {
1760 vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY); 1760 vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY);
1761 if ((error = VOP_FSYNC(ump->um_devvp, cred, 1761 if ((error = VOP_FSYNC(ump->um_devvp, cred,
1762 (waitfor == MNT_WAIT ? FSYNC_WAIT : 0) | FSYNC_NOLOG, 1762 (waitfor == MNT_WAIT ? FSYNC_WAIT : 0) | FSYNC_NOLOG,
1763 0, 0)) != 0) 1763 0, 0)) != 0)
1764 allerror = error; 1764 allerror = error;
1765 VOP_UNLOCK(ump->um_devvp, 0); 1765 VOP_UNLOCK(ump->um_devvp, 0);
1766 if (allerror == 0 && waitfor == MNT_WAIT && !mp->mnt_wapbl) { 1766 if (allerror == 0 && waitfor == MNT_WAIT && !mp->mnt_wapbl) {
1767 mutex_enter(&mntvnode_lock); 1767 mutex_enter(&mntvnode_lock);
1768 goto loop; 1768 goto loop;
1769 } 1769 }
1770 } 1770 }
1771#ifdef QUOTA 1771#ifdef QUOTA
1772 qsync(mp); 1772 qsync(mp);
1773#endif 1773#endif
1774 /* 1774 /*
1775 * Write back modified superblock. 1775 * Write back modified superblock.
1776 */ 1776 */
1777 if (fs->fs_fmod != 0) { 1777 if (fs->fs_fmod != 0) {
1778 fs->fs_fmod = 0; 1778 fs->fs_fmod = 0;
1779 fs->fs_time = time_second; 1779 fs->fs_time = time_second;
1780 error = UFS_WAPBL_BEGIN(mp); 1780 error = UFS_WAPBL_BEGIN(mp);
1781 if (error) 1781 if (error)
1782 allerror = error; 1782 allerror = error;
1783 else { 1783 else {
1784 if ((error = ffs_cgupdate(ump, waitfor))) 1784 if ((error = ffs_cgupdate(ump, waitfor)))
1785 allerror = error; 1785 allerror = error;
1786 UFS_WAPBL_END(mp); 1786 UFS_WAPBL_END(mp);
1787 } 1787 }
1788 } 1788 }
1789 1789
1790#ifdef WAPBL 1790#ifdef WAPBL
1791 if (mp->mnt_wapbl) { 1791 if (mp->mnt_wapbl) {
1792 error = wapbl_flush(mp->mnt_wapbl, 0); 1792 error = wapbl_flush(mp->mnt_wapbl, 0);
1793 if (error) 1793 if (error)
1794 allerror = error; 1794 allerror = error;
1795 } 1795 }
1796#endif 1796#endif
1797 1797
1798 fstrans_done(mp); 1798 fstrans_done(mp);
1799 vnfree(mvp); 1799 vnfree(mvp);
1800 return (allerror); 1800 return (allerror);
1801} 1801}
1802 1802
1803/* 1803/*
1804 * Look up a FFS dinode number to find its incore vnode, otherwise read it 1804 * Look up a FFS dinode number to find its incore vnode, otherwise read it
1805 * in from disk. If it is in core, wait for the lock bit to clear, then 1805 * in from disk. If it is in core, wait for the lock bit to clear, then
1806 * return the inode locked. Detection and handling of mount points must be 1806 * return the inode locked. Detection and handling of mount points must be
1807 * done by the calling routine. 1807 * done by the calling routine.
1808 */ 1808 */
1809int 1809int
1810ffs_vget(struct mount *mp, ino_t ino, struct vnode **vpp) 1810ffs_vget(struct mount *mp, ino_t ino, struct vnode **vpp)
1811{ 1811{
1812 struct fs *fs; 1812 struct fs *fs;
1813 struct inode *ip; 1813 struct inode *ip;
1814 struct ufsmount *ump; 1814 struct ufsmount *ump;
1815 struct buf *bp; 1815 struct buf *bp;
1816 struct vnode *vp; 1816 struct vnode *vp;
1817 dev_t dev; 1817 dev_t dev;
1818 int error; 1818 int error;
1819 1819
1820 ump = VFSTOUFS(mp); 1820 ump = VFSTOUFS(mp);
1821 dev = ump->um_dev; 1821 dev = ump->um_dev;
1822 1822
1823 retry: 1823 retry:
1824 if ((*vpp = ufs_ihashget(dev, ino, LK_EXCLUSIVE)) != NULL) 1824 if ((*vpp = ufs_ihashget(dev, ino, LK_EXCLUSIVE)) != NULL)
1825 return (0); 1825 return (0);
1826 1826
1827 /* Allocate a new vnode/inode. */ 1827 /* Allocate a new vnode/inode. */
1828 if ((error = getnewvnode(VT_UFS, mp, ffs_vnodeop_p, &vp)) != 0) { 1828 if ((error = getnewvnode(VT_UFS, mp, ffs_vnodeop_p, &vp)) != 0) {
1829 *vpp = NULL; 1829 *vpp = NULL;
1830 return (error); 1830 return (error);
1831 } 1831 }
1832 ip = pool_cache_get(ffs_inode_cache, PR_WAITOK); 1832 ip = pool_cache_get(ffs_inode_cache, PR_WAITOK);
1833 1833
1834 /* 1834 /*
1835 * If someone beat us to it, put back the freshly allocated 1835 * If someone beat us to it, put back the freshly allocated
1836 * vnode/inode pair and retry. 1836 * vnode/inode pair and retry.
1837 */ 1837 */
1838 mutex_enter(&ufs_hashlock); 1838 mutex_enter(&ufs_hashlock);
1839 if (ufs_ihashget(dev, ino, 0) != NULL) { 1839 if (ufs_ihashget(dev, ino, 0) != NULL) {
1840 mutex_exit(&ufs_hashlock); 1840 mutex_exit(&ufs_hashlock);
1841 ungetnewvnode(vp); 1841 ungetnewvnode(vp);
1842 pool_cache_put(ffs_inode_cache, ip); 1842 pool_cache_put(ffs_inode_cache, ip);
1843 goto retry; 1843 goto retry;
1844 } 1844 }
1845 1845
1846 vp->v_vflag |= VV_LOCKSWORK; 1846 vp->v_vflag |= VV_LOCKSWORK;
1847 if ((mp->mnt_flag & MNT_SOFTDEP) != 0) 1847 if ((mp->mnt_flag & MNT_SOFTDEP) != 0)
1848 vp->v_uflag |= VU_SOFTDEP; 1848 vp->v_uflag |= VU_SOFTDEP;
1849 1849
1850 /* 1850 /*
1851 * XXX MFS ends up here, too, to allocate an inode. Should we 1851 * XXX MFS ends up here, too, to allocate an inode. Should we
1852 * XXX create another pool for MFS inodes? 1852 * XXX create another pool for MFS inodes?
1853 */ 1853 */
1854 1854
1855 memset(ip, 0, sizeof(struct inode)); 1855 memset(ip, 0, sizeof(struct inode));
1856 vp->v_data = ip; 1856 vp->v_data = ip;
1857 ip->i_vnode = vp; 1857 ip->i_vnode = vp;
1858 ip->i_ump = ump; 1858 ip->i_ump = ump;
1859 ip->i_fs = fs = ump->um_fs; 1859 ip->i_fs = fs = ump->um_fs;
1860 ip->i_dev = dev; 1860 ip->i_dev = dev;
1861 ip->i_number = ino; 1861 ip->i_number = ino;
1862 LIST_INIT(&ip->i_pcbufhd); 1862 LIST_INIT(&ip->i_pcbufhd);
1863#ifdef QUOTA 1863#ifdef QUOTA
1864 ufsquota_init(ip); 1864 ufsquota_init(ip);
1865#endif 1865#endif
1866 1866
1867 /* 1867 /*
1868 * Initialize genfs node, we might proceed to destroy it in 1868 * Initialize genfs node, we might proceed to destroy it in
1869 * error branches. 1869 * error branches.
1870 */ 1870 */
1871 genfs_node_init(vp, &ffs_genfsops); 1871 genfs_node_init(vp, &ffs_genfsops);
1872 1872
1873 /* 1873 /*
1874 * Put it onto its hash chain and lock it so that other requests for 1874 * Put it onto its hash chain and lock it so that other requests for
1875 * this inode will block if they arrive while we are sleeping waiting 1875 * this inode will block if they arrive while we are sleeping waiting
1876 * for old data structures to be purged or for the contents of the 1876 * for old data structures to be purged or for the contents of the
1877 * disk portion of this inode to be read. 1877 * disk portion of this inode to be read.
1878 */ 1878 */
1879 1879
1880 ufs_ihashins(ip); 1880 ufs_ihashins(ip);
1881 mutex_exit(&ufs_hashlock); 1881 mutex_exit(&ufs_hashlock);
1882 1882
1883 /* Read in the disk contents for the inode, copy into the inode. */ 1883 /* Read in the disk contents for the inode, copy into the inode. */
1884 error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)), 1884 error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)),
1885 (int)fs->fs_bsize, NOCRED, 0, &bp); 1885 (int)fs->fs_bsize, NOCRED, 0, &bp);
1886 if (error) { 1886 if (error) {
1887 1887
1888 /* 1888 /*
1889 * The inode does not contain anything useful, so it would 1889 * The inode does not contain anything useful, so it would
1890 * be misleading to leave it on its hash chain. With mode 1890 * be misleading to leave it on its hash chain. With mode
1891 * still zero, it will be unlinked and returned to the free 1891 * still zero, it will be unlinked and returned to the free
1892 * list by vput(). 1892 * list by vput().
1893 */ 1893 */
1894 1894
1895 vput(vp); 1895 vput(vp);
1896 brelse(bp, 0); 1896 brelse(bp, 0);
1897 *vpp = NULL; 1897 *vpp = NULL;
1898 return (error); 1898 return (error);
1899 } 1899 }
1900 if (ip->i_ump->um_fstype == UFS1) 1900 if (ip->i_ump->um_fstype == UFS1)
1901 ip->i_din.ffs1_din = pool_cache_get(ffs_dinode1_cache, 1901 ip->i_din.ffs1_din = pool_cache_get(ffs_dinode1_cache,
1902 PR_WAITOK); 1902 PR_WAITOK);
1903 else 1903 else
1904 ip->i_din.ffs2_din = pool_cache_get(ffs_dinode2_cache, 1904 ip->i_din.ffs2_din = pool_cache_get(ffs_dinode2_cache,
1905 PR_WAITOK); 1905 PR_WAITOK);
1906 ffs_load_inode(bp, ip, fs, ino); 1906 ffs_load_inode(bp, ip, fs, ino);
1907 if (DOINGSOFTDEP(vp)) 1907 if (DOINGSOFTDEP(vp))
1908 softdep_load_inodeblock(ip); 1908 softdep_load_inodeblock(ip);
1909 else 1909 else
1910 ip->i_ffs_effnlink = ip->i_nlink; 1910 ip->i_ffs_effnlink = ip->i_nlink;
1911 brelse(bp, 0); 1911 brelse(bp, 0);
1912 1912
1913 /* 1913 /*
1914 * Initialize the vnode from the inode, check for aliases. 1914 * Initialize the vnode from the inode, check for aliases.
1915 * Note that the underlying vnode may have changed. 1915 * Note that the underlying vnode may have changed.
1916 */ 1916 */
1917 1917
1918 ufs_vinit(mp, ffs_specop_p, ffs_fifoop_p, &vp); 1918 ufs_vinit(mp, ffs_specop_p, ffs_fifoop_p, &vp);
1919 1919
1920 /* 1920 /*
1921 * Finish inode initialization now that aliasing has been resolved. 1921 * Finish inode initialization now that aliasing has been resolved.
1922 */ 1922 */
1923 1923
1924 ip->i_devvp = ump->um_devvp; 1924 ip->i_devvp = ump->um_devvp;
1925 VREF(ip->i_devvp); 1925 VREF(ip->i_devvp);
1926 1926
1927 /* 1927 /*
1928 * Ensure that uid and gid are correct. This is a temporary 1928 * Ensure that uid and gid are correct. This is a temporary
1929 * fix until fsck has been changed to do the update. 1929 * fix until fsck has been changed to do the update.
1930 */ 1930 */
1931 1931
1932 if (fs->fs_old_inodefmt < FS_44INODEFMT) { /* XXX */ 1932 if (fs->fs_old_inodefmt < FS_44INODEFMT) { /* XXX */
1933 ip->i_uid = ip->i_ffs1_ouid; /* XXX */ 1933 ip->i_uid = ip->i_ffs1_ouid; /* XXX */
1934 ip->i_gid = ip->i_ffs1_ogid; /* XXX */ 1934 ip->i_gid = ip->i_ffs1_ogid; /* XXX */
1935 } /* XXX */ 1935 } /* XXX */
1936 uvm_vnp_setsize(vp, ip->i_size); 1936 uvm_vnp_setsize(vp, ip->i_size);
1937 *vpp = vp; 1937 *vpp = vp;
1938 return (0); 1938 return (0);
1939} 1939}
1940 1940
1941/* 1941/*
1942 * File handle to vnode 1942 * File handle to vnode
1943 * 1943 *
1944 * Have to be really careful about stale file handles: 1944 * Have to be really careful about stale file handles:
1945 * - check that the inode number is valid 1945 * - check that the inode number is valid
1946 * - call ffs_vget() to get the locked inode 1946 * - call ffs_vget() to get the locked inode
1947 * - check for an unallocated inode (i_mode == 0) 1947 * - check for an unallocated inode (i_mode == 0)
1948 * - check that the given client host has export rights and return 1948 * - check that the given client host has export rights and return
1949 * those rights via. exflagsp and credanonp 1949 * those rights via. exflagsp and credanonp
1950 */ 1950 */
1951int 1951int
1952ffs_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp) 1952ffs_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp)
1953{ 1953{
1954 struct ufid ufh; 1954 struct ufid ufh;
1955 struct fs *fs; 1955 struct fs *fs;
1956 1956
1957 if (fhp->fid_len != sizeof(struct ufid)) 1957 if (fhp->fid_len != sizeof(struct ufid))
1958 return EINVAL; 1958 return EINVAL;
1959 1959
1960 memcpy(&ufh, fhp, sizeof(ufh)); 1960 memcpy(&ufh, fhp, sizeof(ufh));
1961 fs = VFSTOUFS(mp)->um_fs; 1961 fs = VFSTOUFS(mp)->um_fs;
1962 if (ufh.ufid_ino < ROOTINO || 1962 if (ufh.ufid_ino < ROOTINO ||
1963 ufh.ufid_ino >= fs->fs_ncg * fs->fs_ipg) 1963 ufh.ufid_ino >= fs->fs_ncg * fs->fs_ipg)
1964 return (ESTALE); 1964 return (ESTALE);
1965 return (ufs_fhtovp(mp, &ufh, vpp)); 1965 return (ufs_fhtovp(mp, &ufh, vpp));
1966} 1966}
1967 1967
1968/* 1968/*
1969 * Vnode pointer to File handle 1969 * Vnode pointer to File handle
1970 */ 1970 */
1971/* ARGSUSED */ 1971/* ARGSUSED */
1972int 1972int
1973ffs_vptofh(struct vnode *vp, struct fid *fhp, size_t *fh_size) 1973ffs_vptofh(struct vnode *vp, struct fid *fhp, size_t *fh_size)
1974{ 1974{
1975 struct inode *ip; 1975 struct inode *ip;
1976 struct ufid ufh; 1976 struct ufid ufh;
1977 1977
1978 if (*fh_size < sizeof(struct ufid)) { 1978 if (*fh_size < sizeof(struct ufid)) {
1979 *fh_size = sizeof(struct ufid); 1979 *fh_size = sizeof(struct ufid);
1980 return E2BIG; 1980 return E2BIG;
1981 } 1981 }
1982 ip = VTOI(vp); 1982 ip = VTOI(vp);
1983 *fh_size = sizeof(struct ufid); 1983 *fh_size = sizeof(struct ufid);
1984 memset(&ufh, 0, sizeof(ufh)); 1984 memset(&ufh, 0, sizeof(ufh));
1985 ufh.ufid_len = sizeof(struct ufid); 1985 ufh.ufid_len = sizeof(struct ufid);
1986 ufh.ufid_ino = ip->i_number; 1986 ufh.ufid_ino = ip->i_number;
1987 ufh.ufid_gen = ip->i_gen; 1987 ufh.ufid_gen = ip->i_gen;
1988 memcpy(fhp, &ufh, sizeof(ufh)); 1988 memcpy(fhp, &ufh, sizeof(ufh));
1989 return (0); 1989 return (0);
1990} 1990}
1991 1991
1992void 1992void
1993ffs_init(void) 1993ffs_init(void)
1994{ 1994{
1995 if (ffs_initcount++ > 0) 1995 if (ffs_initcount++ > 0)
1996 return; 1996 return;
1997 1997
1998 ffs_inode_cache = pool_cache_init(sizeof(struct inode), 0, 0, 0, 1998 ffs_inode_cache = pool_cache_init(sizeof(struct inode), 0, 0, 0,
1999 "ffsino", NULL, IPL_NONE, NULL, NULL, NULL); 1999 "ffsino", NULL, IPL_NONE, NULL, NULL, NULL);
2000 ffs_dinode1_cache = pool_cache_init(sizeof(struct ufs1_dinode), 0, 0, 0, 2000 ffs_dinode1_cache = pool_cache_init(sizeof(struct ufs1_dinode), 0, 0, 0,
2001 "ffsdino1", NULL, IPL_NONE, NULL, NULL, NULL); 2001 "ffsdino1", NULL, IPL_NONE, NULL, NULL, NULL);
2002 ffs_dinode2_cache = pool_cache_init(sizeof(struct ufs2_dinode), 0, 0, 0, 2002 ffs_dinode2_cache = pool_cache_init(sizeof(struct ufs2_dinode), 0, 0, 0,
2003 "ffsdino2", NULL, IPL_NONE, NULL, NULL, NULL); 2003 "ffsdino2", NULL, IPL_NONE, NULL, NULL, NULL);
2004 softdep_initialize(); 2004 softdep_initialize();
2005 ufs_init(); 2005 ufs_init();
2006} 2006}
2007 2007
2008void 2008void
2009ffs_reinit(void) 2009ffs_reinit(void)
2010{ 2010{
2011 softdep_reinitialize(); 2011 softdep_reinitialize();
2012 ufs_reinit(); 2012 ufs_reinit();
2013} 2013}
2014 2014
2015void 2015void
2016ffs_done(void) 2016ffs_done(void)
2017{ 2017{
2018 if (--ffs_initcount > 0) 2018 if (--ffs_initcount > 0)
2019 return; 2019 return;
2020 2020
2021 /* XXX softdep cleanup ? */ 2021 /* XXX softdep cleanup ? */
2022 ufs_done(); 2022 ufs_done();
2023 pool_cache_destroy(ffs_dinode2_cache); 2023 pool_cache_destroy(ffs_dinode2_cache);
2024 pool_cache_destroy(ffs_dinode1_cache); 2024 pool_cache_destroy(ffs_dinode1_cache);
2025 pool_cache_destroy(ffs_inode_cache); 2025 pool_cache_destroy(ffs_inode_cache);
2026} 2026}
2027 2027
2028/* 2028/*
2029 * Write a superblock and associated information back to disk. 2029 * Write a superblock and associated information back to disk.
2030 */ 2030 */
2031int 2031int
2032ffs_sbupdate(struct ufsmount *mp, int waitfor) 2032ffs_sbupdate(struct ufsmount *mp, int waitfor)
2033{ 2033{
2034 struct fs *fs = mp->um_fs; 2034 struct fs *fs = mp->um_fs;
2035 struct buf *bp; 2035 struct buf *bp;
2036 int error = 0; 2036 int error = 0;
2037 u_int32_t saveflag; 2037 u_int32_t saveflag;
2038 2038
2039 error = ffs_getblk(mp->um_devvp, 2039 error = ffs_getblk(mp->um_devvp,
2040 fs->fs_sblockloc >> (fs->fs_fshift - fs->fs_fsbtodb), FFS_NOBLK, 2040 fs->fs_sblockloc >> (fs->fs_fshift - fs->fs_fsbtodb), FFS_NOBLK,
2041 fs->fs_sbsize, false, &bp); 2041 fs->fs_sbsize, false, &bp);
2042 if (error) 2042 if (error)
2043 return error; 2043 return error;
2044 saveflag = fs->fs_flags & FS_INTERNAL; 2044 saveflag = fs->fs_flags & FS_INTERNAL;
2045 fs->fs_flags &= ~FS_INTERNAL; 2045 fs->fs_flags &= ~FS_INTERNAL;
2046 2046
2047 memcpy(bp->b_data, fs, fs->fs_sbsize); 2047 memcpy(bp->b_data, fs, fs->fs_sbsize);
2048 2048
2049 ffs_oldfscompat_write((struct fs *)bp->b_data, mp); 2049 ffs_oldfscompat_write((struct fs *)bp->b_data, mp);
2050#ifdef FFS_EI 2050#ifdef FFS_EI
2051 if (mp->um_flags & UFS_NEEDSWAP) 2051 if (mp->um_flags & UFS_NEEDSWAP)
2052 ffs_sb_swap((struct fs *)bp->b_data, (struct fs *)bp->b_data); 2052 ffs_sb_swap((struct fs *)bp->b_data, (struct fs *)bp->b_data);
2053#endif 2053#endif
2054 fs->fs_flags |= saveflag; 2054 fs->fs_flags |= saveflag;
2055 2055
2056 if (waitfor == MNT_WAIT) 2056 if (waitfor == MNT_WAIT)
2057 error = bwrite(bp); 2057 error = bwrite(bp);
2058 else 2058 else
2059 bawrite(bp); 2059 bawrite(bp);
2060 return (error); 2060 return (error);
2061} 2061}
2062 2062
2063int 2063int
2064ffs_cgupdate(struct ufsmount *mp, int waitfor) 2064ffs_cgupdate(struct ufsmount *mp, int waitfor)
2065{ 2065{
2066 struct fs *fs = mp->um_fs; 2066 struct fs *fs = mp->um_fs;
2067 struct buf *bp; 2067 struct buf *bp;
2068 int blks; 2068 int blks;
2069 void *space; 2069 void *space;
2070 int i, size, error = 0, allerror = 0; 2070 int i, size, error = 0, allerror = 0;
2071 2071
2072 allerror = ffs_sbupdate(mp, waitfor); 2072 allerror = ffs_sbupdate(mp, waitfor);
2073 blks = howmany(fs->fs_cssize, fs->fs_fsize); 2073 blks = howmany(fs->fs_cssize, fs->fs_fsize);