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