xref: /original-bsd/sys/ufs/ufs/ufs_vfsops.c (revision 9a35f7df)
1 /*
2  * Copyright (c) 1991, 1993, 1994
3  *	The Regents of the University of California.  All rights reserved.
4  * (c) UNIX System Laboratories, Inc.
5  * All or some portions of this file are derived from material licensed
6  * to the University of California by American Telephone and Telegraph
7  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8  * the permission of UNIX System Laboratories, Inc.
9  *
10  * %sccs.include.redist.c%
11  *
12  *	@(#)ufs_vfsops.c	8.8 (Berkeley) 05/20/95
13  */
14 
15 #include <sys/param.h>
16 #include <sys/mbuf.h>
17 #include <sys/mount.h>
18 #include <sys/proc.h>
19 #include <sys/buf.h>
20 #include <sys/vnode.h>
21 #include <sys/malloc.h>
22 
23 #include <miscfs/specfs/specdev.h>
24 
25 #include <ufs/ufs/quota.h>
26 #include <ufs/ufs/inode.h>
27 #include <ufs/ufs/ufsmount.h>
28 #include <ufs/ufs/ufs_extern.h>
29 
30 /*
31  * Make a filesystem operational.
32  * Nothing to do at the moment.
33  */
34 /* ARGSUSED */
35 int
36 ufs_start(mp, flags, p)
37 	struct mount *mp;
38 	int flags;
39 	struct proc *p;
40 {
41 
42 	return (0);
43 }
44 
45 /*
46  * Return the root of a filesystem.
47  */
48 int
49 ufs_root(mp, vpp)
50 	struct mount *mp;
51 	struct vnode **vpp;
52 {
53 	struct vnode *nvp;
54 	int error;
55 
56 	if (error = VFS_VGET(mp, (ino_t)ROOTINO, &nvp))
57 		return (error);
58 	*vpp = nvp;
59 	return (0);
60 }
61 
62 /*
63  * Do operations associated with quotas
64  */
65 int
66 ufs_quotactl(mp, cmds, uid, arg, p)
67 	struct mount *mp;
68 	int cmds;
69 	uid_t uid;
70 	caddr_t arg;
71 	struct proc *p;
72 {
73 	int cmd, type, error;
74 
75 #ifndef QUOTA
76 	return (EOPNOTSUPP);
77 #else
78 	if (uid == -1)
79 		uid = p->p_cred->p_ruid;
80 	cmd = cmds >> SUBCMDSHIFT;
81 
82 	switch (cmd) {
83 	case Q_SYNC:
84 		break;
85 	case Q_GETQUOTA:
86 		if (uid == p->p_cred->p_ruid)
87 			break;
88 		/* fall through */
89 	default:
90 		if (error = suser(p->p_ucred, &p->p_acflag))
91 			return (error);
92 	}
93 
94 	type = cmds & SUBCMDMASK;
95 	if ((u_int)type >= MAXQUOTAS)
96 		return (EINVAL);
97 	if (vfs_busy(mp, LK_NOWAIT, 0, p))
98 		return (0);
99 
100 	switch (cmd) {
101 
102 	case Q_QUOTAON:
103 		error = quotaon(p, mp, type, arg);
104 		break;
105 
106 	case Q_QUOTAOFF:
107 		error = quotaoff(p, mp, type);
108 		break;
109 
110 	case Q_SETQUOTA:
111 		error = setquota(mp, uid, type, arg);
112 		break;
113 
114 	case Q_SETUSE:
115 		error = setuse(mp, uid, type, arg);
116 		break;
117 
118 	case Q_GETQUOTA:
119 		error = getquota(mp, uid, type, arg);
120 		break;
121 
122 	case Q_SYNC:
123 		error = qsync(mp);
124 		break;
125 
126 	default:
127 		error = EINVAL;
128 		break;
129 	}
130 	vfs_unbusy(mp, p);
131 	return (error);
132 #endif
133 }
134 
135 /*
136  * Initial UFS filesystems, done only once.
137  */
138 int
139 ufs_init(vfsp)
140 	struct vfsconf *vfsp;
141 {
142 	static int done;
143 
144 	if (done)
145 		return (0);
146 	done = 1;
147 	ufs_ihashinit();
148 #ifdef QUOTA
149 	dqinit();
150 #endif
151 	return (0);
152 }
153 
154 /*
155  * This is the generic part of fhtovp called after the underlying
156  * filesystem has validated the file handle.
157  *
158  * Verify that a host should have access to a filesystem, and if so
159  * return a vnode for the presented file handle.
160  */
161 int
162 ufs_check_export(mp, ufhp, nam, vpp, exflagsp, credanonp)
163 	register struct mount *mp;
164 	struct ufid *ufhp;
165 	struct mbuf *nam;
166 	struct vnode **vpp;
167 	int *exflagsp;
168 	struct ucred **credanonp;
169 {
170 	register struct inode *ip;
171 	register struct netcred *np;
172 	register struct ufsmount *ump = VFSTOUFS(mp);
173 	struct vnode *nvp;
174 	int error;
175 
176 	/*
177 	 * Get the export permission structure for this <mp, client> tuple.
178 	 */
179 	np = vfs_export_lookup(mp, &ump->um_export, nam);
180 	if (np == NULL)
181 		return (EACCES);
182 
183 	if (error = VFS_VGET(mp, ufhp->ufid_ino, &nvp)) {
184 		*vpp = NULLVP;
185 		return (error);
186 	}
187 	ip = VTOI(nvp);
188 	if (ip->i_mode == 0 || ip->i_gen != ufhp->ufid_gen) {
189 		vput(nvp);
190 		*vpp = NULLVP;
191 		return (ESTALE);
192 	}
193 	*vpp = nvp;
194 	*exflagsp = np->netc_exflags;
195 	*credanonp = &np->netc_anon;
196 	return (0);
197 }
198