ffs_vfsops.c revision 66617
1/*
2 * Copyright (c) 1989, 1991, 1993, 1994
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 *    must display the following acknowledgement:
15 *	This product includes software developed by the University of
16 *	California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 *	@(#)ffs_vfsops.c	8.31 (Berkeley) 5/20/95
34 * $FreeBSD: head/sys/ufs/ffs/ffs_vfsops.c 66617 2000-10-04 04:44:51Z rwatson $
35 */
36
37#include "opt_ffs.h"
38#include "opt_quota.h"
39
40#include <sys/param.h>
41#include <sys/systm.h>
42#include <sys/namei.h>
43#include <sys/proc.h>
44#include <sys/kernel.h>
45#include <sys/vnode.h>
46#include <sys/mount.h>
47#include <sys/bio.h>
48#include <sys/buf.h>
49#include <sys/conf.h>
50#include <sys/fcntl.h>
51#include <sys/disklabel.h>
52#include <sys/malloc.h>
53
54#include <machine/mutex.h>
55
56#include <ufs/ufs/extattr.h>
57#include <ufs/ufs/quota.h>
58#include <ufs/ufs/ufsmount.h>
59#include <ufs/ufs/inode.h>
60#include <ufs/ufs/ufs_extern.h>
61
62#include <ufs/ffs/fs.h>
63#include <ufs/ffs/ffs_extern.h>
64
65#include <vm/vm.h>
66#include <vm/vm_page.h>
67
68static MALLOC_DEFINE(M_FFSNODE, "FFS node", "FFS vnode private part");
69
70static int	ffs_sbupdate __P((struct ufsmount *, int));
71static int	ffs_reload __P((struct mount *,struct ucred *,struct proc *));
72static int	ffs_oldfscompat __P((struct fs *));
73static int	ffs_mount __P((struct mount *, char *, caddr_t,
74				struct nameidata *, struct proc *));
75static int	ffs_init __P((struct vfsconf *));
76
77static struct vfsops ufs_vfsops = {
78	ffs_mount,
79	ufs_start,
80	ffs_unmount,
81	ufs_root,
82	ufs_quotactl,
83	ffs_statfs,
84	ffs_sync,
85	ffs_vget,
86	ffs_fhtovp,
87	ufs_check_export,
88	ffs_vptofh,
89	ffs_init,
90	vfs_stduninit,
91#ifdef FFS_EXTATTR
92	ufs_extattrctl,
93#else
94	vfs_stdextattrctl,
95#endif
96};
97
98VFS_SET(ufs_vfsops, ufs, 0);
99
100/*
101 * ffs_mount
102 *
103 * Called when mounting local physical media
104 *
105 * PARAMETERS:
106 *		mountroot
107 *			mp	mount point structure
108 *			path	NULL (flag for root mount!!!)
109 *			data	<unused>
110 *			ndp	<unused>
111 *			p	process (user credentials check [statfs])
112 *
113 *		mount
114 *			mp	mount point structure
115 *			path	path to mount point
116 *			data	pointer to argument struct in user space
117 *			ndp	mount point namei() return (used for
118 *				credentials on reload), reused to look
119 *				up block device.
120 *			p	process (user credentials check)
121 *
122 * RETURNS:	0	Success
123 *		!0	error number (errno.h)
124 *
125 * LOCK STATE:
126 *
127 *		ENTRY
128 *			mount point is locked
129 *		EXIT
130 *			mount point is locked
131 *
132 * NOTES:
133 *		A NULL path can be used for a flag since the mount
134 *		system call will fail with EFAULT in copyinstr in
135 *		namei() if it is a genuine NULL from the user.
136 */
137static int
138ffs_mount(mp, path, data, ndp, p)
139        struct mount		*mp;	/* mount struct pointer*/
140        char			*path;	/* path to mount point*/
141        caddr_t			data;	/* arguments to FS specific mount*/
142        struct nameidata	*ndp;	/* mount point credentials*/
143        struct proc		*p;	/* process requesting mount*/
144{
145	size_t		size;
146	struct vnode	*devvp;
147	struct ufs_args args;
148	struct ufsmount *ump = 0;
149	register struct fs *fs;
150	int error, flags;
151	mode_t accessmode;
152
153	/*
154	 * Use NULL path to indicate we are mounting the root file system.
155	 */
156	if (path == NULL) {
157		if ((error = bdevvp(rootdev, &rootvp))) {
158			printf("ffs_mountroot: can't find rootvp\n");
159			return (error);
160		}
161
162		if ((error = ffs_mountfs(rootvp, mp, p, M_FFSNODE)) != 0)
163			return (error);
164
165		(void)VFS_STATFS(mp, &mp->mnt_stat, p);
166		return (0);
167	}
168
169	/*
170	 * Mounting non-root file system or updating a file system
171	 */
172	if ((error = copyin(data, (caddr_t)&args, sizeof(struct ufs_args)))!= 0)
173		return (error);
174
175	/*
176	 * If updating, check whether changing from read-only to
177	 * read/write; if there is no device name, that's all we do.
178	 */
179	if (mp->mnt_flag & MNT_UPDATE) {
180		ump = VFSTOUFS(mp);
181		fs = ump->um_fs;
182		devvp = ump->um_devvp;
183		if (fs->fs_ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) {
184			if ((error = vn_start_write(NULL, &mp, V_WAIT)) != 0)
185				return (error);
186			flags = WRITECLOSE;
187			if (mp->mnt_flag & MNT_FORCE)
188				flags |= FORCECLOSE;
189			if (mp->mnt_flag & MNT_SOFTDEP) {
190				error = softdep_flushfiles(mp, flags, p);
191			} else {
192				error = ffs_flushfiles(mp, flags, p);
193			}
194			if (error) {
195				vn_finished_write(mp);
196				return (error);
197			}
198			fs->fs_ronly = 1;
199			if ((fs->fs_flags & FS_UNCLEAN) == 0)
200				fs->fs_clean = 1;
201			if ((error = ffs_sbupdate(ump, MNT_WAIT)) != 0) {
202				fs->fs_ronly = 0;
203				fs->fs_clean = 0;
204				vn_finished_write(mp);
205				return (error);
206			}
207			vn_finished_write(mp);
208		}
209		if ((mp->mnt_flag & MNT_RELOAD) &&
210		    (error = ffs_reload(mp, ndp->ni_cnd.cn_cred, p)) != 0)
211			return (error);
212		if (fs->fs_ronly && (mp->mnt_kern_flag & MNTK_WANTRDWR)) {
213			/*
214			 * If upgrade to read-write by non-root, then verify
215			 * that user has necessary permissions on the device.
216			 */
217			if (p->p_ucred->cr_uid != 0) {
218				vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
219				if ((error = VOP_ACCESS(devvp, VREAD | VWRITE,
220				    p->p_ucred, p)) != 0) {
221					VOP_UNLOCK(devvp, 0, p);
222					return (error);
223				}
224				VOP_UNLOCK(devvp, 0, p);
225			}
226			fs->fs_flags &= ~FS_UNCLEAN;
227			if (fs->fs_clean == 0) {
228				fs->fs_flags |= FS_UNCLEAN;
229				if (mp->mnt_flag & MNT_FORCE) {
230					printf("WARNING: %s was not %s\n",
231					   fs->fs_fsmnt, "properly dismounted");
232				} else {
233					printf(
234"WARNING: R/W mount of %s denied.  Filesystem is not clean - run fsck\n",
235					    fs->fs_fsmnt);
236					return (EPERM);
237				}
238			}
239			if ((error = vn_start_write(NULL, &mp, V_WAIT)) != 0)
240				return (error);
241			fs->fs_ronly = 0;
242			fs->fs_clean = 0;
243			if ((error = ffs_sbupdate(ump, MNT_WAIT)) != 0) {
244				vn_finished_write(mp);
245				return (error);
246			}
247			/* check to see if we need to start softdep */
248			if ((fs->fs_flags & FS_DOSOFTDEP) &&
249			    (error = softdep_mount(devvp, mp, fs, p->p_ucred))){
250				vn_finished_write(mp);
251				return (error);
252			}
253			if (fs->fs_snapinum[0] != 0)
254				ffs_snapshot_mount(mp);
255			vn_finished_write(mp);
256		}
257		/*
258		 * Soft updates is incompatible with "async",
259		 * so if we are doing softupdates stop the user
260		 * from setting the async flag in an update.
261		 * Softdep_mount() clears it in an initial mount
262		 * or ro->rw remount.
263		 */
264		if (mp->mnt_flag & MNT_SOFTDEP)
265			mp->mnt_flag &= ~MNT_ASYNC;
266		/*
267		 * If not updating name, process export requests.
268		 */
269		if (args.fspec == 0)
270			return (vfs_export(mp, &ump->um_export, &args.export));
271		/*
272		 * If this is a snapshot request, take the snapshot.
273		 */
274		if (mp->mnt_flag & MNT_SNAPSHOT)
275			return (ffs_snapshot(mp, args.fspec));
276	}
277
278	/*
279	 * Not an update, or updating the name: look up the name
280	 * and verify that it refers to a sensible block device.
281	 */
282	NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, p);
283	if ((error = namei(ndp)) != 0)
284		return (error);
285	NDFREE(ndp, NDF_ONLY_PNBUF);
286	devvp = ndp->ni_vp;
287	if (!vn_isdisk(devvp, &error)) {
288		vrele(devvp);
289		return (error);
290	}
291
292	/*
293	 * If mount by non-root, then verify that user has necessary
294	 * permissions on the device.
295	 */
296	if (p->p_ucred->cr_uid != 0) {
297		accessmode = VREAD;
298		if ((mp->mnt_flag & MNT_RDONLY) == 0)
299			accessmode |= VWRITE;
300		vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
301		if ((error = VOP_ACCESS(devvp, accessmode, p->p_ucred, p))!= 0){
302			vput(devvp);
303			return (error);
304		}
305		VOP_UNLOCK(devvp, 0, p);
306	}
307
308	if (mp->mnt_flag & MNT_UPDATE) {
309		/*
310		 * Update only
311		 *
312		 * If it's not the same vnode, or at least the same device
313		 * then it's not correct.
314		 */
315
316		if (devvp != ump->um_devvp &&
317		    devvp->v_rdev != ump->um_devvp->v_rdev)
318			error = EINVAL;	/* needs translation */
319		vrele(devvp);
320		if (error)
321			return (error);
322	} else {
323		/*
324		 * New mount
325		 *
326		 * We need the name for the mount point (also used for
327		 * "last mounted on") copied in. If an error occurs,
328		 * the mount point is discarded by the upper level code.
329		 */
330		copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
331		bzero( mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
332		if ((error = ffs_mountfs(devvp, mp, p, M_FFSNODE)) != 0) {
333			vrele(devvp);
334			return (error);
335		}
336	}
337	/*
338	 * Save "mounted from" device name info for mount point (NULL pad).
339	 */
340	copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, &size);
341	bzero( mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
342	/*
343	 * Initialize filesystem stat information in mount struct.
344	 */
345	(void)VFS_STATFS(mp, &mp->mnt_stat, p);
346	return (0);
347}
348
349/*
350 * Reload all incore data for a filesystem (used after running fsck on
351 * the root filesystem and finding things to fix). The filesystem must
352 * be mounted read-only.
353 *
354 * Things to do to update the mount:
355 *	1) invalidate all cached meta-data.
356 *	2) re-read superblock from disk.
357 *	3) re-read summary information from disk.
358 *	4) invalidate all inactive vnodes.
359 *	5) invalidate all cached file data.
360 *	6) re-read inode data for all active vnodes.
361 */
362static int
363ffs_reload(mp, cred, p)
364	register struct mount *mp;
365	struct ucred *cred;
366	struct proc *p;
367{
368	register struct vnode *vp, *nvp, *devvp;
369	struct inode *ip;
370	struct csum *space;
371	struct buf *bp;
372	struct fs *fs, *newfs;
373	struct partinfo dpart;
374	dev_t dev;
375	int i, blks, size, error;
376	int32_t *lp;
377
378	if ((mp->mnt_flag & MNT_RDONLY) == 0)
379		return (EINVAL);
380	/*
381	 * Step 1: invalidate all cached meta-data.
382	 */
383	devvp = VFSTOUFS(mp)->um_devvp;
384	vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
385	error = vinvalbuf(devvp, 0, cred, p, 0, 0);
386	VOP_UNLOCK(devvp, 0, p);
387	if (error)
388		panic("ffs_reload: dirty1");
389
390	dev = devvp->v_rdev;
391
392	/*
393	 * Only VMIO the backing device if the backing device is a real
394	 * block device.  See ffs_mountmfs() for more details.
395	 */
396	if (devvp->v_tag != VT_MFS && vn_isdisk(devvp, NULL)) {
397		vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
398		vfs_object_create(devvp, p, p->p_ucred);
399		mtx_enter(&devvp->v_interlock, MTX_DEF);
400		VOP_UNLOCK(devvp, LK_INTERLOCK, p);
401	}
402
403	/*
404	 * Step 2: re-read superblock from disk.
405	 */
406	if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, NOCRED, p) != 0)
407		size = DEV_BSIZE;
408	else
409		size = dpart.disklab->d_secsize;
410	if ((error = bread(devvp, (ufs_daddr_t)(SBOFF/size), SBSIZE, NOCRED,&bp)) != 0)
411		return (error);
412	newfs = (struct fs *)bp->b_data;
413	if (newfs->fs_magic != FS_MAGIC || newfs->fs_bsize > MAXBSIZE ||
414		newfs->fs_bsize < sizeof(struct fs)) {
415			brelse(bp);
416			return (EIO);		/* XXX needs translation */
417	}
418	fs = VFSTOUFS(mp)->um_fs;
419	/*
420	 * Copy pointer fields back into superblock before copying in	XXX
421	 * new superblock. These should really be in the ufsmount.	XXX
422	 * Note that important parameters (eg fs_ncg) are unchanged.
423	 */
424	bcopy(&fs->fs_csp[0], &newfs->fs_csp[0], sizeof(fs->fs_csp));
425	newfs->fs_maxcluster = fs->fs_maxcluster;
426	bcopy(newfs, fs, (u_int)fs->fs_sbsize);
427	if (fs->fs_sbsize < SBSIZE)
428		bp->b_flags |= B_INVAL | B_NOCACHE;
429	brelse(bp);
430	mp->mnt_maxsymlinklen = fs->fs_maxsymlinklen;
431	ffs_oldfscompat(fs);
432
433	/*
434	 * Step 3: re-read summary information from disk.
435	 */
436	blks = howmany(fs->fs_cssize, fs->fs_fsize);
437	space = fs->fs_csp[0];
438	for (i = 0; i < blks; i += fs->fs_frag) {
439		size = fs->fs_bsize;
440		if (i + fs->fs_frag > blks)
441			size = (blks - i) * fs->fs_fsize;
442		error = bread(devvp, fsbtodb(fs, fs->fs_csaddr + i), size,
443		    NOCRED, &bp);
444		if (error)
445			return (error);
446		bcopy(bp->b_data, fs->fs_csp[fragstoblks(fs, i)], (u_int)size);
447		brelse(bp);
448	}
449	/*
450	 * We no longer know anything about clusters per cylinder group.
451	 */
452	if (fs->fs_contigsumsize > 0) {
453		lp = fs->fs_maxcluster;
454		for (i = 0; i < fs->fs_ncg; i++)
455			*lp++ = fs->fs_contigsumsize;
456	}
457
458loop:
459	simple_lock(&mntvnode_slock);
460	for (vp = mp->mnt_vnodelist.lh_first; vp != NULL; vp = nvp) {
461		if (vp->v_mount != mp) {
462			simple_unlock(&mntvnode_slock);
463			goto loop;
464		}
465		nvp = vp->v_mntvnodes.le_next;
466		/*
467		 * Step 4: invalidate all inactive vnodes.
468		 */
469		if (vrecycle(vp, &mntvnode_slock, p))
470			goto loop;
471		/*
472		 * Step 5: invalidate all cached file data.
473		 */
474		mtx_enter(&vp->v_interlock, MTX_DEF);
475		simple_unlock(&mntvnode_slock);
476		if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, p)) {
477			goto loop;
478		}
479		if (vinvalbuf(vp, 0, cred, p, 0, 0))
480			panic("ffs_reload: dirty2");
481		/*
482		 * Step 6: re-read inode data for all active vnodes.
483		 */
484		ip = VTOI(vp);
485		error =
486		    bread(devvp, fsbtodb(fs, ino_to_fsba(fs, ip->i_number)),
487		    (int)fs->fs_bsize, NOCRED, &bp);
488		if (error) {
489			vput(vp);
490			return (error);
491		}
492		ip->i_din = *((struct dinode *)bp->b_data +
493		    ino_to_fsbo(fs, ip->i_number));
494		ip->i_effnlink = ip->i_nlink;
495		brelse(bp);
496		vput(vp);
497		simple_lock(&mntvnode_slock);
498	}
499	simple_unlock(&mntvnode_slock);
500	return (0);
501}
502
503/*
504 * Common code for mount and mountroot
505 */
506int
507ffs_mountfs(devvp, mp, p, malloctype)
508	register struct vnode *devvp;
509	struct mount *mp;
510	struct proc *p;
511	struct malloc_type *malloctype;
512{
513	register struct ufsmount *ump;
514	struct buf *bp;
515	register struct fs *fs;
516	dev_t dev;
517	struct partinfo dpart;
518	caddr_t base, space;
519	int error, i, blks, size, ronly;
520	int32_t *lp;
521	struct ucred *cred;
522	u_int64_t maxfilesize;					/* XXX */
523	size_t strsize;
524	int ncount;
525
526	dev = devvp->v_rdev;
527	cred = p ? p->p_ucred : NOCRED;
528	/*
529	 * Disallow multiple mounts of the same device.
530	 * Disallow mounting of a device that is currently in use
531	 * (except for root, which might share swap device for miniroot).
532	 * Flush out any old buffers remaining from a previous use.
533	 */
534	error = vfs_mountedon(devvp);
535	if (error)
536		return (error);
537	ncount = vcount(devvp);
538
539	if (ncount > 1 && devvp != rootvp)
540		return (EBUSY);
541	vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
542	error = vinvalbuf(devvp, V_SAVE, cred, p, 0, 0);
543	VOP_UNLOCK(devvp, 0, p);
544	if (error)
545		return (error);
546
547	/*
548	 * Only VMIO the backing device if the backing device is a real
549	 * block device.  This excludes the original MFS implementation.
550	 * Note that it is optional that the backing device be VMIOed.  This
551	 * increases the opportunity for metadata caching.
552	 */
553	if (devvp->v_tag != VT_MFS && vn_isdisk(devvp, NULL)) {
554		vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
555		vfs_object_create(devvp, p, cred);
556		mtx_enter(&devvp->v_interlock, MTX_DEF);
557		VOP_UNLOCK(devvp, LK_INTERLOCK, p);
558	}
559
560	ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
561	vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
562	error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, p);
563	VOP_UNLOCK(devvp, 0, p);
564	if (error)
565		return (error);
566	if (devvp->v_rdev->si_iosize_max > mp->mnt_iosize_max)
567		mp->mnt_iosize_max = devvp->v_rdev->si_iosize_max;
568	if (mp->mnt_iosize_max > MAXPHYS)
569		mp->mnt_iosize_max = MAXPHYS;
570
571	if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, cred, p) != 0)
572		size = DEV_BSIZE;
573	else
574		size = dpart.disklab->d_secsize;
575
576	bp = NULL;
577	ump = NULL;
578	if ((error = bread(devvp, SBLOCK, SBSIZE, cred, &bp)) != 0)
579		goto out;
580	fs = (struct fs *)bp->b_data;
581	if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE ||
582	    fs->fs_bsize < sizeof(struct fs)) {
583		error = EINVAL;		/* XXX needs translation */
584		goto out;
585	}
586	fs->fs_fmod = 0;
587	fs->fs_flags &= ~FS_UNCLEAN;
588	if (fs->fs_clean == 0) {
589		fs->fs_flags |= FS_UNCLEAN;
590		if (ronly || (mp->mnt_flag & MNT_FORCE)) {
591			printf(
592"WARNING: %s was not properly dismounted\n",
593			    fs->fs_fsmnt);
594		} else {
595			printf(
596"WARNING: R/W mount of %s denied.  Filesystem is not clean - run fsck\n",
597			    fs->fs_fsmnt);
598			error = EPERM;
599			goto out;
600		}
601	}
602	/* XXX updating 4.2 FFS superblocks trashes rotational layout tables */
603	if (fs->fs_postblformat == FS_42POSTBLFMT && !ronly) {
604		error = EROFS;          /* needs translation */
605		goto out;
606	}
607	ump = malloc(sizeof *ump, M_UFSMNT, M_WAITOK);
608	bzero((caddr_t)ump, sizeof *ump);
609	ump->um_malloctype = malloctype;
610	ump->um_i_effnlink_valid = 1;
611	ump->um_fs = malloc((u_long)fs->fs_sbsize, M_UFSMNT,
612	    M_WAITOK);
613	ump->um_blkatoff = ffs_blkatoff;
614	ump->um_truncate = ffs_truncate;
615	ump->um_update = ffs_update;
616	ump->um_valloc = ffs_valloc;
617	ump->um_vfree = ffs_vfree;
618	bcopy(bp->b_data, ump->um_fs, (u_int)fs->fs_sbsize);
619	if (fs->fs_sbsize < SBSIZE)
620		bp->b_flags |= B_INVAL | B_NOCACHE;
621	brelse(bp);
622	bp = NULL;
623	fs = ump->um_fs;
624	fs->fs_ronly = ronly;
625	size = fs->fs_cssize;
626	blks = howmany(size, fs->fs_fsize);
627	if (fs->fs_contigsumsize > 0)
628		size += fs->fs_ncg * sizeof(int32_t);
629	base = space = malloc((u_long)size, M_UFSMNT, M_WAITOK);
630	for (i = 0; i < blks; i += fs->fs_frag) {
631		size = fs->fs_bsize;
632		if (i + fs->fs_frag > blks)
633			size = (blks - i) * fs->fs_fsize;
634		if ((error = bread(devvp, fsbtodb(fs, fs->fs_csaddr + i), size,
635		    cred, &bp)) != 0) {
636			free(base, M_UFSMNT);
637			goto out;
638		}
639		bcopy(bp->b_data, space, (u_int)size);
640		fs->fs_csp[fragstoblks(fs, i)] = (struct csum *)space;
641		space += size;
642		brelse(bp);
643		bp = NULL;
644	}
645	if (fs->fs_contigsumsize > 0) {
646		fs->fs_maxcluster = lp = (int32_t *)space;
647		for (i = 0; i < fs->fs_ncg; i++)
648			*lp++ = fs->fs_contigsumsize;
649	}
650	mp->mnt_data = (qaddr_t)ump;
651	mp->mnt_stat.f_fsid.val[0] = fs->fs_id[0];
652	mp->mnt_stat.f_fsid.val[1] = fs->fs_id[1];
653	if (fs->fs_id[0] == 0 || fs->fs_id[1] == 0 ||
654	    vfs_getvfs(&mp->mnt_stat.f_fsid))
655		vfs_getnewfsid(mp);
656	mp->mnt_maxsymlinklen = fs->fs_maxsymlinklen;
657	mp->mnt_flag |= MNT_LOCAL;
658	ump->um_mountp = mp;
659	ump->um_dev = dev;
660	ump->um_devvp = devvp;
661	ump->um_nindir = fs->fs_nindir;
662	ump->um_bptrtodb = fs->fs_fsbtodb;
663	ump->um_seqinc = fs->fs_frag;
664	for (i = 0; i < MAXQUOTAS; i++)
665		ump->um_quotas[i] = NULLVP;
666#ifdef FFS_EXTATTR
667	ufs_extattr_uepm_init(&ump->um_extattr);
668#endif
669	devvp->v_specmountpoint = mp;
670	ffs_oldfscompat(fs);
671
672	/*
673	 * Set FS local "last mounted on" information (NULL pad)
674	 */
675	copystr(	mp->mnt_stat.f_mntonname,	/* mount point*/
676			fs->fs_fsmnt,			/* copy area*/
677			sizeof(fs->fs_fsmnt) - 1,	/* max size*/
678			&strsize);			/* real size*/
679	bzero( fs->fs_fsmnt + strsize, sizeof(fs->fs_fsmnt) - strsize);
680
681	if( mp->mnt_flag & MNT_ROOTFS) {
682		/*
683		 * Root mount; update timestamp in mount structure.
684		 * this will be used by the common root mount code
685		 * to update the system clock.
686		 */
687		mp->mnt_time = fs->fs_time;
688	}
689
690	ump->um_savedmaxfilesize = fs->fs_maxfilesize;		/* XXX */
691	maxfilesize = (u_int64_t)0x40000000 * fs->fs_bsize - 1;	/* XXX */
692	if (fs->fs_maxfilesize > maxfilesize)			/* XXX */
693		fs->fs_maxfilesize = maxfilesize;		/* XXX */
694	if (ronly == 0) {
695		if ((fs->fs_flags & FS_DOSOFTDEP) &&
696		    (error = softdep_mount(devvp, mp, fs, cred)) != 0) {
697			free(base, M_UFSMNT);
698			goto out;
699		}
700		if (fs->fs_snapinum[0] != 0)
701			ffs_snapshot_mount(mp);
702		fs->fs_fmod = 1;
703		fs->fs_clean = 0;
704		(void) ffs_sbupdate(ump, MNT_WAIT);
705	}
706#ifdef FFS_EXTATTR
707	/*
708	 * XXX Auto-starting of EAs would go here.
709	 *
710	 * Auto-starting would:
711	 *	- check for /.attribute in the fs, and extattr_start if so
712	 *	- for each file in .attribute, enable that file with
713	 * 	  an attribute of the same name.
714	 * Not clear how to report errors -- probably eat them.
715	 * This would all happen while the file system was busy/not
716	 * available, so would effectively be "atomic".
717	 */
718	/* ufs_extattr_autostart(mp, ump); */
719#endif
720	return (0);
721out:
722	devvp->v_specmountpoint = NULL;
723	if (bp)
724		brelse(bp);
725	(void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, cred, p);
726	if (ump) {
727		free(ump->um_fs, M_UFSMNT);
728		free(ump, M_UFSMNT);
729		mp->mnt_data = (qaddr_t)0;
730	}
731	return (error);
732}
733
734/*
735 * Sanity checks for old file systems.
736 *
737 * XXX - goes away some day.
738 */
739static int
740ffs_oldfscompat(fs)
741	struct fs *fs;
742{
743
744	fs->fs_npsect = max(fs->fs_npsect, fs->fs_nsect);	/* XXX */
745	fs->fs_interleave = max(fs->fs_interleave, 1);		/* XXX */
746	if (fs->fs_postblformat == FS_42POSTBLFMT)		/* XXX */
747		fs->fs_nrpos = 8;				/* XXX */
748	if (fs->fs_inodefmt < FS_44INODEFMT) {			/* XXX */
749#if 0
750		int i;						/* XXX */
751		u_int64_t sizepb = fs->fs_bsize;		/* XXX */
752								/* XXX */
753		fs->fs_maxfilesize = fs->fs_bsize * NDADDR - 1;	/* XXX */
754		for (i = 0; i < NIADDR; i++) {			/* XXX */
755			sizepb *= NINDIR(fs);			/* XXX */
756			fs->fs_maxfilesize += sizepb;		/* XXX */
757		}						/* XXX */
758#endif
759		fs->fs_maxfilesize = (u_quad_t) 1LL << 39;
760		fs->fs_qbmask = ~fs->fs_bmask;			/* XXX */
761		fs->fs_qfmask = ~fs->fs_fmask;			/* XXX */
762	}							/* XXX */
763	return (0);
764}
765
766/*
767 * unmount system call
768 */
769int
770ffs_unmount(mp, mntflags, p)
771	struct mount *mp;
772	int mntflags;
773	struct proc *p;
774{
775	register struct ufsmount *ump;
776	register struct fs *fs;
777	int error, flags;
778
779	flags = 0;
780	if (mntflags & MNT_FORCE) {
781		flags |= FORCECLOSE;
782	}
783#ifdef FFS_EXTATTR
784	if ((error = ufs_extattr_stop(mp, p)))
785		if (error != EOPNOTSUPP)
786			printf("ffs_unmount: ufs_extattr_stop returned %d\n",
787			    error);
788	ufs_extattr_uepm_destroy(&ump->um_extattr);
789#endif
790	if (mp->mnt_flag & MNT_SOFTDEP) {
791		if ((error = softdep_flushfiles(mp, flags, p)) != 0)
792			return (error);
793	} else {
794		if ((error = ffs_flushfiles(mp, flags, p)) != 0)
795			return (error);
796	}
797	ump = VFSTOUFS(mp);
798	fs = ump->um_fs;
799	if (fs->fs_ronly == 0) {
800		fs->fs_clean = fs->fs_flags & FS_UNCLEAN ? 0 : 1;
801		error = ffs_sbupdate(ump, MNT_WAIT);
802		if (error) {
803			fs->fs_clean = 0;
804			return (error);
805		}
806	}
807	ump->um_devvp->v_specmountpoint = NULL;
808
809	vinvalbuf(ump->um_devvp, V_SAVE, NOCRED, p, 0, 0);
810	error = VOP_CLOSE(ump->um_devvp, fs->fs_ronly ? FREAD : FREAD|FWRITE,
811		NOCRED, p);
812
813	vrele(ump->um_devvp);
814
815	free(fs->fs_csp[0], M_UFSMNT);
816	free(fs, M_UFSMNT);
817	free(ump, M_UFSMNT);
818	mp->mnt_data = (qaddr_t)0;
819	mp->mnt_flag &= ~MNT_LOCAL;
820	return (error);
821}
822
823/*
824 * Flush out all the files in a filesystem.
825 */
826int
827ffs_flushfiles(mp, flags, p)
828	register struct mount *mp;
829	int flags;
830	struct proc *p;
831{
832	register struct ufsmount *ump;
833	int error;
834
835	ump = VFSTOUFS(mp);
836#ifdef QUOTA
837	if (mp->mnt_flag & MNT_QUOTA) {
838		int i;
839		error = vflush(mp, NULLVP, SKIPSYSTEM|flags);
840		if (error)
841			return (error);
842		for (i = 0; i < MAXQUOTAS; i++) {
843			if (ump->um_quotas[i] == NULLVP)
844				continue;
845			quotaoff(p, mp, i);
846		}
847		/*
848		 * Here we fall through to vflush again to ensure
849		 * that we have gotten rid of all the system vnodes.
850		 */
851	}
852#endif
853	if (ump->um_devvp->v_flag & VCOPYONWRITE) {
854		if ((error = vflush(mp, NULL, SKIPSYSTEM | flags)) != 0)
855			return (error);
856		ffs_snapshot_unmount(mp);
857		/*
858		 * Here we fall through to vflush again to ensure
859		 * that we have gotten rid of all the system vnodes.
860		 */
861	}
862        /*
863	 * Flush all the files.
864	 */
865	if ((error = vflush(mp, NULL, flags)) != 0)
866		return (error);
867	/*
868	 * Flush filesystem metadata.
869	 */
870	vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY, p);
871	error = VOP_FSYNC(ump->um_devvp, p->p_ucred, MNT_WAIT, p);
872	VOP_UNLOCK(ump->um_devvp, 0, p);
873	return (error);
874}
875
876/*
877 * Get file system statistics.
878 */
879int
880ffs_statfs(mp, sbp, p)
881	struct mount *mp;
882	register struct statfs *sbp;
883	struct proc *p;
884{
885	register struct ufsmount *ump;
886	register struct fs *fs;
887
888	ump = VFSTOUFS(mp);
889	fs = ump->um_fs;
890	if (fs->fs_magic != FS_MAGIC)
891		panic("ffs_statfs");
892	sbp->f_bsize = fs->fs_fsize;
893	sbp->f_iosize = fs->fs_bsize;
894	sbp->f_blocks = fs->fs_dsize;
895	sbp->f_bfree = fs->fs_cstotal.cs_nbfree * fs->fs_frag +
896		fs->fs_cstotal.cs_nffree;
897	sbp->f_bavail = freespace(fs, fs->fs_minfree);
898	sbp->f_files =  fs->fs_ncg * fs->fs_ipg - ROOTINO;
899	sbp->f_ffree = fs->fs_cstotal.cs_nifree;
900	if (sbp != &mp->mnt_stat) {
901		sbp->f_type = mp->mnt_vfc->vfc_typenum;
902		bcopy((caddr_t)mp->mnt_stat.f_mntonname,
903			(caddr_t)&sbp->f_mntonname[0], MNAMELEN);
904		bcopy((caddr_t)mp->mnt_stat.f_mntfromname,
905			(caddr_t)&sbp->f_mntfromname[0], MNAMELEN);
906	}
907	return (0);
908}
909
910/*
911 * Go through the disk queues to initiate sandbagged IO;
912 * go through the inodes to write those that have been modified;
913 * initiate the writing of the super block if it has been modified.
914 *
915 * Note: we are always called with the filesystem marked `MPBUSY'.
916 */
917int
918ffs_sync(mp, waitfor, cred, p)
919	struct mount *mp;
920	int waitfor;
921	struct ucred *cred;
922	struct proc *p;
923{
924	struct vnode *nvp, *vp;
925	struct inode *ip;
926	struct ufsmount *ump = VFSTOUFS(mp);
927	struct fs *fs;
928	int error, count, wait, lockreq, allerror = 0;
929
930	fs = ump->um_fs;
931	if (fs->fs_fmod != 0 && fs->fs_ronly != 0) {		/* XXX */
932		printf("fs = %s\n", fs->fs_fsmnt);
933		panic("ffs_sync: rofs mod");
934	}
935	/*
936	 * Write back each (modified) inode.
937	 */
938	wait = 0;
939	lockreq = LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK;
940	if (waitfor == MNT_WAIT) {
941		wait = 1;
942		lockreq = LK_EXCLUSIVE | LK_INTERLOCK;
943	}
944	simple_lock(&mntvnode_slock);
945loop:
946	for (vp = mp->mnt_vnodelist.lh_first; vp != NULL; vp = nvp) {
947		/*
948		 * If the vnode that we are about to sync is no longer
949		 * associated with this mount point, start over.
950		 */
951		if (vp->v_mount != mp)
952			goto loop;
953		mtx_enter(&vp->v_interlock, MTX_DEF);
954		nvp = vp->v_mntvnodes.le_next;
955		ip = VTOI(vp);
956		if (vp->v_type == VNON || ((ip->i_flag &
957		     (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 &&
958		     TAILQ_EMPTY(&vp->v_dirtyblkhd))) {
959			mtx_exit(&vp->v_interlock, MTX_DEF);
960			continue;
961		}
962		if (vp->v_type != VCHR) {
963			simple_unlock(&mntvnode_slock);
964			if ((error = vget(vp, lockreq, p)) != 0) {
965				simple_lock(&mntvnode_slock);
966				if (error == ENOENT)
967					goto loop;
968				continue;
969			}
970			if ((error = VOP_FSYNC(vp, cred, waitfor, p)) != 0)
971				allerror = error;
972			VOP_UNLOCK(vp, 0, p);
973			vrele(vp);
974			simple_lock(&mntvnode_slock);
975		} else {
976			simple_unlock(&mntvnode_slock);
977			mtx_exit(&vp->v_interlock, MTX_DEF);
978			UFS_UPDATE(vp, wait);
979			simple_lock(&mntvnode_slock);
980		}
981	}
982	simple_unlock(&mntvnode_slock);
983	/*
984	 * Force stale file system control information to be flushed.
985	 */
986	if (waitfor == MNT_WAIT) {
987		if ((error = softdep_flushworklist(ump->um_mountp, &count, p)))
988			allerror = error;
989		/* Flushed work items may create new vnodes to clean */
990		if (count) {
991			simple_lock(&mntvnode_slock);
992			goto loop;
993		}
994	}
995	if (waitfor == MNT_NOWAIT) {
996		vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY, p);
997		if ((error = VOP_FSYNC(ump->um_devvp, cred, waitfor, p)) != 0)
998			allerror = error;
999		VOP_UNLOCK(ump->um_devvp, 0, p);
1000	}
1001#ifdef QUOTA
1002	qsync(mp);
1003#endif
1004	/*
1005	 * Write back modified superblock.
1006	 */
1007	if (fs->fs_fmod != 0 && (error = ffs_sbupdate(ump, waitfor)) != 0)
1008		allerror = error;
1009	return (allerror);
1010}
1011
1012/*
1013 * Look up a FFS dinode number to find its incore vnode, otherwise read it
1014 * in from disk.  If it is in core, wait for the lock bit to clear, then
1015 * return the inode locked.  Detection and handling of mount points must be
1016 * done by the calling routine.
1017 */
1018static int ffs_inode_hash_lock;
1019
1020int
1021ffs_vget(mp, ino, vpp)
1022	struct mount *mp;
1023	ino_t ino;
1024	struct vnode **vpp;
1025{
1026	struct fs *fs;
1027	struct inode *ip;
1028	struct ufsmount *ump;
1029	struct buf *bp;
1030	struct vnode *vp;
1031	dev_t dev;
1032	int error;
1033
1034	ump = VFSTOUFS(mp);
1035	dev = ump->um_dev;
1036restart:
1037	if ((*vpp = ufs_ihashget(dev, ino)) != NULL) {
1038		return (0);
1039	}
1040
1041	/*
1042	 * Lock out the creation of new entries in the FFS hash table in
1043	 * case getnewvnode() or MALLOC() blocks, otherwise a duplicate
1044	 * may occur!
1045	 */
1046	if (ffs_inode_hash_lock) {
1047		while (ffs_inode_hash_lock) {
1048			ffs_inode_hash_lock = -1;
1049			tsleep(&ffs_inode_hash_lock, PVM, "ffsvgt", 0);
1050		}
1051		goto restart;
1052	}
1053	ffs_inode_hash_lock = 1;
1054
1055	/*
1056	 * If this MALLOC() is performed after the getnewvnode()
1057	 * it might block, leaving a vnode with a NULL v_data to be
1058	 * found by ffs_sync() if a sync happens to fire right then,
1059	 * which will cause a panic because ffs_sync() blindly
1060	 * dereferences vp->v_data (as well it should).
1061	 */
1062	MALLOC(ip, struct inode *, sizeof(struct inode),
1063	    ump->um_malloctype, M_WAITOK);
1064
1065	/* Allocate a new vnode/inode. */
1066	error = getnewvnode(VT_UFS, mp, ffs_vnodeop_p, &vp);
1067	if (error) {
1068		if (ffs_inode_hash_lock < 0)
1069			wakeup(&ffs_inode_hash_lock);
1070		ffs_inode_hash_lock = 0;
1071		*vpp = NULL;
1072		FREE(ip, ump->um_malloctype);
1073		return (error);
1074	}
1075	bzero((caddr_t)ip, sizeof(struct inode));
1076	/*
1077	 * FFS supports lock sharing in the stack of vnodes
1078	 */
1079	vp->v_vnlock = &vp->v_lock;
1080	lockinit(vp->v_vnlock, PINOD, "inode", 0, LK_CANRECURSE);
1081	vp->v_data = ip;
1082	ip->i_vnode = vp;
1083	ip->i_fs = fs = ump->um_fs;
1084	ip->i_dev = dev;
1085	ip->i_number = ino;
1086#ifdef QUOTA
1087	{
1088		int i;
1089		for (i = 0; i < MAXQUOTAS; i++)
1090			ip->i_dquot[i] = NODQUOT;
1091	}
1092#endif
1093	/*
1094	 * Put it onto its hash chain and lock it so that other requests for
1095	 * this inode will block if they arrive while we are sleeping waiting
1096	 * for old data structures to be purged or for the contents of the
1097	 * disk portion of this inode to be read.
1098	 */
1099	ufs_ihashins(ip);
1100
1101	if (ffs_inode_hash_lock < 0)
1102		wakeup(&ffs_inode_hash_lock);
1103	ffs_inode_hash_lock = 0;
1104
1105	/* Read in the disk contents for the inode, copy into the inode. */
1106	error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)),
1107	    (int)fs->fs_bsize, NOCRED, &bp);
1108	if (error) {
1109		/*
1110		 * The inode does not contain anything useful, so it would
1111		 * be misleading to leave it on its hash chain. With mode
1112		 * still zero, it will be unlinked and returned to the free
1113		 * list by vput().
1114		 */
1115		brelse(bp);
1116		vput(vp);
1117		*vpp = NULL;
1118		return (error);
1119	}
1120	ip->i_din = *((struct dinode *)bp->b_data + ino_to_fsbo(fs, ino));
1121	if (DOINGSOFTDEP(vp))
1122		softdep_load_inodeblock(ip);
1123	else
1124		ip->i_effnlink = ip->i_nlink;
1125	bqrelse(bp);
1126
1127	/*
1128	 * Initialize the vnode from the inode, check for aliases.
1129	 * Note that the underlying vnode may have changed.
1130	 */
1131	error = ufs_vinit(mp, ffs_specop_p, ffs_fifoop_p, &vp);
1132	if (error) {
1133		vput(vp);
1134		*vpp = NULL;
1135		return (error);
1136	}
1137	/*
1138	 * Finish inode initialization now that aliasing has been resolved.
1139	 */
1140	ip->i_devvp = ump->um_devvp;
1141	VREF(ip->i_devvp);
1142	/*
1143	 * Set up a generation number for this inode if it does not
1144	 * already have one. This should only happen on old filesystems.
1145	 */
1146	if (ip->i_gen == 0) {
1147		ip->i_gen = random() / 2 + 1;
1148		if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0)
1149			ip->i_flag |= IN_MODIFIED;
1150	}
1151	/*
1152	 * Ensure that uid and gid are correct. This is a temporary
1153	 * fix until fsck has been changed to do the update.
1154	 */
1155	if (fs->fs_inodefmt < FS_44INODEFMT) {		/* XXX */
1156		ip->i_uid = ip->i_din.di_ouid;		/* XXX */
1157		ip->i_gid = ip->i_din.di_ogid;		/* XXX */
1158	}						/* XXX */
1159
1160	*vpp = vp;
1161	return (0);
1162}
1163
1164/*
1165 * File handle to vnode
1166 *
1167 * Have to be really careful about stale file handles:
1168 * - check that the inode number is valid
1169 * - call ffs_vget() to get the locked inode
1170 * - check for an unallocated inode (i_mode == 0)
1171 * - check that the given client host has export rights and return
1172 *   those rights via. exflagsp and credanonp
1173 */
1174int
1175ffs_fhtovp(mp, fhp, vpp)
1176	register struct mount *mp;
1177	struct fid *fhp;
1178	struct vnode **vpp;
1179{
1180	register struct ufid *ufhp;
1181	struct fs *fs;
1182
1183	ufhp = (struct ufid *)fhp;
1184	fs = VFSTOUFS(mp)->um_fs;
1185	if (ufhp->ufid_ino < ROOTINO ||
1186	    ufhp->ufid_ino >= fs->fs_ncg * fs->fs_ipg)
1187		return (ESTALE);
1188	return (ufs_fhtovp(mp, ufhp, vpp));
1189}
1190
1191/*
1192 * Vnode pointer to File handle
1193 */
1194/* ARGSUSED */
1195int
1196ffs_vptofh(vp, fhp)
1197	struct vnode *vp;
1198	struct fid *fhp;
1199{
1200	register struct inode *ip;
1201	register struct ufid *ufhp;
1202
1203	ip = VTOI(vp);
1204	ufhp = (struct ufid *)fhp;
1205	ufhp->ufid_len = sizeof(struct ufid);
1206	ufhp->ufid_ino = ip->i_number;
1207	ufhp->ufid_gen = ip->i_gen;
1208	return (0);
1209}
1210
1211/*
1212 * Initialize the filesystem; just use ufs_init.
1213 */
1214static int
1215ffs_init(vfsp)
1216	struct vfsconf *vfsp;
1217{
1218
1219	softdep_initialize();
1220	return (ufs_init(vfsp));
1221}
1222
1223/*
1224 * Write a superblock and associated information back to disk.
1225 */
1226static int
1227ffs_sbupdate(mp, waitfor)
1228	struct ufsmount *mp;
1229	int waitfor;
1230{
1231	register struct fs *dfs, *fs = mp->um_fs;
1232	register struct buf *bp;
1233	int blks;
1234	caddr_t space;
1235	int i, size, error, allerror = 0;
1236
1237	/*
1238	 * First write back the summary information.
1239	 */
1240	blks = howmany(fs->fs_cssize, fs->fs_fsize);
1241	space = (caddr_t)fs->fs_csp[0];
1242	for (i = 0; i < blks; i += fs->fs_frag) {
1243		size = fs->fs_bsize;
1244		if (i + fs->fs_frag > blks)
1245			size = (blks - i) * fs->fs_fsize;
1246		bp = getblk(mp->um_devvp, fsbtodb(fs, fs->fs_csaddr + i),
1247		    size, 0, 0);
1248		bcopy(space, bp->b_data, (u_int)size);
1249		space += size;
1250		if (waitfor != MNT_WAIT)
1251			bawrite(bp);
1252		else if ((error = bwrite(bp)) != 0)
1253			allerror = error;
1254	}
1255	/*
1256	 * Now write back the superblock itself. If any errors occurred
1257	 * up to this point, then fail so that the superblock avoids
1258	 * being written out as clean.
1259	 */
1260	if (allerror)
1261		return (allerror);
1262	bp = getblk(mp->um_devvp, SBLOCK, (int)fs->fs_sbsize, 0, 0);
1263	fs->fs_fmod = 0;
1264	fs->fs_time = time_second;
1265	bcopy((caddr_t)fs, bp->b_data, (u_int)fs->fs_sbsize);
1266	/* Restore compatibility to old file systems.		   XXX */
1267	dfs = (struct fs *)bp->b_data;				/* XXX */
1268	if (fs->fs_postblformat == FS_42POSTBLFMT)		/* XXX */
1269		dfs->fs_nrpos = -1;				/* XXX */
1270	if (fs->fs_inodefmt < FS_44INODEFMT) {			/* XXX */
1271		int32_t *lp, tmp;				/* XXX */
1272								/* XXX */
1273		lp = (int32_t *)&dfs->fs_qbmask;		/* XXX */
1274		tmp = lp[4];					/* XXX */
1275		for (i = 4; i > 0; i--)				/* XXX */
1276			lp[i] = lp[i-1];			/* XXX */
1277		lp[0] = tmp;					/* XXX */
1278	}							/* XXX */
1279	dfs->fs_maxfilesize = mp->um_savedmaxfilesize;		/* XXX */
1280	if (waitfor != MNT_WAIT)
1281		bawrite(bp);
1282	else if ((error = bwrite(bp)) != 0)
1283		allerror = error;
1284	return (allerror);
1285}
1286