xref: /original-bsd/sys/ufs/ufs/ufs_vfsops.c (revision 58b1b499)
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.6 (Berkeley) 03/30/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  * Flag to permit forcible unmounting.
32  */
33 int doforce = 1;
34 
35 /*
36  * Make a filesystem operational.
37  * Nothing to do at the moment.
38  */
39 /* ARGSUSED */
40 int
41 ufs_start(mp, flags, p)
42 	struct mount *mp;
43 	int flags;
44 	struct proc *p;
45 {
46 
47 	return (0);
48 }
49 
50 /*
51  * Return the root of a filesystem.
52  */
53 int
54 ufs_root(mp, vpp)
55 	struct mount *mp;
56 	struct vnode **vpp;
57 {
58 	struct vnode *nvp;
59 	int error;
60 
61 	if (error = VFS_VGET(mp, (ino_t)ROOTINO, &nvp))
62 		return (error);
63 	*vpp = nvp;
64 	return (0);
65 }
66 
67 /*
68  * Do operations associated with quotas
69  */
70 int
71 ufs_quotactl(mp, cmds, uid, arg, p)
72 	struct mount *mp;
73 	int cmds;
74 	uid_t uid;
75 	caddr_t arg;
76 	struct proc *p;
77 {
78 	int cmd, type, error;
79 
80 #ifndef QUOTA
81 	return (EOPNOTSUPP);
82 #else
83 	if (uid == -1)
84 		uid = p->p_cred->p_ruid;
85 	cmd = cmds >> SUBCMDSHIFT;
86 
87 	switch (cmd) {
88 	case Q_SYNC:
89 		break;
90 	case Q_GETQUOTA:
91 		if (uid == p->p_cred->p_ruid)
92 			break;
93 		/* fall through */
94 	default:
95 		if (error = suser(p->p_ucred, &p->p_acflag))
96 			return (error);
97 	}
98 
99 	type = cmds & SUBCMDMASK;
100 	if ((u_int)type >= MAXQUOTAS)
101 		return (EINVAL);
102 
103 	switch (cmd) {
104 
105 	case Q_QUOTAON:
106 		return (quotaon(p, mp, type, arg));
107 
108 	case Q_QUOTAOFF:
109 		if (vfs_busy(mp))
110 			return (0);
111 		error = quotaoff(p, mp, type);
112 		vfs_unbusy(mp);
113 		return (error);
114 
115 	case Q_SETQUOTA:
116 		return (setquota(mp, uid, type, arg));
117 
118 	case Q_SETUSE:
119 		return (setuse(mp, uid, type, arg));
120 
121 	case Q_GETQUOTA:
122 		return (getquota(mp, uid, type, arg));
123 
124 	case Q_SYNC:
125 		if (vfs_busy(mp))
126 			return (0);
127 		error = qsync(mp);
128 		vfs_unbusy(mp);
129 		return (error);
130 
131 	default:
132 		return (EINVAL);
133 	}
134 	/* NOTREACHED */
135 #endif
136 }
137 
138 /*
139  * Initial UFS filesystems, done only once.
140  */
141 int
142 ufs_init(vfsp)
143 	struct vfsconf *vfsp;
144 {
145 	static int done;
146 
147 	if (done)
148 		return (0);
149 	done = 1;
150 	ufs_ihashinit();
151 #ifdef QUOTA
152 	dqinit();
153 #endif
154 	return (0);
155 }
156 
157 /*
158  * This is the generic part of fhtovp called after the underlying
159  * filesystem has validated the file handle.
160  *
161  * Verify that a host should have access to a filesystem, and if so
162  * return a vnode for the presented file handle.
163  */
164 int
165 ufs_check_export(mp, ufhp, nam, vpp, exflagsp, credanonp)
166 	register struct mount *mp;
167 	struct ufid *ufhp;
168 	struct mbuf *nam;
169 	struct vnode **vpp;
170 	int *exflagsp;
171 	struct ucred **credanonp;
172 {
173 	register struct inode *ip;
174 	register struct netcred *np;
175 	register struct ufsmount *ump = VFSTOUFS(mp);
176 	struct vnode *nvp;
177 	int error;
178 
179 	/*
180 	 * Get the export permission structure for this <mp, client> tuple.
181 	 */
182 	np = vfs_export_lookup(mp, &ump->um_export, nam);
183 	if (np == NULL)
184 		return (EACCES);
185 
186 	if (error = VFS_VGET(mp, ufhp->ufid_ino, &nvp)) {
187 		*vpp = NULLVP;
188 		return (error);
189 	}
190 	ip = VTOI(nvp);
191 	if (ip->i_mode == 0 || ip->i_gen != ufhp->ufid_gen) {
192 		vput(nvp);
193 		*vpp = NULLVP;
194 		return (ESTALE);
195 	}
196 	*vpp = nvp;
197 	*exflagsp = np->netc_exflags;
198 	*credanonp = &np->netc_anon;
199 	return (0);
200 }
201