xref: /netbsd/sys/ufs/ufs/ufs_vfsops.c (revision bf9ec67e)
1 /*	$NetBSD: ufs_vfsops.c,v 1.13 2001/11/08 02:39:17 lukem Exp $	*/
2 
3 /*
4  * Copyright (c) 1991, 1993, 1994
5  *	The Regents of the University of California.  All rights reserved.
6  * (c) UNIX System Laboratories, Inc.
7  * All or some portions of this file are derived from material licensed
8  * to the University of California by American Telephone and Telegraph
9  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
10  * the permission of UNIX System Laboratories, Inc.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 3. All advertising materials mentioning features or use of this software
21  *    must display the following acknowledgement:
22  *	This product includes software developed by the University of
23  *	California, Berkeley and its contributors.
24  * 4. Neither the name of the University nor the names of its contributors
25  *    may be used to endorse or promote products derived from this software
26  *    without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38  * SUCH DAMAGE.
39  *
40  *	@(#)ufs_vfsops.c	8.8 (Berkeley) 5/20/95
41  */
42 
43 #include <sys/cdefs.h>
44 __KERNEL_RCSID(0, "$NetBSD: ufs_vfsops.c,v 1.13 2001/11/08 02:39:17 lukem Exp $");
45 
46 #include "opt_quota.h"
47 
48 #include <sys/param.h>
49 #include <sys/mbuf.h>
50 #include <sys/mount.h>
51 #include <sys/proc.h>
52 #include <sys/buf.h>
53 #include <sys/vnode.h>
54 #include <sys/malloc.h>
55 
56 #include <miscfs/specfs/specdev.h>
57 
58 #include <ufs/ufs/quota.h>
59 #include <ufs/ufs/inode.h>
60 #include <ufs/ufs/ufsmount.h>
61 #include <ufs/ufs/ufs_extern.h>
62 
63 /* how many times ufs_init() was called */
64 int ufs_initcount = 0;
65 
66 /*
67  * Make a filesystem operational.
68  * Nothing to do at the moment.
69  */
70 /* ARGSUSED */
71 int
72 ufs_start(mp, flags, p)
73 	struct mount *mp;
74 	int flags;
75 	struct proc *p;
76 {
77 
78 	return (0);
79 }
80 
81 /*
82  * Return the root of a filesystem.
83  */
84 int
85 ufs_root(mp, vpp)
86 	struct mount *mp;
87 	struct vnode **vpp;
88 {
89 	struct vnode *nvp;
90 	int error;
91 
92 	if ((error = VFS_VGET(mp, (ino_t)ROOTINO, &nvp)) != 0)
93 		return (error);
94 	*vpp = nvp;
95 	return (0);
96 }
97 
98 /*
99  * Do operations associated with quotas
100  */
101 int
102 ufs_quotactl(mp, cmds, uid, arg, p)
103 	struct mount *mp;
104 	int cmds;
105 	uid_t uid;
106 	caddr_t arg;
107 	struct proc *p;
108 {
109 
110 #ifndef QUOTA
111 	return (EOPNOTSUPP);
112 #else
113 	int cmd, type, error;
114 
115 	if (uid == -1)
116 		uid = p->p_cred->p_ruid;
117 	cmd = cmds >> SUBCMDSHIFT;
118 
119 	switch (cmd) {
120 	case Q_SYNC:
121 		break;
122 	case Q_GETQUOTA:
123 		if (uid == p->p_cred->p_ruid)
124 			break;
125 		/* fall through */
126 	default:
127 		if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
128 			return (error);
129 	}
130 
131 	type = cmds & SUBCMDMASK;
132 	if ((u_int)type >= MAXQUOTAS)
133 		return (EINVAL);
134 	if (vfs_busy(mp, LK_NOWAIT, 0))
135 		return (0);
136 
137 	switch (cmd) {
138 
139 	case Q_QUOTAON:
140 		error = quotaon(p, mp, type, arg);
141 		break;
142 
143 	case Q_QUOTAOFF:
144 		error = quotaoff(p, mp, type);
145 		break;
146 
147 	case Q_SETQUOTA:
148 		error = setquota(mp, uid, type, arg);
149 		break;
150 
151 	case Q_SETUSE:
152 		error = setuse(mp, uid, type, arg);
153 		break;
154 
155 	case Q_GETQUOTA:
156 		error = getquota(mp, uid, type, arg);
157 		break;
158 
159 	case Q_SYNC:
160 		error = qsync(mp);
161 		break;
162 
163 	default:
164 		error = EINVAL;
165 	}
166 	vfs_unbusy(mp);
167 	return (error);
168 #endif
169 }
170 
171 /*
172  * Verify a remote client has export rights and return these rights via.
173  * exflagsp and credanonp.
174  */
175 int
176 ufs_check_export(mp, nam, exflagsp, credanonp)
177 	struct mount *mp;
178 	struct mbuf *nam;
179 	int *exflagsp;
180 	struct ucred **credanonp;
181 {
182 	struct netcred *np;
183 	struct ufsmount *ump = VFSTOUFS(mp);
184 
185 	/*
186 	 * Get the export permission structure for this <mp, client> tuple.
187 	 */
188 	np = vfs_export_lookup(mp, &ump->um_export, nam);
189 	if (np == NULL)
190 		return (EACCES);
191 
192 	*exflagsp = np->netc_exflags;
193 	*credanonp = &np->netc_anon;
194 	return (0);
195 }
196 
197 /*
198  * This is the generic part of fhtovp called after the underlying
199  * filesystem has validated the file handle.
200  */
201 int
202 ufs_fhtovp(mp, ufhp, vpp)
203 	struct mount *mp;
204 	struct ufid *ufhp;
205 	struct vnode **vpp;
206 {
207 	struct vnode *nvp;
208 	struct inode *ip;
209 	int error;
210 
211 	if ((error = VFS_VGET(mp, ufhp->ufid_ino, &nvp)) != 0) {
212 		*vpp = NULLVP;
213 		return (error);
214 	}
215 	ip = VTOI(nvp);
216 	if (ip->i_ffs_mode == 0 || ip->i_ffs_gen != ufhp->ufid_gen) {
217 		vput(nvp);
218 		*vpp = NULLVP;
219 		return (ESTALE);
220 	}
221 	*vpp = nvp;
222 	return (0);
223 }
224 
225 /*
226  * Initialize UFS filesystems, done only once.
227  */
228 void
229 ufs_init()
230 {
231 	if (ufs_initcount++ > 0)
232 		return;
233 
234 	ufs_ihashinit();
235 #ifdef QUOTA
236 	dqinit();
237 #endif
238 }
239 
240 void
241 ufs_reinit()
242 {
243 	ufs_ihashreinit();
244 #ifdef QUOTA
245 	dqreinit();
246 #endif
247 }
248 
249 /*
250  * Free UFS filesystem resources, done only once.
251  */
252 void
253 ufs_done()
254 {
255 	if (--ufs_initcount > 0)
256 		return;
257 
258 	ufs_ihashdone();
259 #ifdef QUOTA
260 	dqdone();
261 #endif
262 }
263