xref: /csrg-svn/sys/ufs/ufs/ufs_vfsops.c (revision 69581)
123400Smckusick /*
266804Sbostic  * 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*69581Smckusick  *	@(#)ufs_vfsops.c	8.8 (Berkeley) 05/20/95
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 /*
3139043Smckusick  * Make a filesystem operational.
3239043Smckusick  * Nothing to do at the moment.
3339043Smckusick  */
3439390Smckusick /* ARGSUSED */
3551513Sbostic int
ufs_start(mp,flags,p)3648036Smckusick ufs_start(mp, flags, p)
3739043Smckusick 	struct mount *mp;
3839043Smckusick 	int flags;
3948036Smckusick 	struct proc *p;
4039043Smckusick {
4112795Ssam 
4239043Smckusick 	return (0);
4339043Smckusick }
4439043Smckusick 
4537737Smckusick /*
4666804Sbostic  * Return the root of a filesystem.
4766804Sbostic  */
4866804Sbostic int
ufs_root(mp,vpp)4966804Sbostic ufs_root(mp, vpp)
5066804Sbostic 	struct mount *mp;
5166804Sbostic 	struct vnode **vpp;
5266804Sbostic {
5366804Sbostic 	struct vnode *nvp;
5466804Sbostic 	int error;
5566804Sbostic 
5666804Sbostic 	if (error = VFS_VGET(mp, (ino_t)ROOTINO, &nvp))
5766804Sbostic 		return (error);
5866804Sbostic 	*vpp = nvp;
5966804Sbostic 	return (0);
6066804Sbostic }
6166804Sbostic 
6266804Sbostic /*
6341314Smckusick  * Do operations associated with quotas
6441314Smckusick  */
6551513Sbostic int
ufs_quotactl(mp,cmds,uid,arg,p)6648036Smckusick ufs_quotactl(mp, cmds, uid, arg, p)
6741314Smckusick 	struct mount *mp;
6841314Smckusick 	int cmds;
6954454Smckusick 	uid_t uid;
7041314Smckusick 	caddr_t arg;
7148036Smckusick 	struct proc *p;
7241314Smckusick {
7341314Smckusick 	int cmd, type, error;
7441314Smckusick 
7541314Smckusick #ifndef QUOTA
7641314Smckusick 	return (EOPNOTSUPP);
7741314Smckusick #else
7841314Smckusick 	if (uid == -1)
7947571Skarels 		uid = p->p_cred->p_ruid;
8041314Smckusick 	cmd = cmds >> SUBCMDSHIFT;
8141314Smckusick 
8241314Smckusick 	switch (cmd) {
8368337Smckusick 	case Q_SYNC:
8468337Smckusick 		break;
8541314Smckusick 	case Q_GETQUOTA:
8647571Skarels 		if (uid == p->p_cred->p_ruid)
8741314Smckusick 			break;
8841314Smckusick 		/* fall through */
8941314Smckusick 	default:
9047571Skarels 		if (error = suser(p->p_ucred, &p->p_acflag))
9141314Smckusick 			return (error);
9241314Smckusick 	}
9341314Smckusick 
9468337Smckusick 	type = cmds & SUBCMDMASK;
9541314Smckusick 	if ((u_int)type >= MAXQUOTAS)
9641314Smckusick 		return (EINVAL);
97*69581Smckusick 	if (vfs_busy(mp, LK_NOWAIT, 0, p))
98*69581Smckusick 		return (0);
9941314Smckusick 
10041314Smckusick 	switch (cmd) {
10141314Smckusick 
10241314Smckusick 	case Q_QUOTAON:
103*69581Smckusick 		error = quotaon(p, mp, type, arg);
104*69581Smckusick 		break;
10541314Smckusick 
10641314Smckusick 	case Q_QUOTAOFF:
10750114Smckusick 		error = quotaoff(p, mp, type);
108*69581Smckusick 		break;
10941314Smckusick 
11041314Smckusick 	case Q_SETQUOTA:
111*69581Smckusick 		error = setquota(mp, uid, type, arg);
112*69581Smckusick 		break;
11341314Smckusick 
11441314Smckusick 	case Q_SETUSE:
115*69581Smckusick 		error = setuse(mp, uid, type, arg);
116*69581Smckusick 		break;
11741314Smckusick 
11841314Smckusick 	case Q_GETQUOTA:
119*69581Smckusick 		error = getquota(mp, uid, type, arg);
120*69581Smckusick 		break;
12141314Smckusick 
12241314Smckusick 	case Q_SYNC:
12341314Smckusick 		error = qsync(mp);
124*69581Smckusick 		break;
12541314Smckusick 
12641314Smckusick 	default:
127*69581Smckusick 		error = EINVAL;
128*69581Smckusick 		break;
12941314Smckusick 	}
130*69581Smckusick 	vfs_unbusy(mp, p);
131*69581Smckusick 	return (error);
13241314Smckusick #endif
13341314Smckusick }
13441314Smckusick 
13537737Smckusick /*
13668672Smckusick  * Initial UFS filesystems, done only once.
13768672Smckusick  */
13868672Smckusick int
ufs_init(vfsp)13968672Smckusick ufs_init(vfsp)
14068672Smckusick 	struct vfsconf *vfsp;
14168672Smckusick {
14268672Smckusick 	static int done;
14368672Smckusick 
14468672Smckusick 	if (done)
14568672Smckusick 		return (0);
14668672Smckusick 	done = 1;
14768672Smckusick 	ufs_ihashinit();
14868672Smckusick #ifdef QUOTA
14968672Smckusick 	dqinit();
15068672Smckusick #endif
15168672Smckusick 	return (0);
15268672Smckusick }
15368672Smckusick 
15468672Smckusick /*
15555889Smckusick  * This is the generic part of fhtovp called after the underlying
15655889Smckusick  * filesystem has validated the file handle.
15755889Smckusick  *
15855889Smckusick  * Verify that a host should have access to a filesystem, and if so
15955889Smckusick  * return a vnode for the presented file handle.
16055889Smckusick  */
16155889Smckusick int
ufs_check_export(mp,ufhp,nam,vpp,exflagsp,credanonp)16256244Smckusick ufs_check_export(mp, ufhp, nam, vpp, exflagsp, credanonp)
16355889Smckusick 	register struct mount *mp;
16456244Smckusick 	struct ufid *ufhp;
16555889Smckusick 	struct mbuf *nam;
16655889Smckusick 	struct vnode **vpp;
16755889Smckusick 	int *exflagsp;
16855889Smckusick 	struct ucred **credanonp;
16955889Smckusick {
17055889Smckusick 	register struct inode *ip;
17155889Smckusick 	register struct netcred *np;
17255889Smckusick 	register struct ufsmount *ump = VFSTOUFS(mp);
17355889Smckusick 	struct vnode *nvp;
17455889Smckusick 	int error;
17555889Smckusick 
17655889Smckusick 	/*
17755889Smckusick 	 * Get the export permission structure for this <mp, client> tuple.
17855889Smckusick 	 */
17965677Shibler 	np = vfs_export_lookup(mp, &ump->um_export, nam);
18065677Shibler 	if (np == NULL)
18155889Smckusick 		return (EACCES);
18265677Shibler 
18355889Smckusick 	if (error = VFS_VGET(mp, ufhp->ufid_ino, &nvp)) {
18455889Smckusick 		*vpp = NULLVP;
18555889Smckusick 		return (error);
18655889Smckusick 	}
18755889Smckusick 	ip = VTOI(nvp);
18855889Smckusick 	if (ip->i_mode == 0 || ip->i_gen != ufhp->ufid_gen) {
18956796Smckusick 		vput(nvp);
19055889Smckusick 		*vpp = NULLVP;
19155889Smckusick 		return (ESTALE);
19255889Smckusick 	}
19355889Smckusick 	*vpp = nvp;
19455889Smckusick 	*exflagsp = np->netc_exflags;
19555889Smckusick 	*credanonp = &np->netc_anon;
19655889Smckusick 	return (0);
19754617Smckusick }
198