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