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