Line data Source code
1 : /* $OpenBSD: ffs_vfsops.c,v 1.178 2018/07/11 17:44:57 kn Exp $ */
2 : /* $NetBSD: ffs_vfsops.c,v 1.19 1996/02/09 22:22:26 christos Exp $ */
3 :
4 : /*
5 : * Copyright (c) 1989, 1991, 1993, 1994
6 : * The Regents of the University of California. All rights reserved.
7 : *
8 : * Redistribution and use in source and binary forms, with or without
9 : * modification, are permitted provided that the following conditions
10 : * are met:
11 : * 1. Redistributions of source code must retain the above copyright
12 : * notice, this list of conditions and the following disclaimer.
13 : * 2. Redistributions in binary form must reproduce the above copyright
14 : * notice, this list of conditions and the following disclaimer in the
15 : * documentation and/or other materials provided with the distribution.
16 : * 3. Neither the name of the University nor the names of its contributors
17 : * may be used to endorse or promote products derived from this software
18 : * without specific prior written permission.
19 : *
20 : * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 : * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 : * SUCH DAMAGE.
31 : *
32 : * @(#)ffs_vfsops.c 8.14 (Berkeley) 11/28/94
33 : */
34 :
35 : #include <sys/param.h>
36 : #include <sys/systm.h>
37 : #include <sys/namei.h>
38 : #include <sys/proc.h>
39 : #include <sys/kernel.h>
40 : #include <sys/vnode.h>
41 : #include <sys/socket.h>
42 : #include <sys/mount.h>
43 : #include <sys/buf.h>
44 : #include <sys/mbuf.h>
45 : #include <sys/fcntl.h>
46 : #include <sys/ioctl.h>
47 : #include <sys/errno.h>
48 : #include <sys/malloc.h>
49 : #include <sys/sysctl.h>
50 : #include <sys/pool.h>
51 : #include <sys/dkio.h>
52 : #include <sys/disk.h>
53 : #include <sys/specdev.h>
54 :
55 : #include <ufs/ufs/quota.h>
56 : #include <ufs/ufs/ufsmount.h>
57 : #include <ufs/ufs/inode.h>
58 : #include <ufs/ufs/dir.h>
59 : #include <ufs/ufs/ufs_extern.h>
60 : #include <ufs/ufs/dirhash.h>
61 :
62 : #include <ufs/ffs/fs.h>
63 : #include <ufs/ffs/ffs_extern.h>
64 :
65 : #include <uvm/uvm_extern.h>
66 :
67 : int ffs_sbupdate(struct ufsmount *, int);
68 : int ffs_reload_vnode(struct vnode *, void *);
69 : int ffs_sync_vnode(struct vnode *, void *);
70 : int ffs_validate(struct fs *);
71 :
72 : void ffs1_compat_read(struct fs *, struct ufsmount *, daddr_t);
73 : void ffs1_compat_write(struct fs *, struct ufsmount *);
74 :
75 : const struct vfsops ffs_vfsops = {
76 : ffs_mount,
77 : ufs_start,
78 : ffs_unmount,
79 : ufs_root,
80 : ufs_quotactl,
81 : ffs_statfs,
82 : ffs_sync,
83 : ffs_vget,
84 : ffs_fhtovp,
85 : ffs_vptofh,
86 : ffs_init,
87 : ffs_sysctl,
88 : ufs_check_export
89 : };
90 :
91 : struct inode_vtbl ffs_vtbl = {
92 : ffs_truncate,
93 : ffs_update,
94 : ffs_inode_alloc,
95 : ffs_inode_free,
96 : ffs_balloc,
97 : ffs_bufatoff
98 : };
99 :
100 : int
101 0 : ffs_checkrange(struct mount *mp, uint32_t ino)
102 : {
103 0 : struct buf *bp;
104 : struct cg *cgp;
105 : struct fs *fs;
106 : struct ufsmount *ump;
107 : int cg, error;
108 :
109 0 : fs = VFSTOUFS(mp)->um_fs;
110 0 : if (ino < ROOTINO || ino >= fs->fs_ncg * fs->fs_ipg)
111 0 : return ESTALE;
112 :
113 : /*
114 : * Need to check if inode is initialized because ffsv2 does
115 : * lazy initialization and we can get here from nfs_fhtovp
116 : */
117 0 : if (fs->fs_magic != FS_UFS2_MAGIC)
118 0 : return 0;
119 :
120 0 : cg = ino_to_cg(fs, ino);
121 : ump = VFSTOUFS(mp);
122 :
123 0 : error = bread(ump->um_devvp, fsbtodb(fs, cgtod(fs, cg)),
124 0 : (int)fs->fs_cgsize, &bp);
125 0 : if (error)
126 0 : return error;
127 :
128 0 : cgp = (struct cg *)bp->b_data;
129 0 : if (!cg_chkmagic(cgp)) {
130 0 : brelse(bp);
131 0 : return ESTALE;
132 : }
133 :
134 0 : brelse(bp);
135 :
136 0 : if (cg * fs->fs_ipg + cgp->cg_initediblk < ino)
137 0 : return ESTALE;
138 :
139 0 : return 0;
140 0 : }
141 :
142 : /*
143 : * Called by main() when ufs is going to be mounted as root.
144 : */
145 :
146 : struct pool ffs_ino_pool;
147 : struct pool ffs_dinode1_pool;
148 : #ifdef FFS2
149 : struct pool ffs_dinode2_pool;
150 : #endif
151 :
152 : int
153 0 : ffs_mountroot(void)
154 : {
155 : struct fs *fs;
156 0 : struct mount *mp;
157 0 : struct proc *p = curproc; /* XXX */
158 : struct ufsmount *ump;
159 : int error;
160 :
161 : /*
162 : * Get vnodes for swapdev and rootdev.
163 : */
164 0 : swapdev_vp = NULL;
165 0 : if ((error = bdevvp(swapdev, &swapdev_vp)) ||
166 0 : (error = bdevvp(rootdev, &rootvp))) {
167 0 : printf("ffs_mountroot: can't setup bdevvp's\n");
168 0 : if (swapdev_vp)
169 0 : vrele(swapdev_vp);
170 0 : return (error);
171 : }
172 :
173 0 : if ((error = vfs_rootmountalloc("ffs", "root_device", &mp)) != 0) {
174 0 : vrele(swapdev_vp);
175 0 : vrele(rootvp);
176 0 : return (error);
177 : }
178 :
179 0 : if ((error = ffs_mountfs(rootvp, mp, p)) != 0) {
180 0 : mp->mnt_vfc->vfc_refcount--;
181 0 : vfs_unbusy(mp);
182 0 : free(mp, M_MOUNT, sizeof(*mp));
183 0 : vrele(swapdev_vp);
184 0 : vrele(rootvp);
185 0 : return (error);
186 : }
187 :
188 0 : TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list);
189 0 : ump = VFSTOUFS(mp);
190 0 : fs = ump->um_fs;
191 0 : strlcpy(fs->fs_fsmnt, mp->mnt_stat.f_mntonname, sizeof(fs->fs_fsmnt));
192 0 : (void)ffs_statfs(mp, &mp->mnt_stat, p);
193 0 : vfs_unbusy(mp);
194 0 : inittodr(fs->fs_time);
195 :
196 0 : return (0);
197 0 : }
198 :
199 : /*
200 : * VFS Operations.
201 : *
202 : * mount system call
203 : */
204 : int
205 0 : ffs_mount(struct mount *mp, const char *path, void *data,
206 : struct nameidata *ndp, struct proc *p)
207 : {
208 : struct vnode *devvp;
209 0 : struct ufs_args *args = data;
210 : struct ufsmount *ump = NULL;
211 : struct fs *fs;
212 0 : char fname[MNAMELEN];
213 0 : char fspec[MNAMELEN];
214 : int error = 0, flags;
215 : int ronly;
216 :
217 : #ifndef FFS_SOFTUPDATES
218 : if (mp->mnt_flag & MNT_SOFTDEP) {
219 : printf("WARNING: soft updates isn't compiled in\n");
220 : mp->mnt_flag &= ~MNT_SOFTDEP;
221 : }
222 : #endif
223 :
224 : /*
225 : * Soft updates is incompatible with "async",
226 : * so if we are doing softupdates stop the user
227 : * from setting the async flag.
228 : */
229 0 : if ((mp->mnt_flag & (MNT_SOFTDEP | MNT_ASYNC)) ==
230 : (MNT_SOFTDEP | MNT_ASYNC)) {
231 0 : return (EINVAL);
232 : }
233 : /*
234 : * If updating, check whether changing from read-only to
235 : * read/write; if there is no device name, that's all we do.
236 : */
237 0 : if (mp->mnt_flag & MNT_UPDATE) {
238 0 : ump = VFSTOUFS(mp);
239 0 : fs = ump->um_fs;
240 0 : devvp = ump->um_devvp;
241 : error = 0;
242 0 : ronly = fs->fs_ronly;
243 :
244 : /*
245 : * Soft updates won't be set if read/write,
246 : * so "async" will be illegal.
247 : */
248 0 : if (ronly == 0 && (mp->mnt_flag & MNT_ASYNC) &&
249 0 : (fs->fs_flags & FS_DOSOFTDEP)) {
250 : error = EINVAL;
251 0 : goto error_1;
252 : }
253 :
254 0 : if (ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) {
255 : /* Flush any dirty data */
256 0 : VFS_SYNC(mp, MNT_WAIT, 0, p->p_ucred, p);
257 :
258 : /*
259 : * Get rid of files open for writing.
260 : */
261 : flags = WRITECLOSE;
262 0 : if (args == NULL)
263 0 : flags |= IGNORECLEAN;
264 0 : if (mp->mnt_flag & MNT_FORCE)
265 0 : flags |= FORCECLOSE;
266 0 : if (fs->fs_flags & FS_DOSOFTDEP) {
267 0 : error = softdep_flushfiles(mp, flags, p);
268 0 : mp->mnt_flag &= ~MNT_SOFTDEP;
269 0 : } else
270 0 : error = ffs_flushfiles(mp, flags, p);
271 0 : mp->mnt_flag |= MNT_RDONLY;
272 : ronly = 1;
273 0 : }
274 :
275 : /*
276 : * Flush soft dependencies if disabling it via an update
277 : * mount. This may leave some items to be processed,
278 : * so don't do this yet XXX.
279 : */
280 0 : if ((fs->fs_flags & FS_DOSOFTDEP) &&
281 0 : !(mp->mnt_flag & MNT_SOFTDEP) &&
282 0 : !(mp->mnt_flag & MNT_RDONLY) && fs->fs_ronly == 0) {
283 : #if 0
284 : flags = WRITECLOSE;
285 : if (mp->mnt_flag & MNT_FORCE)
286 : flags |= FORCECLOSE;
287 : error = softdep_flushfiles(mp, flags, p);
288 : #elif FFS_SOFTUPDATES
289 0 : mp->mnt_flag |= MNT_SOFTDEP;
290 : #endif
291 0 : }
292 : /*
293 : * When upgrading to a softdep mount, we must first flush
294 : * all vnodes. (not done yet -- see above)
295 : */
296 0 : if (!(fs->fs_flags & FS_DOSOFTDEP) &&
297 0 : (mp->mnt_flag & MNT_SOFTDEP) && fs->fs_ronly == 0) {
298 : #if 0
299 : flags = WRITECLOSE;
300 : if (mp->mnt_flag & MNT_FORCE)
301 : flags |= FORCECLOSE;
302 : error = ffs_flushfiles(mp, flags, p);
303 : #else
304 0 : mp->mnt_flag &= ~MNT_SOFTDEP;
305 : #endif
306 0 : }
307 :
308 0 : if (!error && (mp->mnt_flag & MNT_RELOAD))
309 0 : error = ffs_reload(mp, ndp->ni_cnd.cn_cred, p);
310 0 : if (error)
311 : goto error_1;
312 :
313 0 : if (ronly && (mp->mnt_flag & MNT_WANTRDWR)) {
314 0 : if (fs->fs_clean == 0) {
315 : #if 0
316 : /*
317 : * It is safe to mount an unclean file system
318 : * if it was previously mounted with softdep
319 : * but we may lose space and must
320 : * sometimes run fsck manually.
321 : */
322 : if (fs->fs_flags & FS_DOSOFTDEP)
323 : printf(
324 : "WARNING: %s was not properly unmounted\n",
325 : fs->fs_fsmnt);
326 : else
327 : #endif
328 0 : if (mp->mnt_flag & MNT_FORCE) {
329 0 : printf(
330 : "WARNING: %s was not properly unmounted\n",
331 : fs->fs_fsmnt);
332 : } else {
333 0 : printf(
334 : "WARNING: R/W mount of %s denied. Filesystem is not clean - run fsck\n",
335 : fs->fs_fsmnt);
336 : error = EROFS;
337 0 : goto error_1;
338 : }
339 0 : }
340 :
341 0 : if ((fs->fs_flags & FS_DOSOFTDEP)) {
342 0 : error = softdep_mount(devvp, mp, fs,
343 0 : p->p_ucred);
344 0 : if (error)
345 : goto error_1;
346 : }
347 0 : fs->fs_contigdirs = malloc((u_long)fs->fs_ncg,
348 : M_UFSMNT, M_WAITOK|M_ZERO);
349 :
350 : ronly = 0;
351 0 : }
352 0 : if (args == NULL)
353 : goto success;
354 0 : if (args->fspec == NULL) {
355 : /*
356 : * Process export requests.
357 : */
358 0 : error = vfs_export(mp, &ump->um_export,
359 0 : &args->export_info);
360 0 : if (error)
361 : goto error_1;
362 : else
363 : goto success;
364 : }
365 : }
366 :
367 : /*
368 : * Not an update, or updating the name: look up the name
369 : * and verify that it refers to a sensible block device.
370 : */
371 0 : error = copyinstr(args->fspec, fspec, sizeof(fspec), NULL);
372 0 : if (error)
373 : goto error_1;
374 :
375 0 : if (disk_map(fspec, fname, MNAMELEN, DM_OPENBLCK) == -1)
376 0 : memcpy(fname, fspec, sizeof(fname));
377 :
378 0 : NDINIT(ndp, LOOKUP, FOLLOW, UIO_SYSSPACE, fname, p);
379 0 : if ((error = namei(ndp)) != 0)
380 : goto error_1;
381 :
382 0 : devvp = ndp->ni_vp;
383 :
384 0 : if (devvp->v_type != VBLK) {
385 : error = ENOTBLK;
386 0 : goto error_2;
387 : }
388 :
389 0 : if (major(devvp->v_rdev) >= nblkdev) {
390 : error = ENXIO;
391 0 : goto error_2;
392 : }
393 :
394 0 : if (mp->mnt_flag & MNT_UPDATE) {
395 : /*
396 : * UPDATE
397 : * If it's not the same vnode, or at least the same device
398 : * then it's not correct.
399 : */
400 :
401 0 : if (devvp != ump->um_devvp) {
402 0 : if (devvp->v_rdev == ump->um_devvp->v_rdev) {
403 0 : vrele(devvp);
404 0 : } else {
405 : error = EINVAL; /* needs translation */
406 : }
407 : } else
408 0 : vrele(devvp);
409 : /*
410 : * Update device name only on success
411 : */
412 0 : if (!error) {
413 : /*
414 : * Save "mounted from" info for mount point (NULL pad)
415 : */
416 0 : memset(mp->mnt_stat.f_mntfromname, 0, MNAMELEN);
417 0 : strlcpy(mp->mnt_stat.f_mntfromname, fname, MNAMELEN);
418 0 : memset(mp->mnt_stat.f_mntfromspec, 0, MNAMELEN);
419 0 : strlcpy(mp->mnt_stat.f_mntfromspec, fspec, MNAMELEN);
420 0 : }
421 : } else {
422 : /*
423 : * Since this is a new mount, we want the names for
424 : * the device and the mount point copied in. If an
425 : * error occurs, the mountpoint is discarded by the
426 : * upper level code.
427 : */
428 0 : memset(mp->mnt_stat.f_mntonname, 0, MNAMELEN);
429 0 : strlcpy(mp->mnt_stat.f_mntonname, path, MNAMELEN);
430 0 : memset(mp->mnt_stat.f_mntfromname, 0, MNAMELEN);
431 0 : strlcpy(mp->mnt_stat.f_mntfromname, fname, MNAMELEN);
432 0 : memset(mp->mnt_stat.f_mntfromspec, 0, MNAMELEN);
433 0 : strlcpy(mp->mnt_stat.f_mntfromspec, fspec, MNAMELEN);
434 :
435 0 : error = ffs_mountfs(devvp, mp, p);
436 : }
437 :
438 0 : if (error)
439 : goto error_2;
440 :
441 : /*
442 : * Initialize FS stat information in mount struct; uses both
443 : * mp->mnt_stat.f_mntonname and mp->mnt_stat.f_mntfromname
444 : *
445 : * This code is common to root and non-root mounts
446 : */
447 0 : if (args)
448 0 : memcpy(&mp->mnt_stat.mount_info.ufs_args, args, sizeof(*args));
449 0 : VFS_STATFS(mp, &mp->mnt_stat, p);
450 :
451 : success:
452 0 : if (path && (mp->mnt_flag & MNT_UPDATE)) {
453 : /* Update clean flag after changing read-onlyness. */
454 0 : fs = ump->um_fs;
455 0 : if (ronly != fs->fs_ronly) {
456 0 : fs->fs_ronly = ronly;
457 0 : fs->fs_clean = ronly &&
458 0 : (fs->fs_flags & FS_UNCLEAN) == 0 ? 1 : 0;
459 0 : if (ronly)
460 0 : free(fs->fs_contigdirs, M_UFSMNT, fs->fs_ncg);
461 : }
462 0 : if (!ronly) {
463 0 : if (mp->mnt_flag & MNT_SOFTDEP)
464 0 : fs->fs_flags |= FS_DOSOFTDEP;
465 : else
466 0 : fs->fs_flags &= ~FS_DOSOFTDEP;
467 : }
468 0 : ffs_sbupdate(ump, MNT_WAIT);
469 : #if 0
470 : if (ronly) {
471 : int force = 0;
472 :
473 : /*
474 : * Updating mount to readonly. Try a cache flush.
475 : * Ignore error because the ioctl may not be supported.
476 : */
477 : VOP_IOCTL(ump->um_devvp, DIOCCACHESYNC, &force,
478 : FWRITE, FSCRED, p);
479 : }
480 : #endif
481 0 : }
482 0 : return (0);
483 :
484 : error_2: /* error with devvp held */
485 0 : vrele (devvp);
486 :
487 : error_1: /* no state to back out */
488 0 : return (error);
489 0 : }
490 :
491 : struct ffs_reload_args {
492 : struct fs *fs;
493 : struct proc *p;
494 : struct ucred *cred;
495 : struct vnode *devvp;
496 : };
497 :
498 : int
499 0 : ffs_reload_vnode(struct vnode *vp, void *args)
500 : {
501 0 : struct ffs_reload_args *fra = args;
502 : struct inode *ip;
503 0 : struct buf *bp;
504 : int error;
505 :
506 : /*
507 : * Step 4: invalidate all inactive vnodes.
508 : */
509 0 : if (vp->v_usecount == 0) {
510 0 : vgonel(vp, fra->p);
511 0 : return (0);
512 : }
513 :
514 : /*
515 : * Step 5: invalidate all cached file data.
516 : */
517 0 : if (vget(vp, LK_EXCLUSIVE))
518 0 : return (0);
519 :
520 0 : if (vinvalbuf(vp, 0, fra->cred, fra->p, 0, 0))
521 0 : panic("ffs_reload: dirty2");
522 :
523 : /*
524 : * Step 6: re-read inode data for all active vnodes.
525 : */
526 0 : ip = VTOI(vp);
527 :
528 0 : error = bread(fra->devvp,
529 0 : fsbtodb(fra->fs, ino_to_fsba(fra->fs, ip->i_number)),
530 0 : (int)fra->fs->fs_bsize, &bp);
531 0 : if (error) {
532 0 : brelse(bp);
533 0 : vput(vp);
534 0 : return (error);
535 : }
536 :
537 0 : *ip->i_din1 = *((struct ufs1_dinode *)bp->b_data +
538 0 : ino_to_fsbo(fra->fs, ip->i_number));
539 0 : ip->i_effnlink = DIP(ip, nlink);
540 0 : brelse(bp);
541 0 : vput(vp);
542 0 : return (0);
543 0 : }
544 :
545 : /*
546 : * Reload all incore data for a filesystem (used after running fsck on
547 : * the root filesystem and finding things to fix). The filesystem must
548 : * be mounted read-only.
549 : *
550 : * Things to do to update the mount:
551 : * 1) invalidate all cached meta-data.
552 : * 2) re-read superblock from disk.
553 : * 3) re-read summary information from disk.
554 : * 4) invalidate all inactive vnodes.
555 : * 5) invalidate all cached file data.
556 : * 6) re-read inode data for all active vnodes.
557 : */
558 : int
559 0 : ffs_reload(struct mount *mountp, struct ucred *cred, struct proc *p)
560 : {
561 : struct vnode *devvp;
562 : caddr_t space;
563 : struct fs *fs, *newfs;
564 : int i, blks, size, error;
565 : int32_t *lp;
566 0 : struct buf *bp = NULL;
567 0 : struct ffs_reload_args fra;
568 :
569 0 : if ((mountp->mnt_flag & MNT_RDONLY) == 0)
570 0 : return (EINVAL);
571 : /*
572 : * Step 1: invalidate all cached meta-data.
573 : */
574 0 : devvp = VFSTOUFS(mountp)->um_devvp;
575 0 : vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
576 0 : error = vinvalbuf(devvp, 0, cred, p, 0, 0);
577 0 : VOP_UNLOCK(devvp);
578 0 : if (error)
579 0 : panic("ffs_reload: dirty1");
580 :
581 : /*
582 : * Step 2: re-read superblock from disk.
583 : */
584 0 : fs = VFSTOUFS(mountp)->um_fs;
585 :
586 0 : error = bread(devvp, fs->fs_sblockloc / DEV_BSIZE, SBSIZE, &bp);
587 0 : if (error) {
588 0 : brelse(bp);
589 0 : return (error);
590 : }
591 :
592 0 : newfs = (struct fs *)bp->b_data;
593 0 : if (ffs_validate(newfs) == 0) {
594 0 : brelse(bp);
595 0 : return (EINVAL);
596 : }
597 :
598 : /*
599 : * Copy pointer fields back into superblock before copying in XXX
600 : * new superblock. These should really be in the ufsmount. XXX
601 : * Note that important parameters (eg fs_ncg) are unchanged.
602 : */
603 0 : newfs->fs_csp = fs->fs_csp;
604 0 : newfs->fs_maxcluster = fs->fs_maxcluster;
605 0 : newfs->fs_ronly = fs->fs_ronly;
606 0 : memcpy(fs, newfs, fs->fs_sbsize);
607 0 : if (fs->fs_sbsize < SBSIZE)
608 0 : bp->b_flags |= B_INVAL;
609 0 : brelse(bp);
610 0 : VFSTOUFS(mountp)->um_maxsymlinklen = fs->fs_maxsymlinklen;
611 0 : ffs1_compat_read(fs, VFSTOUFS(mountp), fs->fs_sblockloc);
612 0 : ffs_oldfscompat(fs);
613 0 : (void)ffs_statfs(mountp, &mountp->mnt_stat, p);
614 : /*
615 : * Step 3: re-read summary information from disk.
616 : */
617 0 : blks = howmany(fs->fs_cssize, fs->fs_fsize);
618 0 : space = (caddr_t)fs->fs_csp;
619 0 : for (i = 0; i < blks; i += fs->fs_frag) {
620 0 : size = fs->fs_bsize;
621 0 : if (i + fs->fs_frag > blks)
622 0 : size = (blks - i) * fs->fs_fsize;
623 0 : error = bread(devvp, fsbtodb(fs, fs->fs_csaddr + i), size, &bp);
624 0 : if (error) {
625 0 : brelse(bp);
626 0 : return (error);
627 : }
628 0 : memcpy(space, bp->b_data, size);
629 0 : space += size;
630 0 : brelse(bp);
631 : }
632 0 : if ((fs->fs_flags & FS_DOSOFTDEP))
633 0 : (void) softdep_mount(devvp, mountp, fs, cred);
634 : /*
635 : * We no longer know anything about clusters per cylinder group.
636 : */
637 0 : if (fs->fs_contigsumsize > 0) {
638 0 : lp = fs->fs_maxcluster;
639 0 : for (i = 0; i < fs->fs_ncg; i++)
640 0 : *lp++ = fs->fs_contigsumsize;
641 : }
642 :
643 0 : fra.p = p;
644 0 : fra.cred = cred;
645 0 : fra.fs = fs;
646 0 : fra.devvp = devvp;
647 :
648 0 : error = vfs_mount_foreach_vnode(mountp, ffs_reload_vnode, &fra);
649 :
650 0 : return (error);
651 0 : }
652 :
653 : /*
654 : * Checks if a super block is sane enough to be mounted.
655 : */
656 : int
657 0 : ffs_validate(struct fs *fsp)
658 : {
659 : #ifdef FFS2
660 0 : if (fsp->fs_magic != FS_UFS2_MAGIC && fsp->fs_magic != FS_UFS1_MAGIC)
661 0 : return (0); /* Invalid magic */
662 : #else
663 : if (fsp->fs_magic != FS_UFS1_MAGIC)
664 : return (0); /* Invalid magic */
665 : #endif /* FFS2 */
666 :
667 0 : if ((u_int)fsp->fs_bsize > MAXBSIZE)
668 0 : return (0); /* Invalid block size */
669 :
670 0 : if ((u_int)fsp->fs_bsize < sizeof(struct fs))
671 0 : return (0); /* Invalid block size */
672 :
673 0 : if ((u_int)fsp->fs_sbsize > SBSIZE)
674 0 : return (0); /* Invalid super block size */
675 :
676 0 : if ((u_int)fsp->fs_frag > MAXFRAG || fragtbl[fsp->fs_frag] == NULL)
677 0 : return (0); /* Invalid number of fragments */
678 :
679 0 : if (fsp->fs_inodefmt == FS_42INODEFMT)
680 0 : fsp->fs_maxsymlinklen = 0;
681 0 : else if (fsp->fs_maxsymlinklen < 0)
682 0 : return (0); /* Invalid max size of short symlink */
683 :
684 0 : return (1); /* Super block is okay */
685 0 : }
686 :
687 : /*
688 : * Possible locations for the super-block.
689 : */
690 : const int sbtry[] = SBLOCKSEARCH;
691 :
692 : /*
693 : * Common code for mount and mountroot
694 : */
695 : int
696 0 : ffs_mountfs(struct vnode *devvp, struct mount *mp, struct proc *p)
697 : {
698 : struct ufsmount *ump;
699 0 : struct buf *bp;
700 : struct fs *fs;
701 : dev_t dev;
702 : caddr_t space;
703 : daddr_t sbloc;
704 : int error, i, blks, size, ronly;
705 : int32_t *lp;
706 : struct ucred *cred;
707 : u_int64_t maxfilesize; /* XXX */
708 :
709 0 : dev = devvp->v_rdev;
710 0 : cred = p ? p->p_ucred : NOCRED;
711 : /*
712 : * Disallow multiple mounts of the same device.
713 : * Disallow mounting of a device that is currently in use
714 : * (except for root, which might share swap device for miniroot).
715 : * Flush out any old buffers remaining from a previous use.
716 : */
717 0 : if ((error = vfs_mountedon(devvp)) != 0)
718 0 : return (error);
719 0 : if (vcount(devvp) > 1 && devvp != rootvp)
720 0 : return (EBUSY);
721 0 : vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
722 0 : error = vinvalbuf(devvp, V_SAVE, cred, p, 0, 0);
723 0 : VOP_UNLOCK(devvp);
724 0 : if (error)
725 0 : return (error);
726 :
727 0 : ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
728 0 : error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, p);
729 0 : if (error)
730 0 : return (error);
731 :
732 0 : bp = NULL;
733 : ump = NULL;
734 :
735 : /*
736 : * Try reading the super-block in each of its possible locations.
737 : */
738 0 : for (i = 0; sbtry[i] != -1; i++) {
739 0 : if (bp != NULL) {
740 0 : bp->b_flags |= B_NOCACHE;
741 0 : brelse(bp);
742 0 : bp = NULL;
743 0 : }
744 :
745 0 : error = bread(devvp, sbtry[i] / DEV_BSIZE, SBSIZE, &bp);
746 0 : if (error)
747 : goto out;
748 :
749 0 : fs = (struct fs *) bp->b_data;
750 0 : sbloc = sbtry[i];
751 :
752 : #if 0
753 : if (fs->fs_magic == FS_UFS2_MAGIC) {
754 : printf("ffs_mountfs(): Sorry, no UFS2 support (yet)\n");
755 : error = EFTYPE;
756 : goto out;
757 : }
758 : #endif
759 :
760 : /*
761 : * Do not look for an FFS1 file system at SBLOCK_UFS2. Doing so
762 : * will find the wrong super-block for file systems with 64k
763 : * block size.
764 : */
765 0 : if (fs->fs_magic == FS_UFS1_MAGIC && sbloc == SBLOCK_UFS2)
766 : continue;
767 :
768 0 : if (ffs_validate(fs))
769 : break; /* Super block validated */
770 : }
771 :
772 0 : if (sbtry[i] == -1) {
773 : error = EINVAL;
774 0 : goto out;
775 : }
776 :
777 0 : fs->fs_fmod = 0;
778 0 : fs->fs_flags &= ~FS_UNCLEAN;
779 0 : if (fs->fs_clean == 0) {
780 : #if 0
781 : /*
782 : * It is safe to mount an unclean file system
783 : * if it was previously mounted with softdep
784 : * but we may lose space and must
785 : * sometimes run fsck manually.
786 : */
787 : if (fs->fs_flags & FS_DOSOFTDEP)
788 : printf(
789 : "WARNING: %s was not properly unmounted\n",
790 : fs->fs_fsmnt);
791 : else
792 : #endif
793 0 : if (ronly || (mp->mnt_flag & MNT_FORCE)) {
794 0 : printf(
795 : "WARNING: %s was not properly unmounted\n",
796 0 : fs->fs_fsmnt);
797 : } else {
798 0 : printf(
799 : "WARNING: R/W mount of %s denied. Filesystem is not clean - run fsck\n",
800 0 : fs->fs_fsmnt);
801 : error = EROFS;
802 0 : goto out;
803 : }
804 0 : }
805 :
806 0 : if (fs->fs_postblformat == FS_42POSTBLFMT && !ronly) {
807 : #ifndef SMALL_KERNEL
808 0 : printf("ffs_mountfs(): obsolete rotational table format, "
809 : "please use fsck_ffs(8) -c 1\n");
810 : #endif
811 : error = EFTYPE;
812 0 : goto out;
813 : }
814 :
815 0 : ump = malloc(sizeof *ump, M_UFSMNT, M_WAITOK|M_ZERO);
816 0 : ump->um_fs = malloc((u_long)fs->fs_sbsize, M_UFSMNT,
817 : M_WAITOK);
818 :
819 0 : if (fs->fs_magic == FS_UFS1_MAGIC)
820 0 : ump->um_fstype = UM_UFS1;
821 : #ifdef FFS2
822 : else
823 0 : ump->um_fstype = UM_UFS2;
824 : #endif
825 :
826 0 : memcpy(ump->um_fs, bp->b_data, fs->fs_sbsize);
827 0 : if (fs->fs_sbsize < SBSIZE)
828 0 : bp->b_flags |= B_INVAL;
829 0 : brelse(bp);
830 0 : bp = NULL;
831 0 : fs = ump->um_fs;
832 :
833 0 : ffs1_compat_read(fs, ump, sbloc);
834 :
835 0 : if (fs->fs_clean == 0)
836 0 : fs->fs_flags |= FS_UNCLEAN;
837 0 : fs->fs_ronly = ronly;
838 0 : size = fs->fs_cssize;
839 0 : blks = howmany(size, fs->fs_fsize);
840 0 : if (fs->fs_contigsumsize > 0)
841 0 : size += fs->fs_ncg * sizeof(int32_t);
842 0 : space = malloc((u_long)size, M_UFSMNT, M_WAITOK);
843 0 : fs->fs_csp = (struct csum *)space;
844 0 : for (i = 0; i < blks; i += fs->fs_frag) {
845 0 : size = fs->fs_bsize;
846 0 : if (i + fs->fs_frag > blks)
847 0 : size = (blks - i) * fs->fs_fsize;
848 0 : error = bread(devvp, fsbtodb(fs, fs->fs_csaddr + i), size, &bp);
849 0 : if (error) {
850 0 : free(fs->fs_csp, M_UFSMNT, 0);
851 0 : goto out;
852 : }
853 0 : memcpy(space, bp->b_data, size);
854 0 : space += size;
855 0 : brelse(bp);
856 0 : bp = NULL;
857 : }
858 0 : if (fs->fs_contigsumsize > 0) {
859 0 : fs->fs_maxcluster = lp = (int32_t *)space;
860 0 : for (i = 0; i < fs->fs_ncg; i++)
861 0 : *lp++ = fs->fs_contigsumsize;
862 : }
863 0 : mp->mnt_data = ump;
864 0 : mp->mnt_stat.f_fsid.val[0] = (long)dev;
865 : /* Use on-disk fsid if it exists, else fake it */
866 0 : if (fs->fs_id[0] != 0 && fs->fs_id[1] != 0)
867 0 : mp->mnt_stat.f_fsid.val[1] = fs->fs_id[1];
868 : else
869 0 : mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
870 0 : mp->mnt_stat.f_namemax = MAXNAMLEN;
871 0 : mp->mnt_flag |= MNT_LOCAL;
872 0 : ump->um_mountp = mp;
873 0 : ump->um_dev = dev;
874 0 : ump->um_devvp = devvp;
875 0 : ump->um_nindir = fs->fs_nindir;
876 0 : ump->um_bptrtodb = fs->fs_fsbtodb;
877 0 : ump->um_seqinc = fs->fs_frag;
878 0 : ump->um_maxsymlinklen = fs->fs_maxsymlinklen;
879 0 : for (i = 0; i < MAXQUOTAS; i++)
880 0 : ump->um_quotas[i] = NULLVP;
881 :
882 0 : devvp->v_specmountpoint = mp;
883 0 : ffs_oldfscompat(fs);
884 :
885 0 : if (ronly)
886 0 : fs->fs_contigdirs = NULL;
887 : else {
888 0 : fs->fs_contigdirs = malloc((u_long)fs->fs_ncg,
889 : M_UFSMNT, M_WAITOK|M_ZERO);
890 : }
891 :
892 : /*
893 : * Set FS local "last mounted on" information (NULL pad)
894 : */
895 0 : memset(fs->fs_fsmnt, 0, sizeof(fs->fs_fsmnt));
896 0 : strlcpy(fs->fs_fsmnt, mp->mnt_stat.f_mntonname, sizeof(fs->fs_fsmnt));
897 :
898 : #if 0
899 : if( mp->mnt_flag & MNT_ROOTFS) {
900 : /*
901 : * Root mount; update timestamp in mount structure.
902 : * this will be used by the common root mount code
903 : * to update the system clock.
904 : */
905 : mp->mnt_time = fs->fs_time;
906 : }
907 : #endif
908 :
909 : /*
910 : * XXX
911 : * Limit max file size. Even though ffs can handle files up to 16TB,
912 : * we do limit the max file to 2^31 pages to prevent overflow of
913 : * a 32-bit unsigned int. The buffer cache has its own checks but
914 : * a little added paranoia never hurts.
915 : */
916 0 : ump->um_savedmaxfilesize = fs->fs_maxfilesize; /* XXX */
917 0 : maxfilesize = FS_KERNMAXFILESIZE(PAGE_SIZE, fs);
918 0 : if (fs->fs_maxfilesize > maxfilesize) /* XXX */
919 0 : fs->fs_maxfilesize = maxfilesize; /* XXX */
920 0 : if (ronly == 0) {
921 0 : if ((fs->fs_flags & FS_DOSOFTDEP) &&
922 0 : (error = softdep_mount(devvp, mp, fs, cred)) != 0) {
923 0 : free(fs->fs_csp, M_UFSMNT, 0);
924 0 : free(fs->fs_contigdirs, M_UFSMNT, fs->fs_ncg);
925 0 : goto out;
926 : }
927 0 : fs->fs_fmod = 1;
928 0 : fs->fs_clean = 0;
929 0 : if (mp->mnt_flag & MNT_SOFTDEP)
930 0 : fs->fs_flags |= FS_DOSOFTDEP;
931 : else
932 0 : fs->fs_flags &= ~FS_DOSOFTDEP;
933 0 : error = ffs_sbupdate(ump, MNT_WAIT);
934 0 : if (error == EROFS)
935 : goto out;
936 : }
937 0 : return (0);
938 : out:
939 0 : if (devvp->v_specinfo)
940 0 : devvp->v_specmountpoint = NULL;
941 0 : if (bp)
942 0 : brelse(bp);
943 :
944 0 : vn_lock(devvp, LK_EXCLUSIVE|LK_RETRY);
945 0 : (void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, cred, p);
946 0 : VOP_UNLOCK(devvp);
947 :
948 0 : if (ump) {
949 0 : free(ump->um_fs, M_UFSMNT, ump->um_fs->fs_sbsize);
950 0 : free(ump, M_UFSMNT, sizeof(*ump));
951 0 : mp->mnt_data = NULL;
952 0 : }
953 0 : return (error);
954 0 : }
955 :
956 : /*
957 : * Sanity checks for old file systems.
958 : */
959 : int
960 0 : ffs_oldfscompat(struct fs *fs)
961 : {
962 : int i;
963 :
964 0 : fs->fs_npsect = max(fs->fs_npsect, fs->fs_nsect); /* XXX */
965 0 : fs->fs_interleave = max(fs->fs_interleave, 1); /* XXX */
966 0 : if (fs->fs_postblformat == FS_42POSTBLFMT) /* XXX */
967 0 : fs->fs_nrpos = 8; /* XXX */
968 0 : if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */
969 0 : u_int64_t sizepb = fs->fs_bsize; /* XXX */
970 : /* XXX */
971 0 : fs->fs_maxfilesize = fs->fs_bsize * NDADDR - 1; /* XXX */
972 0 : for (i = 0; i < NIADDR; i++) { /* XXX */
973 0 : sizepb *= NINDIR(fs); /* XXX */
974 0 : fs->fs_maxfilesize += sizepb; /* XXX */
975 : } /* XXX */
976 0 : fs->fs_qbmask = ~fs->fs_bmask; /* XXX */
977 0 : fs->fs_qfmask = ~fs->fs_fmask; /* XXX */
978 0 : } /* XXX */
979 0 : if (fs->fs_avgfilesize <= 0) /* XXX */
980 0 : fs->fs_avgfilesize = AVFILESIZ; /* XXX */
981 0 : if (fs->fs_avgfpdir <= 0) /* XXX */
982 0 : fs->fs_avgfpdir = AFPDIR; /* XXX */
983 0 : return (0);
984 : }
985 :
986 : /*
987 : * Auxiliary function for reading FFS1 super blocks.
988 : */
989 : void
990 0 : ffs1_compat_read(struct fs *fs, struct ufsmount *ump, daddr_t sbloc)
991 : {
992 0 : if (fs->fs_magic == FS_UFS2_MAGIC)
993 : return; /* UFS2 */
994 : #if 0
995 : if (fs->fs_ffs1_flags & FS_FLAGS_UPDATED)
996 : return; /* Already updated */
997 : #endif
998 0 : fs->fs_flags = fs->fs_ffs1_flags;
999 0 : fs->fs_sblockloc = sbloc;
1000 0 : fs->fs_maxbsize = fs->fs_bsize;
1001 0 : fs->fs_time = fs->fs_ffs1_time;
1002 0 : fs->fs_size = fs->fs_ffs1_size;
1003 0 : fs->fs_dsize = fs->fs_ffs1_dsize;
1004 0 : fs->fs_csaddr = fs->fs_ffs1_csaddr;
1005 0 : fs->fs_cstotal.cs_ndir = fs->fs_ffs1_cstotal.cs_ndir;
1006 0 : fs->fs_cstotal.cs_nbfree = fs->fs_ffs1_cstotal.cs_nbfree;
1007 0 : fs->fs_cstotal.cs_nifree = fs->fs_ffs1_cstotal.cs_nifree;
1008 0 : fs->fs_cstotal.cs_nffree = fs->fs_ffs1_cstotal.cs_nffree;
1009 0 : fs->fs_ffs1_flags |= FS_FLAGS_UPDATED;
1010 0 : }
1011 :
1012 : /*
1013 : * Auxiliary function for writing FFS1 super blocks.
1014 : */
1015 : void
1016 0 : ffs1_compat_write(struct fs *fs, struct ufsmount *ump)
1017 : {
1018 0 : if (fs->fs_magic != FS_UFS1_MAGIC)
1019 : return; /* UFS2 */
1020 :
1021 0 : fs->fs_ffs1_time = fs->fs_time;
1022 0 : fs->fs_ffs1_cstotal.cs_ndir = fs->fs_cstotal.cs_ndir;
1023 0 : fs->fs_ffs1_cstotal.cs_nbfree = fs->fs_cstotal.cs_nbfree;
1024 0 : fs->fs_ffs1_cstotal.cs_nifree = fs->fs_cstotal.cs_nifree;
1025 0 : fs->fs_ffs1_cstotal.cs_nffree = fs->fs_cstotal.cs_nffree;
1026 0 : }
1027 :
1028 : /*
1029 : * unmount system call
1030 : */
1031 : int
1032 0 : ffs_unmount(struct mount *mp, int mntflags, struct proc *p)
1033 : {
1034 : struct ufsmount *ump;
1035 : struct fs *fs;
1036 : int error, flags;
1037 :
1038 : flags = 0;
1039 0 : if (mntflags & MNT_FORCE)
1040 0 : flags |= FORCECLOSE;
1041 :
1042 0 : ump = VFSTOUFS(mp);
1043 0 : fs = ump->um_fs;
1044 0 : if (mp->mnt_flag & MNT_SOFTDEP)
1045 0 : error = softdep_flushfiles(mp, flags, p);
1046 : else
1047 0 : error = ffs_flushfiles(mp, flags, p);
1048 0 : if (error != 0)
1049 0 : return (error);
1050 :
1051 0 : if (fs->fs_ronly == 0) {
1052 0 : fs->fs_clean = (fs->fs_flags & FS_UNCLEAN) ? 0 : 1;
1053 0 : error = ffs_sbupdate(ump, MNT_WAIT);
1054 : /* ignore write errors if mounted RW on read-only device */
1055 0 : if (error && error != EROFS) {
1056 0 : fs->fs_clean = 0;
1057 0 : return (error);
1058 : }
1059 0 : free(fs->fs_contigdirs, M_UFSMNT, fs->fs_ncg);
1060 0 : }
1061 0 : ump->um_devvp->v_specmountpoint = NULL;
1062 :
1063 0 : vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY);
1064 0 : vinvalbuf(ump->um_devvp, V_SAVE, NOCRED, p, 0, 0);
1065 0 : (void)VOP_CLOSE(ump->um_devvp, fs->fs_ronly ? FREAD : FREAD|FWRITE,
1066 : NOCRED, p);
1067 0 : vput(ump->um_devvp);
1068 0 : free(fs->fs_csp, M_UFSMNT, 0);
1069 0 : free(fs, M_UFSMNT, fs->fs_sbsize);
1070 0 : free(ump, M_UFSMNT, sizeof(*ump));
1071 0 : mp->mnt_data = NULL;
1072 0 : mp->mnt_flag &= ~MNT_LOCAL;
1073 0 : return (0);
1074 0 : }
1075 :
1076 : /*
1077 : * Flush out all the files in a filesystem.
1078 : */
1079 : int
1080 0 : ffs_flushfiles(struct mount *mp, int flags, struct proc *p)
1081 : {
1082 : struct ufsmount *ump;
1083 : int error;
1084 :
1085 0 : ump = VFSTOUFS(mp);
1086 0 : if (mp->mnt_flag & MNT_QUOTA) {
1087 : int i;
1088 0 : if ((error = vflush(mp, NULLVP, SKIPSYSTEM|flags)) != 0)
1089 0 : return (error);
1090 0 : for (i = 0; i < MAXQUOTAS; i++) {
1091 0 : if (ump->um_quotas[i] == NULLVP)
1092 : continue;
1093 0 : quotaoff(p, mp, i);
1094 0 : }
1095 : /*
1096 : * Here we fall through to vflush again to ensure
1097 : * that we have gotten rid of all the system vnodes.
1098 : */
1099 0 : }
1100 :
1101 : /*
1102 : * Flush all the files.
1103 : */
1104 0 : if ((error = vflush(mp, NULL, flags)) != 0)
1105 0 : return (error);
1106 : /*
1107 : * Flush filesystem metadata.
1108 : */
1109 0 : vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY);
1110 0 : error = VOP_FSYNC(ump->um_devvp, p->p_ucred, MNT_WAIT, p);
1111 0 : VOP_UNLOCK(ump->um_devvp);
1112 0 : return (error);
1113 0 : }
1114 :
1115 : /*
1116 : * Get file system statistics.
1117 : */
1118 : int
1119 0 : ffs_statfs(struct mount *mp, struct statfs *sbp, struct proc *p)
1120 : {
1121 : struct ufsmount *ump;
1122 : struct fs *fs;
1123 :
1124 0 : ump = VFSTOUFS(mp);
1125 0 : fs = ump->um_fs;
1126 :
1127 : #ifdef FFS2
1128 0 : if (fs->fs_magic != FS_MAGIC && fs->fs_magic != FS_UFS2_MAGIC)
1129 0 : panic("ffs_statfs");
1130 : #else
1131 : if (fs->fs_magic != FS_MAGIC)
1132 : panic("ffs_statfs");
1133 : #endif /* FFS2 */
1134 :
1135 0 : sbp->f_bsize = fs->fs_fsize;
1136 0 : sbp->f_iosize = fs->fs_bsize;
1137 0 : sbp->f_blocks = fs->fs_dsize;
1138 0 : sbp->f_bfree = fs->fs_cstotal.cs_nbfree * fs->fs_frag +
1139 0 : fs->fs_cstotal.cs_nffree;
1140 0 : sbp->f_bavail = sbp->f_bfree -
1141 0 : ((int64_t)fs->fs_dsize * fs->fs_minfree / 100);
1142 0 : sbp->f_files = fs->fs_ncg * fs->fs_ipg - ROOTINO;
1143 0 : sbp->f_ffree = fs->fs_cstotal.cs_nifree;
1144 0 : sbp->f_favail = sbp->f_ffree;
1145 0 : copy_statfs_info(sbp, mp);
1146 :
1147 0 : return (0);
1148 : }
1149 :
1150 : struct ffs_sync_args {
1151 : int allerror;
1152 : struct proc *p;
1153 : int waitfor;
1154 : int nlink0;
1155 : int inflight;
1156 : struct ucred *cred;
1157 : };
1158 :
1159 : int
1160 0 : ffs_sync_vnode(struct vnode *vp, void *arg)
1161 : {
1162 0 : struct ffs_sync_args *fsa = arg;
1163 : struct inode *ip;
1164 : int error, nlink0 = 0;
1165 :
1166 0 : if (vp->v_type == VNON)
1167 0 : return (0);
1168 :
1169 0 : ip = VTOI(vp);
1170 :
1171 0 : if (vp->v_inflight && !(vp->v_type == VCHR || vp->v_type == VBLK))
1172 0 : fsa->inflight = MIN(fsa->inflight+1, 65536);
1173 :
1174 : /*
1175 : * If unmounting or converting rw to ro, then stop deferring
1176 : * timestamp writes.
1177 : */
1178 0 : if (fsa->waitfor == MNT_WAIT && (ip->i_flag & IN_LAZYMOD)) {
1179 0 : ip->i_flag |= IN_MODIFIED;
1180 0 : UFS_UPDATE(ip, 1);
1181 0 : }
1182 :
1183 0 : if (ip->i_effnlink == 0)
1184 0 : nlink0 = 1;
1185 :
1186 0 : if ((ip->i_flag &
1187 0 : (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 &&
1188 0 : LIST_EMPTY(&vp->v_dirtyblkhd)) {
1189 : goto end;
1190 : }
1191 :
1192 0 : if (vget(vp, LK_EXCLUSIVE | LK_NOWAIT)) {
1193 : nlink0 = 1; /* potentially.. */
1194 0 : goto end;
1195 : }
1196 :
1197 0 : if ((error = VOP_FSYNC(vp, fsa->cred, fsa->waitfor, fsa->p)))
1198 0 : fsa->allerror = error;
1199 0 : VOP_UNLOCK(vp);
1200 0 : vrele(vp);
1201 :
1202 : end:
1203 0 : fsa->nlink0 = MIN(fsa->nlink0 + nlink0, 65536);
1204 0 : return (0);
1205 0 : }
1206 :
1207 : /*
1208 : * Go through the disk queues to initiate sandbagged IO;
1209 : * go through the inodes to write those that have been modified;
1210 : * initiate the writing of the super block if it has been modified.
1211 : *
1212 : * Should always be called with the mount point locked.
1213 : */
1214 : int
1215 0 : ffs_sync(struct mount *mp, int waitfor, int stall, struct ucred *cred, struct proc *p)
1216 : {
1217 0 : struct ufsmount *ump = VFSTOUFS(mp);
1218 : struct fs *fs;
1219 0 : int error, allerror = 0, count, clean, fmod;
1220 0 : struct ffs_sync_args fsa;
1221 :
1222 0 : fs = ump->um_fs;
1223 : /*
1224 : * Write back modified superblock.
1225 : * Consistency check that the superblock
1226 : * is still in the buffer cache.
1227 : */
1228 0 : if (fs->fs_fmod != 0 && fs->fs_ronly != 0) {
1229 0 : printf("fs = %s\n", fs->fs_fsmnt);
1230 0 : panic("update: rofs mod");
1231 : }
1232 : loop:
1233 : /*
1234 : * Write back each (modified) inode.
1235 : */
1236 0 : fsa.allerror = 0;
1237 0 : fsa.p = p;
1238 0 : fsa.cred = cred;
1239 0 : fsa.waitfor = waitfor;
1240 0 : fsa.nlink0 = 0;
1241 0 : fsa.inflight = 0;
1242 :
1243 : /*
1244 : * Don't traverse the vnode list if we want to skip all of them.
1245 : */
1246 0 : if (waitfor != MNT_LAZY) {
1247 0 : vfs_mount_foreach_vnode(mp, ffs_sync_vnode, &fsa);
1248 0 : allerror = fsa.allerror;
1249 0 : }
1250 :
1251 : /*
1252 : * Force stale file system control information to be flushed.
1253 : */
1254 0 : if ((ump->um_mountp->mnt_flag & MNT_SOFTDEP) && waitfor == MNT_WAIT) {
1255 0 : if ((error = softdep_flushworklist(ump->um_mountp, &count, p)))
1256 0 : allerror = error;
1257 : /* Flushed work items may create new vnodes to clean */
1258 0 : if (count)
1259 0 : goto loop;
1260 : }
1261 0 : if (waitfor != MNT_LAZY) {
1262 0 : vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY);
1263 0 : if ((error = VOP_FSYNC(ump->um_devvp, cred, waitfor, p)) != 0)
1264 0 : allerror = error;
1265 0 : VOP_UNLOCK(ump->um_devvp);
1266 0 : }
1267 0 : qsync(mp);
1268 : /*
1269 : * Write back modified superblock.
1270 : */
1271 0 : clean = fs->fs_clean;
1272 0 : fmod = fs->fs_fmod;
1273 0 : if (stall && fs->fs_ronly == 0) {
1274 0 : fs->fs_fmod = 1;
1275 0 : if (allerror == 0 && fsa.nlink0 == 0 && fsa.inflight == 0) {
1276 0 : fs->fs_clean = (fs->fs_flags & FS_UNCLEAN) ? 0 : 1;
1277 : #if 0
1278 : printf("%s force clean (dangling %d inflight %d)\n",
1279 : mp->mnt_stat.f_mntonname, fsa.nlink0, fsa.inflight);
1280 : #endif
1281 0 : } else {
1282 0 : fs->fs_clean = 0;
1283 : #if 0
1284 : printf("%s force dirty (dangling %d inflight %d)\n",
1285 : mp->mnt_stat.f_mntonname, fsa.nlink0, fsa.inflight);
1286 : #endif
1287 : }
1288 : }
1289 0 : if (fs->fs_fmod != 0 && (error = ffs_sbupdate(ump, waitfor)) != 0)
1290 0 : allerror = error;
1291 0 : fs->fs_clean = clean;
1292 0 : fs->fs_fmod = fmod;
1293 :
1294 0 : return (allerror);
1295 0 : }
1296 :
1297 : /*
1298 : * Look up a FFS dinode number to find its incore vnode, otherwise read it
1299 : * in from disk. If it is in core, wait for the lock bit to clear, then
1300 : * return the inode locked. Detection and handling of mount points must be
1301 : * done by the calling routine.
1302 : */
1303 : int
1304 0 : ffs_vget(struct mount *mp, ino_t ino, struct vnode **vpp)
1305 : {
1306 : struct fs *fs;
1307 : struct inode *ip;
1308 : struct ufs1_dinode *dp1;
1309 : #ifdef FFS2
1310 : struct ufs2_dinode *dp2;
1311 : #endif
1312 : struct ufsmount *ump;
1313 0 : struct buf *bp;
1314 0 : struct vnode *vp;
1315 : dev_t dev;
1316 : int error;
1317 :
1318 0 : if (ino > (ufsino_t)-1)
1319 0 : panic("ffs_vget: alien ino_t %llu", (unsigned long long)ino);
1320 :
1321 0 : ump = VFSTOUFS(mp);
1322 0 : dev = ump->um_dev;
1323 : retry:
1324 0 : if ((*vpp = ufs_ihashget(dev, ino)) != NULL)
1325 0 : return (0);
1326 :
1327 : /* Allocate a new vnode/inode. */
1328 0 : if ((error = getnewvnode(VT_UFS, mp, &ffs_vops, &vp)) != 0) {
1329 0 : *vpp = NULL;
1330 0 : return (error);
1331 : }
1332 :
1333 : #ifdef VFSLCKDEBUG
1334 : vp->v_flag |= VLOCKSWORK;
1335 : #endif
1336 0 : ip = pool_get(&ffs_ino_pool, PR_WAITOK|PR_ZERO);
1337 0 : rrw_init_flags(&ip->i_lock, "inode", RWL_DUPOK | RWL_IS_VNODE);
1338 0 : ip->i_ump = ump;
1339 0 : vref(ip->i_devvp);
1340 0 : vp->v_data = ip;
1341 0 : ip->i_vnode = vp;
1342 0 : ip->i_fs = fs = ump->um_fs;
1343 0 : ip->i_dev = dev;
1344 0 : ip->i_number = ino;
1345 0 : ip->i_vtbl = &ffs_vtbl;
1346 :
1347 : /*
1348 : * Put it onto its hash chain and lock it so that other requests for
1349 : * this inode will block if they arrive while we are sleeping waiting
1350 : * for old data structures to be purged or for the contents of the
1351 : * disk portion of this inode to be read.
1352 : */
1353 0 : error = ufs_ihashins(ip);
1354 :
1355 0 : if (error) {
1356 : /*
1357 : * VOP_INACTIVE will treat this as a stale file
1358 : * and recycle it quickly
1359 : */
1360 0 : vrele(vp);
1361 :
1362 0 : if (error == EEXIST)
1363 0 : goto retry;
1364 :
1365 0 : return (error);
1366 : }
1367 :
1368 :
1369 : /* Read in the disk contents for the inode, copy into the inode. */
1370 0 : error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)),
1371 0 : (int)fs->fs_bsize, &bp);
1372 0 : if (error) {
1373 : /*
1374 : * The inode does not contain anything useful, so it would
1375 : * be misleading to leave it on its hash chain. With mode
1376 : * still zero, it will be unlinked and returned to the free
1377 : * list by vput().
1378 : */
1379 0 : vput(vp);
1380 0 : brelse(bp);
1381 0 : *vpp = NULL;
1382 0 : return (error);
1383 : }
1384 :
1385 : #ifdef FFS2
1386 0 : if (ip->i_ump->um_fstype == UM_UFS2) {
1387 0 : ip->i_din2 = pool_get(&ffs_dinode2_pool, PR_WAITOK);
1388 0 : dp2 = (struct ufs2_dinode *) bp->b_data + ino_to_fsbo(fs, ino);
1389 0 : *ip->i_din2 = *dp2;
1390 0 : } else
1391 : #endif
1392 : {
1393 0 : ip->i_din1 = pool_get(&ffs_dinode1_pool, PR_WAITOK);
1394 0 : dp1 = (struct ufs1_dinode *) bp->b_data + ino_to_fsbo(fs, ino);
1395 0 : *ip->i_din1 = *dp1;
1396 : }
1397 :
1398 0 : brelse(bp);
1399 :
1400 0 : if (DOINGSOFTDEP(vp))
1401 0 : softdep_load_inodeblock(ip);
1402 : else
1403 0 : ip->i_effnlink = DIP(ip, nlink);
1404 :
1405 : /*
1406 : * Initialize the vnode from the inode, check for aliases.
1407 : * Note that the underlying vnode may have changed.
1408 : */
1409 0 : if ((error = ffs_vinit(mp, &vp)) != 0) {
1410 0 : vput(vp);
1411 0 : *vpp = NULL;
1412 0 : return (error);
1413 : }
1414 :
1415 : /*
1416 : * Set up a generation number for this inode if it does not
1417 : * already have one. This should only happen on old filesystems.
1418 : */
1419 0 : if (DIP(ip, gen) == 0) {
1420 0 : DIP_ASSIGN(ip, gen, arc4random() & INT_MAX);
1421 0 : if (DIP(ip, gen) == 0 || DIP(ip, gen) == -1)
1422 0 : DIP_ASSIGN(ip, gen, 1); /* Shouldn't happen */
1423 0 : if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0)
1424 0 : ip->i_flag |= IN_MODIFIED;
1425 : }
1426 :
1427 : /*
1428 : * Ensure that uid and gid are correct. This is a temporary
1429 : * fix until fsck has been changed to do the update.
1430 : */
1431 0 : if (fs->fs_magic == FS_UFS1_MAGIC && fs->fs_inodefmt < FS_44INODEFMT) {
1432 0 : ip->i_ffs1_uid = ip->i_din1->di_ouid;
1433 0 : ip->i_ffs1_gid = ip->i_din1->di_ogid;
1434 0 : }
1435 :
1436 0 : *vpp = vp;
1437 :
1438 0 : return (0);
1439 0 : }
1440 :
1441 : /*
1442 : * File handle to vnode
1443 : *
1444 : * Have to be really careful about stale file handles.
1445 : */
1446 : int
1447 0 : ffs_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp)
1448 : {
1449 : struct ufid *ufhp;
1450 : int error;
1451 :
1452 0 : ufhp = (struct ufid *)fhp;
1453 0 : if (ufhp->ufid_len != sizeof(*ufhp))
1454 0 : return EINVAL;
1455 :
1456 0 : if ((error = ffs_checkrange(mp, ufhp->ufid_ino)) != 0)
1457 0 : return error;
1458 :
1459 0 : return (ufs_fhtovp(mp, ufhp, vpp));
1460 0 : }
1461 :
1462 : /*
1463 : * Vnode pointer to File handle
1464 : */
1465 : int
1466 0 : ffs_vptofh(struct vnode *vp, struct fid *fhp)
1467 : {
1468 : struct inode *ip;
1469 : struct ufid *ufhp;
1470 :
1471 0 : ip = VTOI(vp);
1472 0 : ufhp = (struct ufid *)fhp;
1473 0 : ufhp->ufid_len = sizeof(struct ufid);
1474 0 : ufhp->ufid_ino = ip->i_number;
1475 0 : ufhp->ufid_gen = DIP(ip, gen);
1476 :
1477 0 : return (0);
1478 : }
1479 :
1480 : /*
1481 : * Write a superblock and associated information back to disk.
1482 : */
1483 : int
1484 0 : ffs_sbupdate(struct ufsmount *mp, int waitfor)
1485 : {
1486 0 : struct fs *dfs, *fs = mp->um_fs;
1487 : struct buf *bp;
1488 : int blks;
1489 : caddr_t space;
1490 : int i, size, error, allerror = 0;
1491 :
1492 : /*
1493 : * First write back the summary information.
1494 : */
1495 0 : blks = howmany(fs->fs_cssize, fs->fs_fsize);
1496 0 : space = (caddr_t)fs->fs_csp;
1497 0 : for (i = 0; i < blks; i += fs->fs_frag) {
1498 0 : size = fs->fs_bsize;
1499 0 : if (i + fs->fs_frag > blks)
1500 0 : size = (blks - i) * fs->fs_fsize;
1501 0 : bp = getblk(mp->um_devvp, fsbtodb(fs, fs->fs_csaddr + i),
1502 : size, 0, 0);
1503 0 : memcpy(bp->b_data, space, size);
1504 0 : space += size;
1505 0 : if (waitfor != MNT_WAIT)
1506 0 : bawrite(bp);
1507 0 : else if ((error = bwrite(bp)))
1508 0 : allerror = error;
1509 : }
1510 :
1511 : /*
1512 : * Now write back the superblock itself. If any errors occurred
1513 : * up to this point, then fail so that the superblock avoids
1514 : * being written out as clean.
1515 : */
1516 0 : if (allerror) {
1517 0 : return (allerror);
1518 : }
1519 :
1520 0 : bp = getblk(mp->um_devvp,
1521 0 : fs->fs_sblockloc >> (fs->fs_fshift - fs->fs_fsbtodb),
1522 0 : (int)fs->fs_sbsize, 0, 0);
1523 0 : fs->fs_fmod = 0;
1524 0 : fs->fs_time = time_second;
1525 0 : memcpy(bp->b_data, fs, fs->fs_sbsize);
1526 : /* Restore compatibility to old file systems. XXX */
1527 0 : dfs = (struct fs *)bp->b_data; /* XXX */
1528 0 : if (fs->fs_postblformat == FS_42POSTBLFMT) /* XXX */
1529 0 : dfs->fs_nrpos = -1; /* XXX */
1530 0 : if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */
1531 : int32_t *lp, tmp; /* XXX */
1532 : /* XXX */
1533 0 : lp = (int32_t *)&dfs->fs_qbmask; /* XXX */
1534 0 : tmp = lp[4]; /* XXX */
1535 0 : for (i = 4; i > 0; i--) /* XXX */
1536 0 : lp[i] = lp[i-1]; /* XXX */
1537 0 : lp[0] = tmp; /* XXX */
1538 0 : } /* XXX */
1539 0 : dfs->fs_maxfilesize = mp->um_savedmaxfilesize; /* XXX */
1540 :
1541 0 : ffs1_compat_write(dfs, mp);
1542 :
1543 0 : if (waitfor != MNT_WAIT)
1544 0 : bawrite(bp);
1545 0 : else if ((error = bwrite(bp)))
1546 0 : allerror = error;
1547 :
1548 0 : return (allerror);
1549 0 : }
1550 :
1551 : int
1552 0 : ffs_init(struct vfsconf *vfsp)
1553 : {
1554 : static int done;
1555 :
1556 0 : if (done)
1557 0 : return (0);
1558 :
1559 0 : done = 1;
1560 :
1561 0 : pool_init(&ffs_ino_pool, sizeof(struct inode), 0, IPL_NONE,
1562 : PR_WAITOK, "ffsino", NULL);
1563 0 : pool_init(&ffs_dinode1_pool, sizeof(struct ufs1_dinode), 0, IPL_NONE,
1564 : PR_WAITOK, "dino1pl", NULL);
1565 : #ifdef FFS2
1566 0 : pool_init(&ffs_dinode2_pool, sizeof(struct ufs2_dinode), 0, IPL_NONE,
1567 : PR_WAITOK, "dino2pl", NULL);
1568 : #endif
1569 :
1570 0 : softdep_initialize();
1571 :
1572 0 : return (ufs_init(vfsp));
1573 0 : }
1574 :
1575 : /*
1576 : * fast filesystem related variables.
1577 : */
1578 : int
1579 0 : ffs_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
1580 : size_t newlen, struct proc *p)
1581 : {
1582 : #ifdef FFS_SOFTUPDATES
1583 : extern int max_softdeps, tickdelay, stat_worklist_push;
1584 : extern int stat_blk_limit_push, stat_ino_limit_push, stat_blk_limit_hit;
1585 : extern int stat_ino_limit_hit, stat_sync_limit_hit, stat_indir_blk_ptrs;
1586 : extern int stat_inode_bitmap, stat_direct_blk_ptrs, stat_dir_entry;
1587 : #endif
1588 :
1589 : /* all sysctl names at this level are terminal */
1590 0 : if (namelen != 1)
1591 0 : return (ENOTDIR); /* overloaded */
1592 :
1593 0 : switch (name[0]) {
1594 : case FFS_CLUSTERREAD:
1595 : case FFS_CLUSTERWRITE:
1596 : case FFS_REALLOCBLKS:
1597 : case FFS_ASYNCFREE:
1598 0 : return (EOPNOTSUPP);
1599 : #ifdef FFS_SOFTUPDATES
1600 : case FFS_MAX_SOFTDEPS:
1601 0 : return (sysctl_int(oldp, oldlenp, newp, newlen, &max_softdeps));
1602 : case FFS_SD_TICKDELAY:
1603 0 : return (sysctl_int(oldp, oldlenp, newp, newlen, &tickdelay));
1604 : case FFS_SD_WORKLIST_PUSH:
1605 0 : return (sysctl_rdint(oldp, oldlenp, newp, stat_worklist_push));
1606 : case FFS_SD_BLK_LIMIT_PUSH:
1607 0 : return (sysctl_rdint(oldp, oldlenp, newp, stat_blk_limit_push));
1608 : case FFS_SD_INO_LIMIT_PUSH:
1609 0 : return (sysctl_rdint(oldp, oldlenp, newp, stat_ino_limit_push));
1610 : case FFS_SD_BLK_LIMIT_HIT:
1611 0 : return (sysctl_rdint(oldp, oldlenp, newp, stat_blk_limit_hit));
1612 : case FFS_SD_INO_LIMIT_HIT:
1613 0 : return (sysctl_rdint(oldp, oldlenp, newp, stat_ino_limit_hit));
1614 : case FFS_SD_SYNC_LIMIT_HIT:
1615 0 : return (sysctl_rdint(oldp, oldlenp, newp, stat_sync_limit_hit));
1616 : case FFS_SD_INDIR_BLK_PTRS:
1617 0 : return (sysctl_rdint(oldp, oldlenp, newp, stat_indir_blk_ptrs));
1618 : case FFS_SD_INODE_BITMAP:
1619 0 : return (sysctl_rdint(oldp, oldlenp, newp, stat_inode_bitmap));
1620 : case FFS_SD_DIRECT_BLK_PTRS:
1621 0 : return (sysctl_rdint(oldp, oldlenp, newp, stat_direct_blk_ptrs));
1622 : case FFS_SD_DIR_ENTRY:
1623 0 : return (sysctl_rdint(oldp, oldlenp, newp, stat_dir_entry));
1624 : #endif
1625 : #ifdef UFS_DIRHASH
1626 : case FFS_DIRHASH_DIRSIZE:
1627 0 : return (sysctl_int(oldp, oldlenp, newp, newlen,
1628 : &ufs_mindirhashsize));
1629 : case FFS_DIRHASH_MAXMEM:
1630 0 : return (sysctl_int(oldp, oldlenp, newp, newlen,
1631 : &ufs_dirhashmaxmem));
1632 : case FFS_DIRHASH_MEM:
1633 0 : return (sysctl_rdint(oldp, oldlenp, newp, ufs_dirhashmem));
1634 : #endif
1635 :
1636 : default:
1637 0 : return (EOPNOTSUPP);
1638 : }
1639 : /* NOTREACHED */
1640 0 : }
|