xref: /csrg-svn/sys/ufs/ffs/ufs_vfsops.c (revision 66804)
123400Smckusick /*
2*66804Sbostic  * Copyright (c) 1991, 1993, 1994
363376Sbostic  *	The Regents of the University of California.  All rights reserved.
465774Sbostic  * (c) UNIX System Laboratories, Inc.
565774Sbostic  * All or some portions of this file are derived from material licensed
665774Sbostic  * to the University of California by American Telephone and Telegraph
765774Sbostic  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
865774Sbostic  * the permission of UNIX System Laboratories, Inc.
923400Smckusick  *
1044539Sbostic  * %sccs.include.redist.c%
1137737Smckusick  *
12*66804Sbostic  *	@(#)ufs_vfsops.c	8.4 (Berkeley) 04/16/94
1323400Smckusick  */
1412795Ssam 
1551513Sbostic #include <sys/param.h>
1655889Smckusick #include <sys/mbuf.h>
1751513Sbostic #include <sys/mount.h>
1851513Sbostic #include <sys/proc.h>
1951513Sbostic #include <sys/buf.h>
2051513Sbostic #include <sys/vnode.h>
2154617Smckusick #include <sys/malloc.h>
2212795Ssam 
2355094Spendry #include <miscfs/specfs/specdev.h>
2455094Spendry 
2551513Sbostic #include <ufs/ufs/quota.h>
2651513Sbostic #include <ufs/ufs/inode.h>
2751513Sbostic #include <ufs/ufs/ufsmount.h>
2851513Sbostic #include <ufs/ufs/ufs_extern.h>
2947571Skarels 
3037737Smckusick /*
3151513Sbostic  * Flag to permit forcible unmounting.
3248359Smckusick  */
3348359Smckusick int doforce = 1;
3448359Smckusick 
3548359Smckusick /*
3639043Smckusick  * Make a filesystem operational.
3739043Smckusick  * Nothing to do at the moment.
3839043Smckusick  */
3939390Smckusick /* ARGSUSED */
4051513Sbostic int
ufs_start(mp,flags,p)4148036Smckusick ufs_start(mp, flags, p)
4239043Smckusick 	struct mount *mp;
4339043Smckusick 	int flags;
4448036Smckusick 	struct proc *p;
4539043Smckusick {
4612795Ssam 
4739043Smckusick 	return (0);
4839043Smckusick }
4939043Smckusick 
5037737Smckusick /*
51*66804Sbostic  * Return the root of a filesystem.
52*66804Sbostic  */
53*66804Sbostic int
ufs_root(mp,vpp)54*66804Sbostic ufs_root(mp, vpp)
55*66804Sbostic 	struct mount *mp;
56*66804Sbostic 	struct vnode **vpp;
57*66804Sbostic {
58*66804Sbostic 	struct vnode *nvp;
59*66804Sbostic 	int error;
60*66804Sbostic 
61*66804Sbostic 	if (error = VFS_VGET(mp, (ino_t)ROOTINO, &nvp))
62*66804Sbostic 		return (error);
63*66804Sbostic 	*vpp = nvp;
64*66804Sbostic 	return (0);
65*66804Sbostic }
66*66804Sbostic 
67*66804Sbostic /*
6841314Smckusick  * Do operations associated with quotas
6941314Smckusick  */
7051513Sbostic int
ufs_quotactl(mp,cmds,uid,arg,p)7148036Smckusick ufs_quotactl(mp, cmds, uid, arg, p)
7241314Smckusick 	struct mount *mp;
7341314Smckusick 	int cmds;
7454454Smckusick 	uid_t uid;
7541314Smckusick 	caddr_t arg;
7648036Smckusick 	struct proc *p;
7741314Smckusick {
7841314Smckusick 	int cmd, type, error;
7941314Smckusick 
8041314Smckusick #ifndef QUOTA
8141314Smckusick 	return (EOPNOTSUPP);
8241314Smckusick #else
8341314Smckusick 	if (uid == -1)
8447571Skarels 		uid = p->p_cred->p_ruid;
8541314Smckusick 	cmd = cmds >> SUBCMDSHIFT;
8641314Smckusick 
8741314Smckusick 	switch (cmd) {
8841314Smckusick 	case Q_GETQUOTA:
8941314Smckusick 	case Q_SYNC:
9047571Skarels 		if (uid == p->p_cred->p_ruid)
9141314Smckusick 			break;
9241314Smckusick 		/* fall through */
9341314Smckusick 	default:
9447571Skarels 		if (error = suser(p->p_ucred, &p->p_acflag))
9541314Smckusick 			return (error);
9641314Smckusick 	}
9741314Smckusick 
9841314Smckusick 	type = cmd & SUBCMDMASK;
9941314Smckusick 	if ((u_int)type >= MAXQUOTAS)
10041314Smckusick 		return (EINVAL);
10141314Smckusick 
10241314Smckusick 	switch (cmd) {
10341314Smckusick 
10441314Smckusick 	case Q_QUOTAON:
10547571Skarels 		return (quotaon(p, mp, type, arg));
10641314Smckusick 
10741314Smckusick 	case Q_QUOTAOFF:
10841314Smckusick 		if (vfs_busy(mp))
10941314Smckusick 			return (0);
11050114Smckusick 		error = quotaoff(p, mp, type);
11141314Smckusick 		vfs_unbusy(mp);
11241314Smckusick 		return (error);
11341314Smckusick 
11441314Smckusick 	case Q_SETQUOTA:
11541314Smckusick 		return (setquota(mp, uid, type, arg));
11641314Smckusick 
11741314Smckusick 	case Q_SETUSE:
11841314Smckusick 		return (setuse(mp, uid, type, arg));
11941314Smckusick 
12041314Smckusick 	case Q_GETQUOTA:
12141314Smckusick 		return (getquota(mp, uid, type, arg));
12241314Smckusick 
12341314Smckusick 	case Q_SYNC:
12441314Smckusick 		if (vfs_busy(mp))
12541314Smckusick 			return (0);
12641314Smckusick 		error = qsync(mp);
12741314Smckusick 		vfs_unbusy(mp);
12841314Smckusick 		return (error);
12941314Smckusick 
13041314Smckusick 	default:
13141314Smckusick 		return (EINVAL);
13241314Smckusick 	}
13341314Smckusick 	/* NOTREACHED */
13441314Smckusick #endif
13541314Smckusick }
13641314Smckusick 
13737737Smckusick /*
13855889Smckusick  * This is the generic part of fhtovp called after the underlying
13955889Smckusick  * filesystem has validated the file handle.
14055889Smckusick  *
14155889Smckusick  * Verify that a host should have access to a filesystem, and if so
14255889Smckusick  * return a vnode for the presented file handle.
14355889Smckusick  */
14455889Smckusick int
ufs_check_export(mp,ufhp,nam,vpp,exflagsp,credanonp)14556244Smckusick ufs_check_export(mp, ufhp, nam, vpp, exflagsp, credanonp)
14655889Smckusick 	register struct mount *mp;
14756244Smckusick 	struct ufid *ufhp;
14855889Smckusick 	struct mbuf *nam;
14955889Smckusick 	struct vnode **vpp;
15055889Smckusick 	int *exflagsp;
15155889Smckusick 	struct ucred **credanonp;
15255889Smckusick {
15355889Smckusick 	register struct inode *ip;
15455889Smckusick 	register struct netcred *np;
15555889Smckusick 	register struct ufsmount *ump = VFSTOUFS(mp);
15655889Smckusick 	struct vnode *nvp;
15755889Smckusick 	int error;
15855889Smckusick 
15955889Smckusick 	/*
16055889Smckusick 	 * Get the export permission structure for this <mp, client> tuple.
16155889Smckusick 	 */
16265677Shibler 	np = vfs_export_lookup(mp, &ump->um_export, nam);
16365677Shibler 	if (np == NULL)
16455889Smckusick 		return (EACCES);
16565677Shibler 
16655889Smckusick 	if (error = VFS_VGET(mp, ufhp->ufid_ino, &nvp)) {
16755889Smckusick 		*vpp = NULLVP;
16855889Smckusick 		return (error);
16955889Smckusick 	}
17055889Smckusick 	ip = VTOI(nvp);
17155889Smckusick 	if (ip->i_mode == 0 || ip->i_gen != ufhp->ufid_gen) {
17256796Smckusick 		vput(nvp);
17355889Smckusick 		*vpp = NULLVP;
17455889Smckusick 		return (ESTALE);
17555889Smckusick 	}
17655889Smckusick 	*vpp = nvp;
17755889Smckusick 	*exflagsp = np->netc_exflags;
17855889Smckusick 	*credanonp = &np->netc_anon;
17955889Smckusick 	return (0);
18054617Smckusick }
181