Commit | Line | Data |
---|---|---|
805e021f CE |
1 | /* |
2 | * Copyright 2000, International Business Machines Corporation and others. | |
3 | * All Rights Reserved. | |
4 | * | |
5 | * This software has been released under the terms of the IBM Public | |
6 | * License. For details, see the LICENSE file in the top-level source | |
7 | * directory or online at http://www.openafs.org/dl/license10.html | |
8 | */ | |
9 | ||
10 | /* | |
11 | * FreeBSD inode operations | |
12 | * | |
13 | * Implements: | |
14 | * | |
15 | */ | |
16 | #include <afsconfig.h> | |
17 | #include "afs/param.h" | |
18 | ||
19 | ||
20 | #include "afs/sysincludes.h" /* Standard vendor system headers */ | |
21 | #include "afsincludes.h" /* Afs-based standard headers */ | |
22 | #include "afs/osi_inode.h" | |
23 | #include "afs/afs_stats.h" /* statistics stuff */ | |
24 | #include <sys/queue.h> | |
25 | #include <sys/lock.h> | |
26 | #include <ufs/ufs/dinode.h> | |
27 | #include <ufs/ufs/extattr.h> | |
28 | #include <ufs/ufs/ufsmount.h> | |
29 | ||
30 | int | |
31 | getinode(fs, dev, inode, ipp, perror) | |
32 | struct mount *fs; | |
33 | struct inode **ipp; | |
34 | #ifdef AFS_FBSD53_ENV | |
35 | struct cdev *dev; | |
36 | #else | |
37 | dev_t dev; | |
38 | #endif | |
39 | ino_t inode; | |
40 | int *perror; | |
41 | { | |
42 | struct vnode *vp; | |
43 | int code; | |
44 | ||
45 | *ipp = 0; | |
46 | *perror = 0; | |
47 | if (!fs) { | |
48 | struct ufsmount *ump; | |
49 | struct mount *mp; | |
50 | ||
51 | mtx_lock(&mountlist_mtx); | |
52 | if ((mp = TAILQ_FIRST(&mountlist)) != NULL) | |
53 | do { | |
54 | /* | |
55 | * XXX Also do the test for MFS | |
56 | */ | |
57 | #undef m_data | |
58 | #undef m_next | |
59 | if (!strcmp(mp->mnt_stat.f_fstypename, MOUNT_UFS)) { | |
60 | ump = VFSTOUFS(mp); | |
61 | if (ump->um_fs == NULL) | |
62 | break; | |
63 | if (ump->um_dev == dev) { | |
64 | fs = ump->um_mountp; | |
65 | } | |
66 | } | |
67 | mp = TAILQ_NEXT(mp, mnt_list); | |
68 | } while (mp != TAILQ_FIRST(&mountlist)); | |
69 | mtx_unlock(&mountlist_mtx); | |
70 | if (!fs) | |
71 | return (ENXIO); | |
72 | } | |
73 | code = VFS_VGET(fs, inode, 0, &vp); | |
74 | if (code != 0) { | |
75 | *perror = BAD_IGET; | |
76 | return code; | |
77 | } else { | |
78 | *ipp = VTOI(vp); | |
79 | return (0); | |
80 | } | |
81 | } | |
82 | ||
83 | int | |
84 | igetinode(vfsp, dev, inode, ipp, perror) | |
85 | struct inode **ipp; | |
86 | struct mount *vfsp; | |
87 | #ifdef AFS_FBSD53_ENV | |
88 | struct cdev *dev; | |
89 | #else | |
90 | dev_t dev; | |
91 | #endif | |
92 | ino_t inode; | |
93 | int *perror; | |
94 | { | |
95 | struct inode *ip; | |
96 | int code = 0; | |
97 | ||
98 | *perror = 0; | |
99 | ||
100 | AFS_STATCNT(igetinode); | |
101 | ||
102 | if ((code = getinode(vfsp, dev, inode, &ip, perror)) != 0) { | |
103 | return (code); | |
104 | } | |
105 | ||
106 | if (ip->i_mode == 0) { | |
107 | /* Not an allocated inode */ | |
108 | vput(ITOV(ip)); | |
109 | return (ENOENT); | |
110 | } | |
111 | ||
112 | if (ip->i_nlink == 0 || (ip->i_mode & IFMT) != IFREG) { | |
113 | vput(ITOV(ip)); | |
114 | return (ENOENT); | |
115 | } | |
116 | ||
117 | *ipp = ip; | |
118 | return (0); | |
119 | } | |
120 | ||
121 | #if 0 | |
122 | /* | |
123 | * icreate system call -- create an inode | |
124 | */ | |
125 | afs_syscall_icreate(dev, near_inode, param1, param2, param3, param4, retval) | |
126 | long *retval; | |
127 | long dev, near_inode, param1, param2, param3, param4; | |
128 | { | |
129 | int dummy, err = 0; | |
130 | struct inode *ip, *newip; | |
131 | int code; | |
132 | struct vnode *vp; | |
133 | ||
134 | AFS_STATCNT(afs_syscall_icreate); | |
135 | ||
136 | if (!afs_suser(NULL)) | |
137 | return (EPERM); | |
138 | ||
139 | code = getinode(0, (dev_t) dev, 2, &ip, &dummy); | |
140 | if (code) { | |
141 | return (ENOENT); | |
142 | } | |
143 | code = ialloc(ip, (ino_t) near_inode, 0, &newip); | |
144 | iput(ip); | |
145 | if (code) { | |
146 | return (code); | |
147 | } | |
148 | IN_LOCK(newip); | |
149 | newip->i_flag |= IACC | IUPD | ICHG; | |
150 | ||
151 | newip->i_nlink = 1; | |
152 | ||
153 | newip->i_mode = IFREG; | |
154 | ||
155 | IN_UNLOCK(newip); | |
156 | vp = ITOV(newip); | |
157 | VN_LOCK(vp); | |
158 | vp->v_type = VREG; | |
159 | VN_UNLOCK(vp); | |
160 | ||
161 | /* | |
162 | * if ( !vp->v_object) | |
163 | * { | |
164 | * extern struct vfs_ubcops ufs_ubcops; | |
165 | * extern struct vm_ubc_object* ubc_object_allocate(); | |
166 | * struct vm_ubc_object* vop; | |
167 | * vop = ubc_object_allocate(&vp, &ufs_ubcops, | |
168 | * vp->v_mount->m_funnel); | |
169 | * VN_LOCK(vp); | |
170 | * vp->v_object = vop; | |
171 | * VN_UNLOCK(vp); | |
172 | * } | |
173 | */ | |
174 | ||
175 | IN_LOCK(newip); | |
176 | /* newip->i_flags |= IC_XUID|IC_XGID; */ | |
177 | /* newip->i_flags &= ~IC_PROPLIST; */ | |
178 | newip->i_vicep1 = param1; | |
179 | if (param2 == 0x1fffffff /*INODESPECIAL*/) { | |
180 | newip->i_vicep2 = ((0x1fffffff << 3) + (param4 & 0x3)); | |
181 | newip->i_vicep3a = (u_short) (param3 >> 16); | |
182 | newip->i_vicep3b = (u_short) param3; | |
183 | } else { | |
184 | newip->i_vicep2 = | |
185 | (((param2 >> 16) & 0x1f) << 27) + | |
186 | (((param4 >> 16) & 0x1f) << 22) + (param3 & 0x3fffff); | |
187 | newip->i_vicep3a = (u_short) param4; | |
188 | newip->i_vicep3b = (u_short) param2; | |
189 | } | |
190 | newip->i_vicemagic = VICEMAGIC; | |
191 | ||
192 | *retval = newip->i_number; | |
193 | IN_UNLOCK(newip); | |
194 | iput(newip); | |
195 | return (code); | |
196 | } | |
197 | ||
198 | ||
199 | int | |
200 | afs_syscall_iopen(dev, inode, usrmod, retval) | |
201 | long *retval; | |
202 | int dev, inode, usrmod; | |
203 | { | |
204 | struct file *fp; | |
205 | struct inode *ip; | |
206 | struct vnode *vp = NULL; | |
207 | int dummy; | |
208 | int fd; | |
209 | extern struct fileops vnops; | |
210 | int code; | |
211 | ||
212 | AFS_STATCNT(afs_syscall_iopen); | |
213 | ||
214 | if (!afs_suser(NULL)) | |
215 | return (EPERM); | |
216 | ||
217 | code = igetinode(0, (dev_t) dev, (ino_t) inode, &ip, &dummy); | |
218 | if (code) { | |
219 | return (code); | |
220 | } | |
221 | if ((code = falloc(curproc, &fp, &fd)) != 0) { | |
222 | iput(ip); | |
223 | return (code); | |
224 | } | |
225 | IN_UNLOCK(ip); | |
226 | ||
227 | /* FreeBSD doesn't do much mp stuff yet :( */ | |
228 | /* FP_LOCK(fp); */ | |
229 | fp->f_flag = (usrmod) & FMASK; | |
230 | fp->f_type = DTYPE_VNODE; | |
231 | fp->f_ops = &vnops; | |
232 | fp->f_data = (caddr_t) ITOV(ip); | |
233 | ||
234 | /* FP_UNLOCK(fp); */ | |
235 | return (0); | |
236 | } | |
237 | ||
238 | ||
239 | /* | |
240 | * Support for iinc() and idec() system calls--increment or decrement | |
241 | * count on inode. | |
242 | * Restricted to super user. | |
243 | * Only VICEMAGIC type inodes. | |
244 | */ | |
245 | int | |
246 | afs_syscall_iincdec(dev, inode, inode_p1, amount) | |
247 | int dev, inode, inode_p1, amount; | |
248 | { | |
249 | int dummy; | |
250 | struct inode *ip; | |
251 | int code; | |
252 | ||
253 | if (!afs_suser(NULL)) | |
254 | return (EPERM); | |
255 | ||
256 | code = igetinode(0, (dev_t) dev, (ino_t) inode, &ip, &dummy); | |
257 | if (code) { | |
258 | return (code); | |
259 | } | |
260 | if (!IS_VICEMAGIC(ip)) { | |
261 | return (EPERM); | |
262 | } else if (ip->i_vicep1 != inode_p1) { | |
263 | return (ENXIO); | |
264 | } | |
265 | ip->i_nlink += amount; | |
266 | if (ip->i_nlink == 0) { | |
267 | CLEAR_VICEMAGIC(ip); | |
268 | } | |
269 | ip->i_flag |= ICHG; | |
270 | iput(ip); | |
271 | return (0); | |
272 | } | |
273 | #else | |
274 | int | |
275 | afs_syscall_icreate(dev, near_inode, param1, param2, param3, param4, retval) | |
276 | long *retval; | |
277 | long dev, near_inode, param1, param2, param3, param4; | |
278 | { | |
279 | return EOPNOTSUPP; | |
280 | } | |
281 | ||
282 | int | |
283 | afs_syscall_iopen(dev, inode, usrmod, retval) | |
284 | long *retval; | |
285 | int dev, inode, usrmod; | |
286 | { | |
287 | return EOPNOTSUPP; | |
288 | } | |
289 | ||
290 | int | |
291 | afs_syscall_iincdec(dev, inode, inode_p1, amount) | |
292 | int dev, inode, inode_p1, amount; | |
293 | { | |
294 | return EOPNOTSUPP; | |
295 | } | |
296 | #endif |