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