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 | #ifndef _AFS_OSI_ | |
11 | #define _AFS_OSI_ | |
12 | ||
13 | #include "h/types.h" | |
14 | #if !defined(AFS_LINUX26_ENV) | |
15 | #include "h/param.h" | |
16 | #endif | |
17 | ||
18 | #ifdef AFS_FBSD_ENV | |
19 | #include <sys/condvar.h> | |
20 | #endif | |
21 | ||
22 | #ifdef AFS_NBSD_ENV | |
23 | #include <sys/lock.h> | |
24 | #endif | |
25 | ||
26 | #ifdef AFS_LINUX20_ENV | |
27 | #ifndef _LINUX_CODA_FS_I | |
28 | #define _LINUX_CODA_FS_I | |
29 | #define _CODA_HEADER_ | |
30 | struct coda_inode_info { | |
31 | }; | |
32 | #endif | |
33 | #ifndef _LINUX_XFS_FS_I | |
34 | #define _LINUX_XFS_FS_I | |
35 | struct xfs_inode_info { | |
36 | }; | |
37 | #endif | |
38 | #include "h/fs.h" | |
39 | #include "h/mm.h" | |
40 | #endif | |
41 | ||
42 | #if defined(AFS_NBSD50_ENV) | |
43 | # if !defined(DEF_CADDR_T) | |
44 | typedef char * caddr_t; | |
45 | #define DEF_CADDR_T | |
46 | # endif | |
47 | #endif | |
48 | ||
49 | ||
50 | /* this is just a dummy type decl, we're really using struct sockets here */ | |
51 | struct osi_socket { | |
52 | int junk; | |
53 | }; | |
54 | ||
55 | struct osi_stat { | |
56 | afs_int32 size; /* file size in bytes */ | |
57 | afs_int32 mtime; /* modification date */ | |
58 | afs_int32 atime; /* access time */ | |
59 | }; | |
60 | ||
61 | struct osi_file { | |
62 | afs_int32 size; /* file size in bytes XXX Must be first field XXX */ | |
63 | #ifdef AFS_LINUX26_ENV | |
64 | struct file *filp; /* May need this if we really open the file. */ | |
65 | #else | |
66 | #ifdef AFS_LINUX22_ENV | |
67 | struct dentry dentry; /* merely to hold the pointer to the inode. */ | |
68 | struct file file; /* May need this if we really open the file. */ | |
69 | #else | |
70 | struct vnode *vnode; | |
71 | #endif | |
72 | #endif | |
73 | #if defined(AFS_HPUX102_ENV) | |
74 | k_off_t offset; | |
75 | #else | |
76 | #if defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL) | |
77 | afs_offs_t offset; | |
78 | #else | |
79 | afs_int32 offset; | |
80 | #endif | |
81 | #endif | |
82 | int (*proc) (struct osi_file * afile, afs_int32 code); /* proc, which, if not null, is called on writes */ | |
83 | char *rock; /* rock passed to proc */ | |
84 | #if defined(UKERNEL) | |
85 | int fd; /* file descriptor for user space files */ | |
86 | #endif /* defined(UKERNEL) */ | |
87 | }; | |
88 | ||
89 | struct osi_dev { | |
90 | #if defined(AFS_XBSD_ENV) | |
91 | struct mount *mp; | |
92 | struct vnode *held_vnode; | |
93 | #elif defined(AFS_AIX42_ENV) | |
94 | dev_t dev; | |
95 | #else | |
96 | afs_int32 dev; | |
97 | #endif | |
98 | }; | |
99 | ||
100 | struct afs_osi_WaitHandle { | |
101 | #ifdef AFS_FBSD_ENV | |
102 | struct cv wh_condvar; | |
103 | int wh_inited; | |
104 | #else | |
105 | caddr_t proc; /* process waiting */ | |
106 | #endif | |
107 | }; | |
108 | ||
109 | #define osi_SetFileProc(x,p) ((x)->proc=(p)) | |
110 | #define osi_SetFileRock(x,r) ((x)->rock=(r)) | |
111 | #define osi_GetFileProc(x) ((x)->proc) | |
112 | #define osi_GetFileRock(x) ((x)->rock) | |
113 | ||
114 | #ifdef AFS_TEXT_ENV | |
115 | #define osi_FlushText(vp) if (hcmp((vp)->f.m.DataVersion, (vp)->flushDV) > 0) \ | |
116 | osi_FlushText_really(vp) | |
117 | #else | |
118 | #define osi_FlushText(vp) | |
119 | #endif | |
120 | ||
121 | ||
122 | #define AFSOP_STOP_RXEVENT 214 /* stop rx event deamon */ | |
123 | #define AFSOP_STOP_COMPLETE 215 /* afs has been shutdown */ | |
124 | #define AFSOP_STOP_RXK_LISTENER 217 /* stop rx listener daemon */ | |
125 | ||
126 | ||
127 | #define osi_NPACKETS 20 /* number of cluster pkts to alloc */ | |
128 | ||
129 | ||
130 | ||
131 | /* | |
132 | * Default vnode related macros | |
133 | * | |
134 | * Darwin, all of the BSDs, and Linux have their own | |
135 | */ | |
136 | #if !defined(AFS_DARWIN_ENV) && !defined(AFS_XBSD_ENV) && !defined(AFS_LINUX20_ENV) | |
137 | # define vType(vc) AFSTOV(vc)->v_type | |
138 | # define vSetType(vc,type) AFSTOV(vc)->v_type = (type) | |
139 | # define vSetVfsp(vc,vfsp) AFSTOV(vc)->v_vfsp = (vfsp) | |
140 | extern struct vnodeops *afs_ops; | |
141 | # define IsAfsVnode(v) ((v)->v_op == afs_ops) | |
142 | # define SetAfsVnode(v) (v)->v_op = afs_ops | |
143 | #endif | |
144 | ||
145 | struct vcache; | |
146 | extern int osi_TryEvictVCache(struct vcache *, int *, int); | |
147 | extern struct vcache *osi_NewVnode(void); | |
148 | extern void osi_PrePopulateVCache(struct vcache *); | |
149 | extern void osi_PostPopulateVCache(struct vcache *); | |
150 | extern void osi_AttachVnode(struct vcache *, int seq); | |
151 | ||
152 | /* | |
153 | * In IRIX 6.5 and NetBSD we cannot have DEBUG turned on since certain | |
154 | * system-defined structures are a different size with DEBUG on, the | |
155 | * kernel is compiled without DEBUG on, and the resulting differences | |
156 | * would break our ability to interact with the rest of the kernel. | |
157 | * | |
158 | * Is DEBUG only for turning the ASSERT() macro? If so, we should | |
159 | * be able to eliminate DEBUG entirely. | |
160 | */ | |
161 | #if !defined(AFS_SGI65_ENV) && !defined(AFS_NBSD_ENV) | |
162 | #ifndef DEBUG | |
163 | #define DEBUG 1 /* Default is to enable debugging/logging */ | |
164 | #endif | |
165 | #endif | |
166 | ||
167 | /* | |
168 | * Time related macros | |
169 | */ | |
170 | #define osi_GetuTime(x) osi_GetTime(x) | |
171 | ||
172 | /* osi_timeval_t exists because SGI 6.x has two sizes of timeval. */ | |
173 | /** In 64 bit Solaris the timeval structure has members that are 64 bit | |
174 | * In the GetTime() interface we expect pointers to afs_int32. So the need to | |
175 | * define osi_timeval_t to have 32 bit members. To make this less ambiguous | |
176 | * we now use 32 bit quantities consistently all over the code. | |
177 | * In 64 bit HP-UX the timeval structure has a 64 bit member. | |
178 | */ | |
179 | ||
180 | #if defined(AFS_HPUX_ENV) || defined(AFS_LINUX_64BIT_KERNEL) || (defined(AFS_SGI61_ENV) && defined(KERNEL) && defined(_K64U64)) | |
181 | typedef struct { | |
182 | afs_int32 tv_sec; | |
183 | afs_int32 tv_usec; | |
184 | } osi_timeval_t; | |
185 | typedef struct { | |
186 | afs_int32 tv_sec; | |
187 | afs_int32 tv_usec; | |
188 | } osi_timeval32_t; | |
189 | #elif defined(AFS_SUN5_ENV) | |
190 | typedef struct timeval32 osi_timeval_t; | |
191 | typedef struct timeval32 osi_timeval32_t; | |
192 | #else | |
193 | typedef struct timeval osi_timeval_t; | |
194 | typedef struct timeval osi_timeval32_t; | |
195 | #endif /* AFS_SGI61_ENV */ | |
196 | ||
197 | #ifndef UKERNEL | |
198 | #define osi_getpid() getpid() | |
199 | #endif | |
200 | ||
201 | /* | |
202 | * osi_ThreadUnique() should yield a value that can be found in ps | |
203 | * output in order to draw correspondences between ICL traces and what | |
204 | * is going on in the system. So if ps cannot show thread IDs it is | |
205 | * likely to be the process ID instead. | |
206 | */ | |
207 | #ifdef AFS_FBSD_ENV | |
208 | /* should use curthread, but 'ps' can't display it */ | |
209 | #define osi_ThreadUnique() (curproc->p_pid) | |
210 | #elif defined(UKERNEL) | |
211 | #define osi_ThreadUnique() osi_getpid() | |
212 | #else | |
213 | #define osi_ThreadUnique() getpid() | |
214 | #endif | |
215 | ||
216 | ||
217 | ||
218 | #ifdef AFS_GLOBAL_SUNLOCK | |
219 | #define AFS_ASSERT_GLOCK() \ | |
220 | do { if (!ISAFS_GLOCK()) osi_Panic("afs global lock not held at %s:%d\n", __FILE__, __LINE__); } while (0) | |
221 | #endif /* AFS_GLOBAL_SUNLOCK */ | |
222 | ||
223 | #ifdef RX_ENABLE_LOCKS | |
224 | #define RX_AFS_GLOCK() AFS_GLOCK() | |
225 | #define RX_AFS_GUNLOCK() AFS_GUNLOCK() | |
226 | #else | |
227 | #define RX_AFS_GLOCK() | |
228 | #define RX_AFS_GUNLOCK() | |
229 | #endif | |
230 | ||
231 | ||
232 | ||
233 | #ifndef KERNEL | |
234 | #define AFS_GLOCK() | |
235 | #define AFS_GUNLOCK() | |
236 | #define ISAFS_GLOCK() 1 | |
237 | #define AFS_ASSERT_GLOCK() | |
238 | #endif | |
239 | ||
240 | /* On an MP that uses multithreading, splnet is not sufficient to provide | |
241 | * mutual exclusion because the other processors will not see it. On some | |
242 | * early multiprocessors (SunOS413 & SGI5.2) splnet actually obtains a global | |
243 | * mutex, which this works in the UP expected way, it means that the whole MP | |
244 | * can only take one interrupt at a time; a serious performance penalty. */ | |
245 | ||
246 | #if ((defined(AFS_GLOBAL_SUNLOCK) || defined(RX_ENABLE_LOCKS)) && !defined(AFS_HPUX_ENV)) || !defined(KERNEL) | |
247 | #define SPLVAR | |
248 | #define NETPRI | |
249 | #define USERPRI | |
250 | #endif | |
251 | ||
252 | /* | |
253 | * vnode/vcache ref count manipulation | |
254 | */ | |
255 | #if defined(UKERNEL) | |
256 | #define AFS_RELE(vp) do { VN_RELE(vp); } while (0) | |
257 | #else /* defined(UKERNEL) */ | |
258 | #define AFS_RELE(vp) do { AFS_GUNLOCK(); VN_RELE(vp); AFS_GLOCK(); } while (0) | |
259 | #endif /* defined(UKERNEL) */ | |
260 | ||
261 | /* | |
262 | * For some reason we do bare refcount manipulation in some places, for some | |
263 | * platforms. The assumption is apparently that either we wouldn't call | |
264 | * afs_inactive anyway (because we know the ref count is high), or that it's | |
265 | * OK not to call it (because we don't expect CUnlinked or CDirty). | |
266 | * (Also, of course, the vnode is assumed to be one of ours. Can't use this | |
267 | * macro for V-file vnodes.) | |
268 | */ | |
269 | /* osi_vnhold is defined in PLATFORM/osi_machdep.h */ | |
270 | #define AFS_FAST_HOLD(vp) osi_vnhold((vp), 0) | |
271 | ||
272 | #ifdef AFS_AIX_ENV | |
273 | #define AFS_FAST_RELE(vp) VREFCOUNT_DEC(vp) | |
274 | #else | |
275 | #define AFS_FAST_RELE(vp) AFS_RELE(AFSTOV(vp)) | |
276 | #endif | |
277 | ||
278 | /* | |
279 | * MP safe versions of routines to copy memory between user space | |
280 | * and kernel space. Call these to avoid taking page faults while | |
281 | * holding the global lock. | |
282 | */ | |
283 | #if defined(CAST_USER_ADDR_T) && !defined(UKERNEL) && !defined(AFS_DARWIN100_ENV) | |
284 | #define __U(X) CAST_USER_ADDR_T((X)) | |
285 | #else | |
286 | #define __U(X) (X) | |
287 | #endif | |
288 | #ifdef AFS_GLOBAL_SUNLOCK | |
289 | ||
290 | #define AFS_COPYIN(SRC,DST,LEN,CODE) \ | |
291 | do { \ | |
292 | int haveGlock = ISAFS_GLOCK(); \ | |
293 | if (haveGlock) \ | |
294 | AFS_GUNLOCK(); \ | |
295 | CODE = copyin(__U((SRC)),(DST),(LEN)); \ | |
296 | if (haveGlock) \ | |
297 | AFS_GLOCK(); \ | |
298 | } while(0) | |
299 | ||
300 | #define AFS_COPYINSTR(SRC,DST,LEN,CNT,CODE) \ | |
301 | do { \ | |
302 | int haveGlock = ISAFS_GLOCK(); \ | |
303 | if (haveGlock) \ | |
304 | AFS_GUNLOCK(); \ | |
305 | CODE = copyinstr(__U((SRC)),(DST),(LEN),(CNT)); \ | |
306 | if (haveGlock) \ | |
307 | AFS_GLOCK(); \ | |
308 | } while(0) | |
309 | ||
310 | #define AFS_COPYOUT(SRC,DST,LEN,CODE) \ | |
311 | do { \ | |
312 | int haveGlock = ISAFS_GLOCK(); \ | |
313 | if (haveGlock) \ | |
314 | AFS_GUNLOCK(); \ | |
315 | CODE = copyout((SRC),__U((DST)),(LEN)); \ | |
316 | if (haveGlock) \ | |
317 | AFS_GLOCK(); \ | |
318 | } while(0) | |
319 | ||
320 | #if defined(AFS_DARWIN80_ENV) | |
321 | #define AFS_UIOMOVE(SRC,LEN,RW,UIO,CODE) \ | |
322 | do { \ | |
323 | int haveGlock = ISAFS_GLOCK(); \ | |
324 | if (haveGlock) \ | |
325 | AFS_GUNLOCK(); \ | |
326 | uio_setrw((UIO),(RW)); \ | |
327 | CODE = uiomove((SRC),(LEN),(UIO)); \ | |
328 | if (haveGlock) \ | |
329 | AFS_GLOCK(); \ | |
330 | } while(0) | |
331 | #else | |
332 | #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) | |
333 | #define AFS_UIOMOVE(SRC,LEN,RW,UIO,CODE) \ | |
334 | do { \ | |
335 | int haveGlock = ISAFS_GLOCK(); \ | |
336 | if (haveGlock) \ | |
337 | AFS_GUNLOCK(); \ | |
338 | (UIO)->uio_rw = (RW); \ | |
339 | CODE = uiomove((SRC),(LEN),(UIO)); \ | |
340 | if (haveGlock) \ | |
341 | AFS_GLOCK(); \ | |
342 | } while(0) | |
343 | #else | |
344 | #define AFS_UIOMOVE(SRC,LEN,RW,UIO,CODE) \ | |
345 | do { \ | |
346 | int haveGlock = ISAFS_GLOCK(); \ | |
347 | if (haveGlock) \ | |
348 | AFS_GUNLOCK(); \ | |
349 | CODE = uiomove((SRC),(LEN),(RW),(UIO)); \ | |
350 | if (haveGlock) \ | |
351 | AFS_GLOCK(); \ | |
352 | } while(0) | |
353 | #endif | |
354 | #endif /* AFS_DARWIN80_ENV */ | |
355 | ||
356 | #else /* AFS_GLOBAL_SUNLOCK */ | |
357 | ||
358 | #define AFS_COPYIN(SRC,DST,LEN,CODE) \ | |
359 | do { \ | |
360 | CODE = copyin(__U((SRC)),(DST),(LEN)); \ | |
361 | } while(0) | |
362 | ||
363 | #define AFS_COPYINSTR(SRC,DST,LEN,CNT,CODE) \ | |
364 | do { \ | |
365 | CODE = copyinstr(__U((SRC)),(DST),(LEN),(CNT)); \ | |
366 | } while(0) | |
367 | ||
368 | #define AFS_COPYOUT(SRC,DST,LEN,CODE) \ | |
369 | do { \ | |
370 | CODE = copyout((SRC),__U((DST)),(LEN)); \ | |
371 | } while(0) | |
372 | ||
373 | #if defined(AFS_DARWIN80_ENV) | |
374 | #define AFS_UIOMOVE(SRC,LEN,RW,UIO,CODE) \ | |
375 | do { \ | |
376 | uio_setrw((UIO),(RW)); \ | |
377 | CODE = uiomove((SRC),(LEN),(UIO)); \ | |
378 | } while(0) | |
379 | #elif defined(AFS_DARWIN_ENV) || (defined(AFS_XBSD_ENV) && !defined(AFS_NBSD40_ENV)) | |
380 | #define AFS_UIOMOVE(SRC,LEN,RW,UIO,CODE) \ | |
381 | do { \ | |
382 | (UIO)->uio_rw = (RW); \ | |
383 | CODE = uiomove((SRC),(LEN),(UIO)); \ | |
384 | } while(0) | |
385 | #else | |
386 | #define AFS_UIOMOVE(SRC,LEN,RW,UIO,CODE) \ | |
387 | do { \ | |
388 | CODE = uiomove((SRC),(LEN),(RW),(UIO)); \ | |
389 | } while(0) | |
390 | #endif | |
391 | ||
392 | #endif /* AFS_GLOBAL_SUNLOCK */ | |
393 | ||
394 | #ifdef AFS_DARWIN80_ENV | |
395 | #define AFS_UIO_OFFSET(uio) uio_offset(uio) | |
396 | #define AFS_UIO_RESID(uio) (int)uio_resid(uio) | |
397 | #define AFS_UIO_SETOFFSET(uio, off) uio_setoffset(uio, off) | |
398 | #define AFS_UIO_SETRESID(uio, val) uio_setresid(uio, val) | |
399 | #else | |
400 | #define AFS_UIO_OFFSET(uio) (uio)->uio_offset | |
401 | #define AFS_UIO_RESID(uio) (uio)->uio_resid | |
402 | #define AFS_UIO_SETOFFSET(uio, off) (uio)->uio_offset = off | |
403 | #define AFS_UIO_SETRESID(uio, val) (uio)->uio_resid = val | |
404 | #endif | |
405 | ||
406 | ||
407 | /* | |
408 | * encapsulation of kernel data structure accesses | |
409 | */ | |
410 | #ifndef UKERNEL | |
411 | #define setuerror(erval) u.u_error = (erval) | |
412 | #define getuerror() u.u_error | |
413 | #endif | |
414 | ||
415 | /* Macros for vcache/vnode and vfs arguments to vnode and vfs ops. | |
416 | * These are required for IRIX 6.4 and later, which pass behavior pointers. | |
417 | * Note that the _CONVERT routines get the ";" here so that argument lists | |
418 | * can have arguments after the OSI_x_CONVERT macro is called. | |
419 | */ | |
420 | #define OSI_VN_ARG(V) V | |
421 | #define OSI_VN_DECL(V) struct vnode *V | |
422 | #define OSI_VN_CONVERT(V) | |
423 | #define OSI_VC_ARG(V) V | |
424 | #define OSI_VC_DECL(V) struct vcache *V | |
425 | #define OSI_VC_CONVERT(V) | |
426 | #define OSI_VFS_ARG(V) V | |
427 | #define OSI_VFS_DECL(V) struct vfs *V | |
428 | #define OSI_VFS_CONVERT(V) | |
429 | ||
430 | ||
431 | /* | |
432 | ** Macro for Solaris 2.6 returns 1 if file is larger than 2GB; else returns 0 | |
433 | */ | |
434 | #define AfsLargeFileUio(uio) 0 | |
435 | #define AfsLargeFileSize(pos, off) 0 | |
436 | ||
437 | /* Now include system specific OSI header file. It will redefine macros | |
438 | * defined here as required by the OS. | |
439 | */ | |
440 | #include "osi_machdep.h" | |
441 | ||
442 | /* Declare any structures which use these macros after the OSI implementation | |
443 | * has had the opportunity to redefine them. | |
444 | */ | |
445 | extern afs_ucred_t afs_osi_cred, *afs_osi_credp; | |
446 | ||
447 | #ifndef osi_curcred | |
448 | #define osi_curcred() (u.u_cred) | |
449 | #endif | |
450 | ||
451 | #ifdef AFS_PAG_ONEGROUP_ENV | |
452 | #define AFS_NUMPAGGROUPS 1 | |
453 | #else | |
454 | #define AFS_NUMPAGGROUPS 2 | |
455 | #endif | |
456 | ||
457 | #endif /* _AFS_OSI_ */ |