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