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