Commit | Line | Data |
---|---|---|
da7c5cc6 | 1 | /* |
e9fed4d6 | 2 | * Copyright (c) 1991 The Regents of the University of California. |
7188ac27 | 3 | * All rights reserved. |
da7c5cc6 | 4 | * |
b702c21d | 5 | * %sccs.include.redist.c% |
7188ac27 | 6 | * |
e9fed4d6 | 7 | * @(#)ufs_vfsops.c 7.57 (Berkeley) %G% |
da7c5cc6 | 8 | */ |
71e4e98b | 9 | |
e9fed4d6 KB |
10 | #include <sys/param.h> |
11 | #include <sys/mount.h> | |
12 | #include <sys/proc.h> | |
13 | #include <sys/buf.h> | |
14 | #include <sys/vnode.h> | |
15 | #include <sys/specdev.h> | |
609e7cfa MK |
16 | #include "ioctl.h" |
17 | #include "disklabel.h" | |
18 | #include "stat.h" | |
71e4e98b | 19 | |
e9fed4d6 KB |
20 | #include <ufs/ufs/quota.h> |
21 | #include <ufs/ufs/inode.h> | |
22 | #include <ufs/ufs/ufsmount.h> | |
23 | #include <ufs/ufs/ufs_extern.h> | |
7188ac27 | 24 | |
d85a9d1b | 25 | /* |
e9fed4d6 | 26 | * Flag to permit forcible unmounting. |
d85a9d1b KM |
27 | */ |
28 | int doforce = 1; | |
29 | ||
5bf9d21f KM |
30 | /* |
31 | * Make a filesystem operational. | |
32 | * Nothing to do at the moment. | |
33 | */ | |
31593ba7 | 34 | /* ARGSUSED */ |
e9fed4d6 | 35 | int |
0eb6f54a | 36 | ufs_start(mp, flags, p) |
5bf9d21f KM |
37 | struct mount *mp; |
38 | int flags; | |
0eb6f54a | 39 | struct proc *p; |
5bf9d21f KM |
40 | { |
41 | ||
42 | return (0); | |
43 | } | |
71e4e98b | 44 | |
7188ac27 | 45 | /* |
ec67a3ce MK |
46 | error = closei(dev, IFBLK, fs->fs_ronly? FREAD : FREAD|FWRITE); |
47 | irele(ip); | |
48 | return (error); | |
71e4e98b SL |
49 | } |
50 | ||
7188ac27 KM |
51 | /* |
52 | * Return root of a filesystem | |
53 | */ | |
e9fed4d6 | 54 | int |
7188ac27 KM |
55 | ufs_root(mp, vpp) |
56 | struct mount *mp; | |
57 | struct vnode **vpp; | |
58 | { | |
31593ba7 | 59 | register struct inode *ip; |
e9fed4d6 | 60 | struct ufsmount *ump; |
31593ba7 KM |
61 | struct inode *nip; |
62 | struct vnode tvp; | |
7188ac27 KM |
63 | int error; |
64 | ||
e9fed4d6 | 65 | ump = VFSTOUFS(mp); |
31593ba7 KM |
66 | tvp.v_mount = mp; |
67 | ip = VTOI(&tvp); | |
68 | ip->i_vnode = &tvp; | |
e9fed4d6 KB |
69 | ip->i_dev = ump->um_dev; |
70 | if (error = (ump->um_iget)(ip, (ino_t)ROOTINO, &nip)) | |
7188ac27 | 71 | return (error); |
31593ba7 | 72 | *vpp = ITOV(nip); |
7188ac27 KM |
73 | return (0); |
74 | } | |
75 | ||
8dc876c1 KM |
76 | /* |
77 | * Do operations associated with quotas | |
78 | */ | |
e9fed4d6 | 79 | int |
0eb6f54a | 80 | ufs_quotactl(mp, cmds, uid, arg, p) |
8dc876c1 KM |
81 | struct mount *mp; |
82 | int cmds; | |
e9fed4d6 | 83 | u_int uid; |
8dc876c1 | 84 | caddr_t arg; |
0eb6f54a | 85 | struct proc *p; |
8dc876c1 | 86 | { |
8dc876c1 KM |
87 | struct ufsmount *ump = VFSTOUFS(mp); |
88 | int cmd, type, error; | |
89 | ||
90 | #ifndef QUOTA | |
91 | return (EOPNOTSUPP); | |
92 | #else | |
93 | if (uid == -1) | |
c6f5111d | 94 | uid = p->p_cred->p_ruid; |
8dc876c1 KM |
95 | cmd = cmds >> SUBCMDSHIFT; |
96 | ||
97 | switch (cmd) { | |
98 | case Q_GETQUOTA: | |
99 | case Q_SYNC: | |
c6f5111d | 100 | if (uid == p->p_cred->p_ruid) |
8dc876c1 KM |
101 | break; |
102 | /* fall through */ | |
103 | default: | |
c6f5111d | 104 | if (error = suser(p->p_ucred, &p->p_acflag)) |
8dc876c1 KM |
105 | return (error); |
106 | } | |
107 | ||
108 | type = cmd & SUBCMDMASK; | |
109 | if ((u_int)type >= MAXQUOTAS) | |
110 | return (EINVAL); | |
111 | ||
112 | switch (cmd) { | |
113 | ||
114 | case Q_QUOTAON: | |
c6f5111d | 115 | return (quotaon(p, mp, type, arg)); |
8dc876c1 KM |
116 | |
117 | case Q_QUOTAOFF: | |
118 | if (vfs_busy(mp)) | |
119 | return (0); | |
70a360ba | 120 | error = quotaoff(p, mp, type); |
8dc876c1 KM |
121 | vfs_unbusy(mp); |
122 | return (error); | |
123 | ||
124 | case Q_SETQUOTA: | |
125 | return (setquota(mp, uid, type, arg)); | |
126 | ||
127 | case Q_SETUSE: | |
128 | return (setuse(mp, uid, type, arg)); | |
129 | ||
130 | case Q_GETQUOTA: | |
131 | return (getquota(mp, uid, type, arg)); | |
132 | ||
133 | case Q_SYNC: | |
134 | if (vfs_busy(mp)) | |
135 | return (0); | |
136 | error = qsync(mp); | |
137 | vfs_unbusy(mp); | |
138 | return (error); | |
139 | ||
140 | default: | |
141 | return (EINVAL); | |
142 | } | |
143 | /* NOTREACHED */ | |
144 | #endif | |
145 | } | |
146 | ||
e9fed4d6 | 147 | int syncprt = 0; |
71e4e98b SL |
148 | |
149 | /* | |
7188ac27 KM |
150 | * Print out statistics on the current allocation of the buffer pool. |
151 | * Can be enabled to print out on every ``sync'' by setting "syncprt" | |
152 | * above. | |
153 | */ | |
e9fed4d6 KB |
154 | void |
155 | ufs_bufstats() | |
7188ac27 KM |
156 | { |
157 | int s, i, j, count; | |
158 | register struct buf *bp, *dp; | |
159 | int counts[MAXBSIZE/CLBYTES+1]; | |
160 | static char *bname[BQUEUES] = { "LOCKED", "LRU", "AGE", "EMPTY" }; | |
161 | ||
162 | for (bp = bfreelist, i = 0; bp < &bfreelist[BQUEUES]; bp++, i++) { | |
163 | count = 0; | |
164 | for (j = 0; j <= MAXBSIZE/CLBYTES; j++) | |
165 | counts[j] = 0; | |
166 | s = splbio(); | |
167 | for (dp = bp->av_forw; dp != bp; dp = dp->av_forw) { | |
168 | counts[dp->b_bufsize/CLBYTES]++; | |
169 | count++; | |
170 | } | |
171 | splx(s); | |
172 | printf("%s: total-%d", bname[i], count); | |
173 | for (j = 0; j <= MAXBSIZE/CLBYTES; j++) | |
174 | if (counts[j] != 0) | |
175 | printf(", %d-%d", j * CLBYTES, counts[j]); | |
176 | printf("\n"); | |
177 | } | |
178 | } | |
179 | ||
180 | /* | |
181 | * File handle to vnode | |
113c35f2 KM |
182 | * |
183 | * Have to be really careful about stale file handles: | |
e9fed4d6 | 184 | * - check that the inode number is valid |
113c35f2 KM |
185 | * - call iget() to get the locked inode |
186 | * - check for an unallocated inode (i_mode == 0) | |
187 | * - check that the generation number matches | |
7188ac27 | 188 | */ |
e9fed4d6 | 189 | int |
7188ac27 | 190 | ufs_fhtovp(mp, fhp, vpp) |
113c35f2 | 191 | register struct mount *mp; |
7188ac27 KM |
192 | struct fid *fhp; |
193 | struct vnode **vpp; | |
194 | { | |
31593ba7 | 195 | register struct inode *ip; |
e9fed4d6 KB |
196 | register struct ufid *ufhp; |
197 | struct ufsmount *ump; | |
31593ba7 KM |
198 | struct inode *nip; |
199 | struct vnode tvp; | |
7188ac27 KM |
200 | int error; |
201 | ||
202 | ufhp = (struct ufid *)fhp; | |
e9fed4d6 | 203 | ump = VFSTOUFS(mp); |
31593ba7 KM |
204 | tvp.v_mount = mp; |
205 | ip = VTOI(&tvp); | |
206 | ip->i_vnode = &tvp; | |
e9fed4d6 KB |
207 | ip->i_dev = ump->um_dev; |
208 | if (error = (ump->um_iget)(ip, ufhp->ufid_ino, &nip)) { | |
82161bc8 | 209 | *vpp = NULLVP; |
7188ac27 KM |
210 | return (error); |
211 | } | |
31593ba7 | 212 | ip = nip; |
113c35f2 | 213 | if (ip->i_mode == 0) { |
e9fed4d6 | 214 | ufs_iput(ip); |
82161bc8 | 215 | *vpp = NULLVP; |
113c35f2 KM |
216 | return (EINVAL); |
217 | } | |
7188ac27 | 218 | if (ip->i_gen != ufhp->ufid_gen) { |
e9fed4d6 | 219 | ufs_iput(ip); |
82161bc8 | 220 | *vpp = NULLVP; |
7188ac27 KM |
221 | return (EINVAL); |
222 | } | |
223 | *vpp = ITOV(ip); | |
224 | return (0); | |
225 | } | |
226 | ||
227 | /* | |
29e77c27 | 228 | * Vnode pointer to File handle |
7188ac27 KM |
229 | */ |
230 | /* ARGSUSED */ | |
758e3529 KM |
231 | ufs_vptofh(vp, fhp) |
232 | struct vnode *vp; | |
7188ac27 | 233 | struct fid *fhp; |
7188ac27 | 234 | { |
e9fed4d6 | 235 | register struct inode *ip; |
758e3529 | 236 | register struct ufid *ufhp; |
7188ac27 | 237 | |
e9fed4d6 | 238 | ip = VTOI(vp); |
758e3529 KM |
239 | ufhp = (struct ufid *)fhp; |
240 | ufhp->ufid_len = sizeof(struct ufid); | |
241 | ufhp->ufid_ino = ip->i_number; | |
242 | ufhp->ufid_gen = ip->i_gen; | |
243 | return (0); | |
7188ac27 | 244 | } |