xref: /original-bsd/sys/ufs/ffs/ffs_vfsops.c (revision f17085de)
1 /*
2  * Copyright (c) 1989, 1991, 1993, 1994
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  *
7  *	@(#)ffs_vfsops.c	8.29 (Berkeley) 05/17/95
8  */
9 
10 #include <sys/param.h>
11 #include <sys/systm.h>
12 #include <sys/namei.h>
13 #include <sys/proc.h>
14 #include <sys/kernel.h>
15 #include <sys/vnode.h>
16 #include <sys/socket.h>
17 #include <sys/mount.h>
18 #include <sys/buf.h>
19 #include <sys/mbuf.h>
20 #include <sys/file.h>
21 #include <sys/disklabel.h>
22 #include <sys/ioctl.h>
23 #include <sys/errno.h>
24 #include <sys/malloc.h>
25 
26 #include <miscfs/specfs/specdev.h>
27 
28 #include <ufs/ufs/quota.h>
29 #include <ufs/ufs/ufsmount.h>
30 #include <ufs/ufs/inode.h>
31 #include <ufs/ufs/ufs_extern.h>
32 
33 #include <ufs/ffs/fs.h>
34 #include <ufs/ffs/ffs_extern.h>
35 
36 int ffs_sbupdate __P((struct ufsmount *, int));
37 
38 struct vfsops ufs_vfsops = {
39 	ffs_mount,
40 	ufs_start,
41 	ffs_unmount,
42 	ufs_root,
43 	ufs_quotactl,
44 	ffs_statfs,
45 	ffs_sync,
46 	ffs_vget,
47 	ffs_fhtovp,
48 	ffs_vptofh,
49 	ffs_init,
50 	ffs_sysctl,
51 };
52 
53 extern u_long nextgennumber;
54 
55 /*
56  * Called by main() when ufs is going to be mounted as root.
57  */
58 ffs_mountroot()
59 {
60 	extern struct vnode *rootvp;
61 	struct fs *fs;
62 	struct mount *mp;
63 	struct proc *p = curproc;	/* XXX */
64 	struct ufsmount *ump;
65 	u_int size;
66 	int error;
67 
68 	/*
69 	 * Get vnodes for swapdev and rootdev.
70 	 */
71 	if ((error = bdevvp(swapdev, &swapdev_vp)) ||
72 	    (error = bdevvp(rootdev, &rootvp))) {
73 		printf("ffs_mountroot: can't setup bdevvp's");
74 		return (error);
75 	}
76 	if (error = vfs_rootmountalloc("ufs", "root_device", &mp))
77 		return (error);
78 	if (error = ffs_mountfs(rootvp, mp, p)) {
79 		mp->mnt_vfc->vfc_refcount--;
80 		free(mp, M_MOUNT);
81 		return (error);
82 	}
83 	if (error = vfs_lock(mp)) {
84 		(void)ffs_unmount(mp, 0, p);
85 		mp->mnt_vfc->vfc_refcount--;
86 		free(mp, M_MOUNT);
87 		return (error);
88 	}
89 	CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
90 	ump = VFSTOUFS(mp);
91 	fs = ump->um_fs;
92 	(void) copystr(mp->mnt_stat.f_mntonname, fs->fs_fsmnt, MNAMELEN - 1, 0);
93 	(void)ffs_statfs(mp, &mp->mnt_stat, p);
94 	vfs_unlock(mp);
95 	inittodr(fs->fs_time);
96 	return (0);
97 }
98 
99 /*
100  * VFS Operations.
101  *
102  * mount system call
103  */
104 int
105 ffs_mount(mp, path, data, ndp, p)
106 	register struct mount *mp;
107 	char *path;
108 	caddr_t data;
109 	struct nameidata *ndp;
110 	struct proc *p;
111 {
112 	struct vnode *devvp;
113 	struct ufs_args args;
114 	struct ufsmount *ump;
115 	register struct fs *fs;
116 	u_int size;
117 	int error, flags;
118 	mode_t accessmode;
119 
120 	if (error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args)))
121 		return (error);
122 	/*
123 	 * If updating, check whether changing from read-only to
124 	 * read/write; if there is no device name, that's all we do.
125 	 */
126 	if (mp->mnt_flag & MNT_UPDATE) {
127 		ump = VFSTOUFS(mp);
128 		fs = ump->um_fs;
129 		if (fs->fs_ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) {
130 			flags = WRITECLOSE;
131 			if (mp->mnt_flag & MNT_FORCE)
132 				flags |= FORCECLOSE;
133 			if (vfs_busy(mp))
134 				return (EBUSY);
135 			if (error = ffs_flushfiles(mp, flags, p)) {
136 				vfs_unbusy(mp);
137 				return (error);
138 			}
139 			fs->fs_clean = 1;
140 			fs->fs_ronly = 1;
141 			if (error = ffs_sbupdate(ump, MNT_WAIT)) {
142 				fs->fs_clean = 0;
143 				fs->fs_ronly = 0;
144 				vfs_unbusy(mp);
145 				return (error);
146 			}
147 			vfs_unbusy(mp);
148 		}
149 		if ((mp->mnt_flag & MNT_RELOAD) &&
150 		    (error = ffs_reload(mp, ndp->ni_cnd.cn_cred, p)))
151 			return (error);
152 		if (fs->fs_ronly && (mp->mnt_flag & MNT_WANTRDWR)) {
153 			/*
154 			 * If upgrade to read-write by non-root, then verify
155 			 * that user has necessary permissions on the device.
156 			 */
157 			if (p->p_ucred->cr_uid != 0) {
158 				devvp = ump->um_devvp;
159 				vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
160 				if (error = VOP_ACCESS(devvp, VREAD | VWRITE,
161 				    p->p_ucred, p)) {
162 					VOP_UNLOCK(devvp, 0, p);
163 					return (error);
164 				}
165 				VOP_UNLOCK(devvp, 0, p);
166 			}
167 			fs->fs_ronly = 0;
168 			fs->fs_clean = 0;
169 			(void) ffs_sbupdate(ump, MNT_WAIT);
170 		}
171 		if (args.fspec == 0) {
172 			/*
173 			 * Process export requests.
174 			 */
175 			return (vfs_export(mp, &ump->um_export, &args.export));
176 		}
177 	}
178 	/*
179 	 * Not an update, or updating the name: look up the name
180 	 * and verify that it refers to a sensible block device.
181 	 */
182 	NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, p);
183 	if (error = namei(ndp))
184 		return (error);
185 	devvp = ndp->ni_vp;
186 
187 	if (devvp->v_type != VBLK) {
188 		vrele(devvp);
189 		return (ENOTBLK);
190 	}
191 	if (major(devvp->v_rdev) >= nblkdev) {
192 		vrele(devvp);
193 		return (ENXIO);
194 	}
195 	/*
196 	 * If mount by non-root, then verify that user has necessary
197 	 * permissions on the device.
198 	 */
199 	if (p->p_ucred->cr_uid != 0) {
200 		accessmode = VREAD;
201 		if ((mp->mnt_flag & MNT_RDONLY) == 0)
202 			accessmode |= VWRITE;
203 		vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
204 		if (error = VOP_ACCESS(devvp, accessmode, p->p_ucred, p)) {
205 			vput(devvp);
206 			return (error);
207 		}
208 		VOP_UNLOCK(devvp, 0, p);
209 	}
210 	if ((mp->mnt_flag & MNT_UPDATE) == 0)
211 		error = ffs_mountfs(devvp, mp, p);
212 	else {
213 		if (devvp != ump->um_devvp)
214 			error = EINVAL;	/* needs translation */
215 		else
216 			vrele(devvp);
217 	}
218 	if (error) {
219 		vrele(devvp);
220 		return (error);
221 	}
222 	ump = VFSTOUFS(mp);
223 	fs = ump->um_fs;
224 	(void) copyinstr(path, fs->fs_fsmnt, sizeof(fs->fs_fsmnt) - 1, &size);
225 	bzero(fs->fs_fsmnt + size, sizeof(fs->fs_fsmnt) - size);
226 	bcopy((caddr_t)fs->fs_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname,
227 	    MNAMELEN);
228 	(void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
229 	    &size);
230 	bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
231 	(void)ffs_statfs(mp, &mp->mnt_stat, p);
232 	return (0);
233 }
234 
235 /*
236  * Reload all incore data for a filesystem (used after running fsck on
237  * the root filesystem and finding things to fix). The filesystem must
238  * be mounted read-only.
239  *
240  * Things to do to update the mount:
241  *	1) invalidate all cached meta-data.
242  *	2) re-read superblock from disk.
243  *	3) re-read summary information from disk.
244  *	4) invalidate all inactive vnodes.
245  *	5) invalidate all cached file data.
246  *	6) re-read inode data for all active vnodes.
247  */
248 ffs_reload(mountp, cred, p)
249 	register struct mount *mountp;
250 	struct ucred *cred;
251 	struct proc *p;
252 {
253 	register struct vnode *vp, *nvp, *devvp;
254 	struct inode *ip;
255 	struct csum *space;
256 	struct buf *bp;
257 	struct fs *fs, *newfs;
258 	struct partinfo dpart;
259 	int i, blks, size, error;
260 	int32_t *lp;
261 
262 	if ((mountp->mnt_flag & MNT_RDONLY) == 0)
263 		return (EINVAL);
264 	/*
265 	 * Step 1: invalidate all cached meta-data.
266 	 */
267 	devvp = VFSTOUFS(mountp)->um_devvp;
268 	if (vinvalbuf(devvp, 0, cred, p, 0, 0))
269 		panic("ffs_reload: dirty1");
270 	/*
271 	 * Step 2: re-read superblock from disk.
272 	 */
273 	if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, NOCRED, p) != 0)
274 		size = DEV_BSIZE;
275 	else
276 		size = dpart.disklab->d_secsize;
277 	if (error = bread(devvp, (ufs_daddr_t)(SBOFF/size), SBSIZE, NOCRED,&bp))
278 		return (error);
279 	newfs = (struct fs *)bp->b_data;
280 	if (newfs->fs_magic != FS_MAGIC || newfs->fs_bsize > MAXBSIZE ||
281 	    newfs->fs_bsize < sizeof(struct fs)) {
282 		brelse(bp);
283 		return (EIO);		/* XXX needs translation */
284 	}
285 	fs = VFSTOUFS(mountp)->um_fs;
286 	/*
287 	 * Copy pointer fields back into superblock before copying in	XXX
288 	 * new superblock. These should really be in the ufsmount.	XXX
289 	 * Note that important parameters (eg fs_ncg) are unchanged.
290 	 */
291 	bcopy(&fs->fs_csp[0], &newfs->fs_csp[0], sizeof(fs->fs_csp));
292 	newfs->fs_maxcluster = fs->fs_maxcluster;
293 	bcopy(newfs, fs, (u_int)fs->fs_sbsize);
294 	if (fs->fs_sbsize < SBSIZE)
295 		bp->b_flags |= B_INVAL;
296 	brelse(bp);
297 	mountp->mnt_maxsymlinklen = fs->fs_maxsymlinklen;
298 	ffs_oldfscompat(fs);
299 	/*
300 	 * Step 3: re-read summary information from disk.
301 	 */
302 	blks = howmany(fs->fs_cssize, fs->fs_fsize);
303 	space = fs->fs_csp[0];
304 	for (i = 0; i < blks; i += fs->fs_frag) {
305 		size = fs->fs_bsize;
306 		if (i + fs->fs_frag > blks)
307 			size = (blks - i) * fs->fs_fsize;
308 		if (error = bread(devvp, fsbtodb(fs, fs->fs_csaddr + i), size,
309 		    NOCRED, &bp))
310 			return (error);
311 		bcopy(bp->b_data, fs->fs_csp[fragstoblks(fs, i)], (u_int)size);
312 		brelse(bp);
313 	}
314 	/*
315 	 * We no longer know anything about clusters per cylinder group.
316 	 */
317 	if (fs->fs_contigsumsize > 0) {
318 		lp = fs->fs_maxcluster;
319 		for (i = 0; i < fs->fs_ncg; i++)
320 			*lp++ = fs->fs_contigsumsize;
321 	}
322 
323 loop:
324 	simple_lock(&mntvnode_slock);
325 	for (vp = mountp->mnt_vnodelist.lh_first; vp != NULL; vp = nvp) {
326 		if (vp->v_mount != mountp) {
327 			simple_unlock(&mntvnode_slock);
328 			goto loop;
329 		}
330 		nvp = vp->v_mntvnodes.le_next;
331 		/*
332 		 * Step 4: invalidate all inactive vnodes.
333 		 */
334 		if (vrecycle(vp, &mntvnode_slock, p))
335 			goto loop;
336 		/*
337 		 * Step 5: invalidate all cached file data.
338 		 */
339 		simple_lock(&vp->v_interlock);
340 		simple_unlock(&mntvnode_slock);
341 		if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, p)) {
342 			goto loop;
343 		}
344 		if (vinvalbuf(vp, 0, cred, p, 0, 0))
345 			panic("ffs_reload: dirty2");
346 		/*
347 		 * Step 6: re-read inode data for all active vnodes.
348 		 */
349 		ip = VTOI(vp);
350 		if (error =
351 		    bread(devvp, fsbtodb(fs, ino_to_fsba(fs, ip->i_number)),
352 		    (int)fs->fs_bsize, NOCRED, &bp)) {
353 			vput(vp);
354 			return (error);
355 		}
356 		ip->i_din = *((struct dinode *)bp->b_data +
357 		    ino_to_fsbo(fs, ip->i_number));
358 		brelse(bp);
359 		vput(vp);
360 		simple_lock(&mntvnode_slock);
361 	}
362 	simple_unlock(&mntvnode_slock);
363 	return (0);
364 }
365 
366 /*
367  * Common code for mount and mountroot
368  */
369 int
370 ffs_mountfs(devvp, mp, p)
371 	register struct vnode *devvp;
372 	struct mount *mp;
373 	struct proc *p;
374 {
375 	register struct ufsmount *ump;
376 	struct buf *bp;
377 	register struct fs *fs;
378 	dev_t dev;
379 	struct partinfo dpart;
380 	caddr_t base, space;
381 	int error, i, blks, size, ronly;
382 	int32_t *lp;
383 	struct ucred *cred;
384 	extern struct vnode *rootvp;
385 	u_int64_t maxfilesize;					/* XXX */
386 
387 	dev = devvp->v_rdev;
388 	cred = p ? p->p_ucred : NOCRED;
389 	/*
390 	 * Disallow multiple mounts of the same device.
391 	 * Disallow mounting of a device that is currently in use
392 	 * (except for root, which might share swap device for miniroot).
393 	 * Flush out any old buffers remaining from a previous use.
394 	 */
395 	if (error = vfs_mountedon(devvp))
396 		return (error);
397 	if (vcount(devvp) > 1 && devvp != rootvp)
398 		return (EBUSY);
399 	if (error = vinvalbuf(devvp, V_SAVE, cred, p, 0, 0))
400 		return (error);
401 
402 	ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
403 	if (error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, p))
404 		return (error);
405 	if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, cred, p) != 0)
406 		size = DEV_BSIZE;
407 	else
408 		size = dpart.disklab->d_secsize;
409 
410 	bp = NULL;
411 	ump = NULL;
412 	if (error = bread(devvp, (ufs_daddr_t)(SBOFF/size), SBSIZE, cred, &bp))
413 		goto out;
414 	fs = (struct fs *)bp->b_data;
415 	if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE ||
416 	    fs->fs_bsize < sizeof(struct fs)) {
417 		error = EINVAL;		/* XXX needs translation */
418 		goto out;
419 	}
420 	/* XXX updating 4.2 FFS superblocks trashes rotational layout tables */
421 	if (fs->fs_postblformat == FS_42POSTBLFMT && !ronly) {
422 		error = EROFS;          /* needs translation */
423 		goto out;
424 	}
425 	ump = malloc(sizeof *ump, M_UFSMNT, M_WAITOK);
426 	bzero((caddr_t)ump, sizeof *ump);
427 	ump->um_fs = malloc((u_long)fs->fs_sbsize, M_UFSMNT,
428 	    M_WAITOK);
429 	bcopy(bp->b_data, ump->um_fs, (u_int)fs->fs_sbsize);
430 	if (fs->fs_sbsize < SBSIZE)
431 		bp->b_flags |= B_INVAL;
432 	brelse(bp);
433 	bp = NULL;
434 	fs = ump->um_fs;
435 	fs->fs_ronly = ronly;
436 	size = fs->fs_cssize;
437 	blks = howmany(size, fs->fs_fsize);
438 	if (fs->fs_contigsumsize > 0)
439 		size += fs->fs_ncg * sizeof(int32_t);
440 	base = space = malloc((u_long)size, M_UFSMNT, M_WAITOK);
441 	for (i = 0; i < blks; i += fs->fs_frag) {
442 		size = fs->fs_bsize;
443 		if (i + fs->fs_frag > blks)
444 			size = (blks - i) * fs->fs_fsize;
445 		if (error = bread(devvp, fsbtodb(fs, fs->fs_csaddr + i), size,
446 		    cred, &bp)) {
447 			free(base, M_UFSMNT);
448 			goto out;
449 		}
450 		bcopy(bp->b_data, space, (u_int)size);
451 		fs->fs_csp[fragstoblks(fs, i)] = (struct csum *)space;
452 		space += size;
453 		brelse(bp);
454 		bp = NULL;
455 	}
456 	if (fs->fs_contigsumsize > 0) {
457 		fs->fs_maxcluster = lp = (int32_t *)space;
458 		for (i = 0; i < fs->fs_ncg; i++)
459 			*lp++ = fs->fs_contigsumsize;
460 	}
461 	mp->mnt_data = (qaddr_t)ump;
462 	mp->mnt_stat.f_fsid.val[0] = (long)dev;
463 	mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
464 	mp->mnt_maxsymlinklen = fs->fs_maxsymlinklen;
465 	ump->um_mountp = mp;
466 	ump->um_dev = dev;
467 	ump->um_devvp = devvp;
468 	ump->um_nindir = fs->fs_nindir;
469 	ump->um_bptrtodb = fs->fs_fsbtodb;
470 	ump->um_seqinc = fs->fs_frag;
471 	for (i = 0; i < MAXQUOTAS; i++)
472 		ump->um_quotas[i] = NULLVP;
473 	devvp->v_specflags |= SI_MOUNTEDON;
474 	ffs_oldfscompat(fs);
475 	ump->um_savedmaxfilesize = fs->fs_maxfilesize;		/* XXX */
476 	maxfilesize = (u_int64_t)0x40000000 * fs->fs_bsize - 1;	/* XXX */
477 	if (fs->fs_maxfilesize > maxfilesize)			/* XXX */
478 		fs->fs_maxfilesize = maxfilesize;		/* XXX */
479 	if (ronly == 0) {
480 		fs->fs_clean = 0;
481 		(void) ffs_sbupdate(ump, MNT_WAIT);
482 	}
483 	return (0);
484 out:
485 	if (bp)
486 		brelse(bp);
487 	(void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, cred, p);
488 	if (ump) {
489 		free(ump->um_fs, M_UFSMNT);
490 		free(ump, M_UFSMNT);
491 		mp->mnt_data = (qaddr_t)0;
492 	}
493 	return (error);
494 }
495 
496 /*
497  * Sanity checks for old file systems.
498  *
499  * XXX - goes away some day.
500  */
501 ffs_oldfscompat(fs)
502 	struct fs *fs;
503 {
504 	int i;
505 
506 	fs->fs_npsect = max(fs->fs_npsect, fs->fs_nsect);	/* XXX */
507 	fs->fs_interleave = max(fs->fs_interleave, 1);		/* XXX */
508 	if (fs->fs_postblformat == FS_42POSTBLFMT)		/* XXX */
509 		fs->fs_nrpos = 8;				/* XXX */
510 	if (fs->fs_inodefmt < FS_44INODEFMT) {			/* XXX */
511 		u_int64_t sizepb = fs->fs_bsize;		/* XXX */
512 								/* XXX */
513 		fs->fs_maxfilesize = fs->fs_bsize * NDADDR - 1;	/* XXX */
514 		for (i = 0; i < NIADDR; i++) {			/* XXX */
515 			sizepb *= NINDIR(fs);			/* XXX */
516 			fs->fs_maxfilesize += sizepb;		/* XXX */
517 		}						/* XXX */
518 		fs->fs_qbmask = ~fs->fs_bmask;			/* XXX */
519 		fs->fs_qfmask = ~fs->fs_fmask;			/* XXX */
520 	}							/* XXX */
521 	return (0);
522 }
523 
524 /*
525  * unmount system call
526  */
527 int
528 ffs_unmount(mp, mntflags, p)
529 	struct mount *mp;
530 	int mntflags;
531 	struct proc *p;
532 {
533 	register struct ufsmount *ump;
534 	register struct fs *fs;
535 	int error, flags;
536 
537 	flags = 0;
538 	if (mntflags & MNT_FORCE)
539 		flags |= FORCECLOSE;
540 	if (error = ffs_flushfiles(mp, flags, p))
541 		return (error);
542 	ump = VFSTOUFS(mp);
543 	fs = ump->um_fs;
544 	if (fs->fs_ronly == 0) {
545 		fs->fs_clean = 1;
546 		if (error = ffs_sbupdate(ump, MNT_WAIT)) {
547 			fs->fs_clean = 0;
548 			return (error);
549 		}
550 	}
551 	ump->um_devvp->v_specflags &= ~SI_MOUNTEDON;
552 	error = VOP_CLOSE(ump->um_devvp, fs->fs_ronly ? FREAD : FREAD|FWRITE,
553 		NOCRED, p);
554 	vrele(ump->um_devvp);
555 	free(fs->fs_csp[0], M_UFSMNT);
556 	free(fs, M_UFSMNT);
557 	free(ump, M_UFSMNT);
558 	mp->mnt_data = (qaddr_t)0;
559 	return (error);
560 }
561 
562 /*
563  * Flush out all the files in a filesystem.
564  */
565 ffs_flushfiles(mp, flags, p)
566 	register struct mount *mp;
567 	int flags;
568 	struct proc *p;
569 {
570 	register struct ufsmount *ump;
571 	int i, error;
572 
573 	ump = VFSTOUFS(mp);
574 #ifdef QUOTA
575 	if (mp->mnt_flag & MNT_QUOTA) {
576 		if (error = vflush(mp, NULLVP, SKIPSYSTEM|flags))
577 			return (error);
578 		for (i = 0; i < MAXQUOTAS; i++) {
579 			if (ump->um_quotas[i] == NULLVP)
580 				continue;
581 			quotaoff(p, mp, i);
582 		}
583 		/*
584 		 * Here we fall through to vflush again to ensure
585 		 * that we have gotten rid of all the system vnodes.
586 		 */
587 	}
588 #endif
589 	error = vflush(mp, NULLVP, flags);
590 	return (error);
591 }
592 
593 /*
594  * Get file system statistics.
595  */
596 int
597 ffs_statfs(mp, sbp, p)
598 	struct mount *mp;
599 	register struct statfs *sbp;
600 	struct proc *p;
601 {
602 	register struct ufsmount *ump;
603 	register struct fs *fs;
604 
605 	ump = VFSTOUFS(mp);
606 	fs = ump->um_fs;
607 	if (fs->fs_magic != FS_MAGIC)
608 		panic("ffs_statfs");
609 	sbp->f_bsize = fs->fs_fsize;
610 	sbp->f_iosize = fs->fs_bsize;
611 	sbp->f_blocks = fs->fs_dsize;
612 	sbp->f_bfree = fs->fs_cstotal.cs_nbfree * fs->fs_frag +
613 		fs->fs_cstotal.cs_nffree;
614 	sbp->f_bavail = (fs->fs_dsize * (100 - fs->fs_minfree) / 100) -
615 		(fs->fs_dsize - sbp->f_bfree);
616 	sbp->f_files =  fs->fs_ncg * fs->fs_ipg - ROOTINO;
617 	sbp->f_ffree = fs->fs_cstotal.cs_nifree;
618 	if (sbp != &mp->mnt_stat) {
619 		sbp->f_type = mp->mnt_vfc->vfc_typenum;
620 		bcopy((caddr_t)mp->mnt_stat.f_mntonname,
621 			(caddr_t)&sbp->f_mntonname[0], MNAMELEN);
622 		bcopy((caddr_t)mp->mnt_stat.f_mntfromname,
623 			(caddr_t)&sbp->f_mntfromname[0], MNAMELEN);
624 	}
625 	return (0);
626 }
627 
628 /*
629  * Go through the disk queues to initiate sandbagged IO;
630  * go through the inodes to write those that have been modified;
631  * initiate the writing of the super block if it has been modified.
632  *
633  * Note: we are always called with the filesystem marked `MPBUSY'.
634  */
635 int
636 ffs_sync(mp, waitfor, cred, p)
637 	struct mount *mp;
638 	int waitfor;
639 	struct ucred *cred;
640 	struct proc *p;
641 {
642 	struct vnode *nvp, *vp;
643 	struct inode *ip;
644 	struct ufsmount *ump = VFSTOUFS(mp);
645 	struct fs *fs;
646 	int error, allerror = 0;
647 
648 	fs = ump->um_fs;
649 	if (fs->fs_fmod != 0 && fs->fs_ronly != 0) {		/* XXX */
650 		printf("fs = %s\n", fs->fs_fsmnt);
651 		panic("update: rofs mod");
652 	}
653 	/*
654 	 * Write back each (modified) inode.
655 	 */
656 	simple_lock(&mntvnode_slock);
657 loop:
658 	for (vp = mp->mnt_vnodelist.lh_first;
659 	     vp != NULL;
660 	     vp = nvp) {
661 		/*
662 		 * If the vnode that we are about to sync is no longer
663 		 * associated with this mount point, start over.
664 		 */
665 		if (vp->v_mount != mp)
666 			goto loop;
667 		simple_lock(&vp->v_interlock);
668 		nvp = vp->v_mntvnodes.le_next;
669 		ip = VTOI(vp);
670 		if ((ip->i_flag &
671 		    (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 &&
672 		    vp->v_dirtyblkhd.lh_first == NULL) {
673 			simple_unlock(&vp->v_interlock);
674 			continue;
675 		}
676 		simple_unlock(&mntvnode_slock);
677 		error = vget(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK, p);
678 		if (error) {
679 			vrele(vp);
680 			simple_lock(&mntvnode_slock);
681 			if (error == ENOENT)
682 				goto loop;
683 			continue;
684 		}
685 		if (error = VOP_FSYNC(vp, cred, waitfor, p))
686 			allerror = error;
687 		VOP_UNLOCK(vp, 0, p);
688 		vrele(vp);
689 		simple_lock(&mntvnode_slock);
690 	}
691 	simple_unlock(&mntvnode_slock);
692 	/*
693 	 * Force stale file system control information to be flushed.
694 	 */
695 	if (error = VOP_FSYNC(ump->um_devvp, cred, waitfor, p))
696 		allerror = error;
697 #ifdef QUOTA
698 	qsync(mp);
699 #endif
700 	/*
701 	 * Write back modified superblock.
702 	 */
703 	if (fs->fs_fmod != 0) {
704 		fs->fs_fmod = 0;
705 		fs->fs_time = time.tv_sec;
706 		if (error = ffs_sbupdate(ump, waitfor))
707 			allerror = error;
708 	}
709 	return (allerror);
710 }
711 
712 /*
713  * Look up a FFS dinode number to find its incore vnode, otherwise read it
714  * in from disk.  If it is in core, wait for the lock bit to clear, then
715  * return the inode locked.  Detection and handling of mount points must be
716  * done by the calling routine.
717  */
718 int
719 ffs_vget(mp, ino, vpp)
720 	struct mount *mp;
721 	ino_t ino;
722 	struct vnode **vpp;
723 {
724 	struct proc *p = curproc;		/* XXX */
725 	struct fs *fs;
726 	struct inode *ip;
727 	struct ufsmount *ump;
728 	struct buf *bp;
729 	struct vnode *vp;
730 	dev_t dev;
731 	int i, type, error;
732 
733 	ump = VFSTOUFS(mp);
734 	dev = ump->um_dev;
735 	if ((*vpp = ufs_ihashget(dev, ino)) != NULL)
736 		return (0);
737 
738 	/* Allocate a new vnode/inode. */
739 	if (error = getnewvnode(VT_UFS, mp, ffs_vnodeop_p, &vp)) {
740 		*vpp = NULL;
741 		return (error);
742 	}
743 	type = ump->um_devvp->v_tag == VT_MFS ? M_MFSNODE : M_FFSNODE; /* XXX */
744 	MALLOC(ip, struct inode *, sizeof(struct inode), type, M_WAITOK);
745 	bzero((caddr_t)ip, sizeof(struct inode));
746 	lockinit(&ip->i_lock, PINOD, "inode", 0, 0);
747 	vp->v_data = ip;
748 	ip->i_vnode = vp;
749 	ip->i_fs = fs = ump->um_fs;
750 	ip->i_dev = dev;
751 	ip->i_number = ino;
752 #ifdef QUOTA
753 	for (i = 0; i < MAXQUOTAS; i++)
754 		ip->i_dquot[i] = NODQUOT;
755 #endif
756 	/*
757 	 * Put it onto its hash chain and lock it so that other requests for
758 	 * this inode will block if they arrive while we are sleeping waiting
759 	 * for old data structures to be purged or for the contents of the
760 	 * disk portion of this inode to be read.
761 	 */
762 	ufs_ihashins(ip);
763 
764 	/* Read in the disk contents for the inode, copy into the inode. */
765 	if (error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)),
766 	    (int)fs->fs_bsize, NOCRED, &bp)) {
767 		/*
768 		 * The inode does not contain anything useful, so it would
769 		 * be misleading to leave it on its hash chain. With mode
770 		 * still zero, it will be unlinked and returned to the free
771 		 * list by vput().
772 		 */
773 		vput(vp);
774 		brelse(bp);
775 		*vpp = NULL;
776 		return (error);
777 	}
778 	ip->i_din = *((struct dinode *)bp->b_data + ino_to_fsbo(fs, ino));
779 	brelse(bp);
780 
781 	/*
782 	 * Initialize the vnode from the inode, check for aliases.
783 	 * Note that the underlying vnode may have changed.
784 	 */
785 	if (error = ufs_vinit(mp, ffs_specop_p, FFS_FIFOOPS, &vp)) {
786 		vput(vp);
787 		*vpp = NULL;
788 		return (error);
789 	}
790 	/*
791 	 * Finish inode initialization now that aliasing has been resolved.
792 	 */
793 	ip->i_devvp = ump->um_devvp;
794 	VREF(ip->i_devvp);
795 	/*
796 	 * Set up a generation number for this inode if it does not
797 	 * already have one. This should only happen on old filesystems.
798 	 */
799 	if (ip->i_gen == 0) {
800 		if (++nextgennumber < (u_long)time.tv_sec)
801 			nextgennumber = time.tv_sec;
802 		ip->i_gen = nextgennumber;
803 		if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0)
804 			ip->i_flag |= IN_MODIFIED;
805 	}
806 	/*
807 	 * Ensure that uid and gid are correct. This is a temporary
808 	 * fix until fsck has been changed to do the update.
809 	 */
810 	if (fs->fs_inodefmt < FS_44INODEFMT) {		/* XXX */
811 		ip->i_uid = ip->i_din.di_ouid;		/* XXX */
812 		ip->i_gid = ip->i_din.di_ogid;		/* XXX */
813 	}						/* XXX */
814 
815 	*vpp = vp;
816 	return (0);
817 }
818 
819 /*
820  * File handle to vnode
821  *
822  * Have to be really careful about stale file handles:
823  * - check that the inode number is valid
824  * - call ffs_vget() to get the locked inode
825  * - check for an unallocated inode (i_mode == 0)
826  * - check that the given client host has export rights and return
827  *   those rights via. exflagsp and credanonp
828  */
829 int
830 ffs_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp)
831 	register struct mount *mp;
832 	struct fid *fhp;
833 	struct mbuf *nam;
834 	struct vnode **vpp;
835 	int *exflagsp;
836 	struct ucred **credanonp;
837 {
838 	register struct ufid *ufhp;
839 	struct fs *fs;
840 
841 	ufhp = (struct ufid *)fhp;
842 	fs = VFSTOUFS(mp)->um_fs;
843 	if (ufhp->ufid_ino < ROOTINO ||
844 	    ufhp->ufid_ino >= fs->fs_ncg * fs->fs_ipg)
845 		return (ESTALE);
846 	return (ufs_check_export(mp, ufhp, nam, vpp, exflagsp, credanonp));
847 }
848 
849 /*
850  * Vnode pointer to File handle
851  */
852 /* ARGSUSED */
853 ffs_vptofh(vp, fhp)
854 	struct vnode *vp;
855 	struct fid *fhp;
856 {
857 	register struct inode *ip;
858 	register struct ufid *ufhp;
859 
860 	ip = VTOI(vp);
861 	ufhp = (struct ufid *)fhp;
862 	ufhp->ufid_len = sizeof(struct ufid);
863 	ufhp->ufid_ino = ip->i_number;
864 	ufhp->ufid_gen = ip->i_gen;
865 	return (0);
866 }
867 
868 /*
869  * Initialize the filesystem; just use ufs_init.
870  */
871 int
872 ffs_init(vfsp)
873 	struct vfsconf *vfsp;
874 {
875 
876 	return (ufs_init(vfsp));
877 }
878 
879 /*
880  * fast filesystem related variables.
881  */
882 ffs_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
883 	int *name;
884 	u_int namelen;
885 	void *oldp;
886 	size_t *oldlenp;
887 	void *newp;
888 	size_t newlen;
889 	struct proc *p;
890 {
891 	extern int doclusterread, doclusterwrite, doreallocblks, doasyncfree;
892 
893 	/* all sysctl names at this level are terminal */
894 	if (namelen != 1)
895 		return (ENOTDIR);		/* overloaded */
896 
897 	switch (name[0]) {
898 	case FFS_CLUSTERREAD:
899 		return (sysctl_int(oldp, oldlenp, newp, newlen,
900 		    &doclusterread));
901 	case FFS_CLUSTERWRITE:
902 		return (sysctl_int(oldp, oldlenp, newp, newlen,
903 		    &doclusterwrite));
904 	case FFS_REALLOCBLKS:
905 		return (sysctl_int(oldp, oldlenp, newp, newlen,
906 		    &doreallocblks));
907 	case FFS_ASYNCFREE:
908 		return (sysctl_int(oldp, oldlenp, newp, newlen, &doasyncfree));
909 	default:
910 		return (EOPNOTSUPP);
911 	}
912 	/* NOTREACHED */
913 }
914 
915 /*
916  * Write a superblock and associated information back to disk.
917  */
918 int
919 ffs_sbupdate(mp, waitfor)
920 	struct ufsmount *mp;
921 	int waitfor;
922 {
923 	register struct fs *dfs, *fs = mp->um_fs;
924 	register struct buf *bp;
925 	int blks;
926 	caddr_t space;
927 	int i, size, error, allerror = 0;
928 
929 	/*
930 	 * First write back the summary information.
931 	 */
932 	blks = howmany(fs->fs_cssize, fs->fs_fsize);
933 	space = (caddr_t)fs->fs_csp[0];
934 	for (i = 0; i < blks; i += fs->fs_frag) {
935 		size = fs->fs_bsize;
936 		if (i + fs->fs_frag > blks)
937 			size = (blks - i) * fs->fs_fsize;
938 		bp = getblk(mp->um_devvp, fsbtodb(fs, fs->fs_csaddr + i),
939 		    size, 0, 0);
940 		bcopy(space, bp->b_data, (u_int)size);
941 		space += size;
942 		if (waitfor != MNT_WAIT)
943 			bawrite(bp);
944 		else if (error = bwrite(bp))
945 			allerror = error;
946 	}
947 	/*
948 	 * Now write back the superblock itself. If any errors occurred
949 	 * up to this point, then fail so that the superblock avoids
950 	 * being written out as clean.
951 	 */
952 	if (allerror)
953 		return (allerror);
954 	bp = getblk(mp->um_devvp, SBLOCK, (int)fs->fs_sbsize, 0, 0);
955 	bcopy((caddr_t)fs, bp->b_data, (u_int)fs->fs_sbsize);
956 	/* Restore compatibility to old file systems.		   XXX */
957 	dfs = (struct fs *)bp->b_data;				/* XXX */
958 	if (fs->fs_postblformat == FS_42POSTBLFMT)		/* XXX */
959 		dfs->fs_nrpos = -1;				/* XXX */
960 	if (fs->fs_inodefmt < FS_44INODEFMT) {			/* XXX */
961 		int32_t *lp, tmp;				/* XXX */
962 								/* XXX */
963 		lp = (int32_t *)&dfs->fs_qbmask;		/* XXX */
964 		tmp = lp[4];					/* XXX */
965 		for (i = 4; i > 0; i--)				/* XXX */
966 			lp[i] = lp[i-1];			/* XXX */
967 		lp[0] = tmp;					/* XXX */
968 	}							/* XXX */
969 	dfs->fs_maxfilesize = mp->um_savedmaxfilesize;		/* XXX */
970 	if (waitfor != MNT_WAIT)
971 		bawrite(bp);
972 	else if (error = bwrite(bp))
973 		allerror = error;
974 	return (allerror);
975 }
976