OpenAFS
OpenAFS distributed network file system
|
00001 /* 00002 * Copyright 2000, International Business Machines Corporation and others. 00003 * All Rights Reserved. 00004 * 00005 * This software has been released under the terms of the IBM Public 00006 * License. For details, see the LICENSE file in the top-level source 00007 * directory or online at http://www.openafs.org/dl/license10.html 00008 */ 00009 00010 #ifndef _AFS_OSI_ 00011 #define _AFS_OSI_ 00012 00013 #include "h/types.h" 00014 #include "h/param.h" 00015 00016 #ifdef AFS_FBSD_ENV 00017 #include <sys/condvar.h> 00018 #endif 00019 00020 #ifdef AFS_NBSD_ENV 00021 #include <sys/lock.h> 00022 #endif 00023 00024 #ifdef AFS_LINUX20_ENV 00025 #ifndef _LINUX_CODA_FS_I 00026 #define _LINUX_CODA_FS_I 00027 #define _CODA_HEADER_ 00028 struct coda_inode_info { 00029 }; 00030 #endif 00031 #ifndef _LINUX_XFS_FS_I 00032 #define _LINUX_XFS_FS_I 00033 struct xfs_inode_info { 00034 }; 00035 #endif 00036 #include "h/fs.h" 00037 #include "h/mm.h" 00038 #endif 00039 00040 #if defined(AFS_NBSD50_ENV) 00041 # if !defined(DEF_CADDR_T) 00042 typedef char * caddr_t; 00043 #define DEF_CADDR_T 00044 # endif 00045 #endif 00046 00047 00048 /* this is just a dummy type decl, we're really using struct sockets here */ 00049 struct osi_socket { 00050 int junk; 00051 }; 00052 00053 struct osi_stat { 00054 afs_int32 size; /* file size in bytes */ 00055 afs_int32 mtime; /* modification date */ 00056 afs_int32 atime; /* access time */ 00057 }; 00058 00059 struct osi_file { 00060 afs_int32 size; /* file size in bytes XXX Must be first field XXX */ 00061 #ifdef AFS_LINUX26_ENV 00062 struct file *filp; /* May need this if we really open the file. */ 00063 #else 00064 #ifdef AFS_LINUX22_ENV 00065 struct dentry dentry; /* merely to hold the pointer to the inode. */ 00066 struct file file; /* May need this if we really open the file. */ 00067 #else 00068 struct vnode *vnode; 00069 #endif 00070 #endif 00071 #if defined(AFS_HPUX102_ENV) 00072 k_off_t offset; 00073 #else 00074 #if defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL) 00075 afs_offs_t offset; 00076 #else 00077 afs_int32 offset; 00078 #endif 00079 #endif 00080 int (*proc) (struct osi_file * afile, afs_int32 code); /* proc, which, if not null, is called on writes */ 00081 char *rock; /* rock passed to proc */ 00082 #if defined(UKERNEL) 00083 int fd; /* file descriptor for user space files */ 00084 #endif /* defined(UKERNEL) */ 00085 }; 00086 00087 struct osi_dev { 00088 #if defined(AFS_XBSD_ENV) 00089 struct mount *mp; 00090 struct vnode *held_vnode; 00091 #elif defined(AFS_AIX42_ENV) 00092 dev_t dev; 00093 #else 00094 afs_int32 dev; 00095 #endif 00096 }; 00097 00098 struct afs_osi_WaitHandle { 00099 #ifdef AFS_FBSD_ENV 00100 struct cv wh_condvar; 00101 int wh_inited; 00102 #else 00103 caddr_t proc; /* process waiting */ 00104 #endif 00105 }; 00106 00107 #define osi_SetFileProc(x,p) ((x)->proc=(p)) 00108 #define osi_SetFileRock(x,r) ((x)->rock=(r)) 00109 #define osi_GetFileProc(x) ((x)->proc) 00110 #define osi_GetFileRock(x) ((x)->rock) 00111 00112 #ifdef AFS_TEXT_ENV 00113 #define osi_FlushText(vp) if (hcmp((vp)->f.m.DataVersion, (vp)->flushDV) > 0) \ 00114 osi_FlushText_really(vp) 00115 #else 00116 #define osi_FlushText(vp) 00117 #endif 00118 00119 00120 #define AFSOP_STOP_RXEVENT 214 /* stop rx event deamon */ 00121 #define AFSOP_STOP_COMPLETE 215 /* afs has been shutdown */ 00122 #define AFSOP_STOP_RXK_LISTENER 217 /* stop rx listener daemon */ 00123 00124 00125 #define osi_NPACKETS 20 /* number of cluster pkts to alloc */ 00126 00127 00128 00129 /* 00130 * Default vnode related macros 00131 * 00132 * Darwin, all of the BSDs, and Linux have their own 00133 */ 00134 #if !defined(AFS_DARWIN_ENV) && !defined(AFS_XBSD_ENV) && !defined(AFS_LINUX20_ENV) 00135 # define vType(vc) (vc)->v.v_type 00136 # define vSetType(vc,type) (vc)->v.v_type = (type) 00137 # define vSetVfsp(vc,vfsp) (vc)->v.v_vfsp = (vfsp) 00138 extern struct vnodeops *afs_ops; 00139 # define IsAfsVnode(v) ((v)->v_op == afs_ops) 00140 # define SetAfsVnode(v) (v)->v_op = afs_ops 00141 #endif 00142 00143 struct vcache; 00144 extern int osi_TryEvictVCache(struct vcache *, int *, int); 00145 extern struct vcache *osi_NewVnode(void); 00146 extern void osi_PrePopulateVCache(struct vcache *); 00147 extern void osi_PostPopulateVCache(struct vcache *); 00148 extern void osi_AttachVnode(struct vcache *, int seq); 00149 00150 /* 00151 * In IRIX 6.5 and NetBSD we cannot have DEBUG turned on since certain 00152 * system-defined structures are a different size with DEBUG on, the 00153 * kernel is compiled without DEBUG on, and the resulting differences 00154 * would break our ability to interact with the rest of the kernel. 00155 * 00156 * Is DEBUG only for turning the ASSERT() macro? If so, we should 00157 * be able to eliminate DEBUG entirely. 00158 */ 00159 #if !defined(AFS_SGI65_ENV) && !defined(AFS_NBSD_ENV) 00160 #ifndef DEBUG 00161 #define DEBUG 1 /* Default is to enable debugging/logging */ 00162 #endif 00163 #endif 00164 00165 /* 00166 * Time related macros 00167 */ 00168 #define osi_GetuTime(x) osi_GetTime(x) 00169 00170 /* osi_timeval_t exists because SGI 6.x has two sizes of timeval. */ 00178 #if defined(AFS_HPUX_ENV) || defined(AFS_LINUX_64BIT_KERNEL) || (defined(AFS_SGI61_ENV) && defined(KERNEL) && defined(_K64U64)) 00179 typedef struct { 00180 afs_int32 tv_sec; 00181 afs_int32 tv_usec; 00182 } osi_timeval_t; 00183 typedef struct { 00184 afs_int32 tv_sec; 00185 afs_int32 tv_usec; 00186 } osi_timeval32_t; 00187 #elif defined(AFS_SUN5_ENV) 00188 typedef struct timeval32 osi_timeval_t; 00189 typedef struct timeval32 osi_timeval32_t; 00190 #else 00191 typedef struct timeval osi_timeval_t; 00192 typedef struct timeval osi_timeval32_t; 00193 #endif /* AFS_SGI61_ENV */ 00194 00195 #ifndef UKERNEL 00196 #define osi_getpid() getpid() 00197 #endif 00198 00199 /* 00200 * osi_ThreadUnique() should yield a value that can be found in ps 00201 * output in order to draw correspondences between ICL traces and what 00202 * is going on in the system. So if ps cannot show thread IDs it is 00203 * likely to be the process ID instead. 00204 */ 00205 #ifdef AFS_FBSD_ENV 00206 /* should use curthread, but 'ps' can't display it */ 00207 #define osi_ThreadUnique() (curproc->p_pid) 00208 #elif defined(UKERNEL) 00209 #define osi_ThreadUnique() osi_getpid() 00210 #else 00211 #define osi_ThreadUnique() getpid() 00212 #endif 00213 00214 00215 00216 #ifdef AFS_GLOBAL_SUNLOCK 00217 #define AFS_ASSERT_GLOCK() \ 00218 do { if (!ISAFS_GLOCK()) osi_Panic("afs global lock not held at %s:%d\n", __FILE__, __LINE__); } while (0) 00219 #endif /* AFS_GLOBAL_SUNLOCK */ 00220 00221 #ifdef RX_ENABLE_LOCKS 00222 #define RX_AFS_GLOCK() AFS_GLOCK() 00223 #define RX_AFS_GUNLOCK() AFS_GUNLOCK() 00224 #else 00225 #define RX_AFS_GLOCK() 00226 #define RX_AFS_GUNLOCK() 00227 #endif 00228 00229 00230 00231 #ifndef KERNEL 00232 #define AFS_GLOCK() 00233 #define AFS_GUNLOCK() 00234 #define ISAFS_GLOCK() 1 00235 #define AFS_ASSERT_GLOCK() 00236 #endif 00237 00238 /* On an MP that uses multithreading, splnet is not sufficient to provide 00239 * mutual exclusion because the other processors will not see it. On some 00240 * early multiprocessors (SunOS413 & SGI5.2) splnet actually obtains a global 00241 * mutex, which this works in the UP expected way, it means that the whole MP 00242 * can only take one interrupt at a time; a serious performance penalty. */ 00243 00244 #if ((defined(AFS_GLOBAL_SUNLOCK) || defined(RX_ENABLE_LOCKS)) && !defined(AFS_HPUX_ENV)) || !defined(KERNEL) 00245 #define SPLVAR 00246 #define NETPRI 00247 #define USERPRI 00248 #endif 00249 00250 /* 00251 * vnode/vcache ref count manipulation 00252 */ 00253 #if defined(UKERNEL) 00254 #define AFS_RELE(vp) do { VN_RELE(vp); } while (0) 00255 #else /* defined(UKERNEL) */ 00256 #define AFS_RELE(vp) do { AFS_GUNLOCK(); VN_RELE(vp); AFS_GLOCK(); } while (0) 00257 #endif /* defined(UKERNEL) */ 00258 00259 /* 00260 * For some reason we do bare refcount manipulation in some places, for some 00261 * platforms. The assumption is apparently that either we wouldn't call 00262 * afs_inactive anyway (because we know the ref count is high), or that it's 00263 * OK not to call it (because we don't expect CUnlinked or CDirty). 00264 * (Also, of course, the vnode is assumed to be one of ours. Can't use this 00265 * macro for V-file vnodes.) 00266 */ 00267 /* osi_vnhold is defined in PLATFORM/osi_machdep.h */ 00268 #define AFS_FAST_HOLD(vp) osi_vnhold((vp), 0) 00269 00270 #ifdef AFS_AIX_ENV 00271 #define AFS_FAST_RELE(vp) VREFCOUNT_DEC(vp) 00272 #else 00273 #define AFS_FAST_RELE(vp) AFS_RELE(AFSTOV(vp)) 00274 #endif 00275 00276 /* 00277 * MP safe versions of routines to copy memory between user space 00278 * and kernel space. Call these to avoid taking page faults while 00279 * holding the global lock. 00280 */ 00281 #if defined(CAST_USER_ADDR_T) && !defined(UKERNEL) && !defined(AFS_DARWIN100_ENV) 00282 #define __U(X) CAST_USER_ADDR_T((X)) 00283 #else 00284 #define __U(X) (X) 00285 #endif 00286 #ifdef AFS_GLOBAL_SUNLOCK 00287 00288 #define AFS_COPYIN(SRC,DST,LEN,CODE) \ 00289 do { \ 00290 int haveGlock = ISAFS_GLOCK(); \ 00291 if (haveGlock) \ 00292 AFS_GUNLOCK(); \ 00293 CODE = copyin(__U((SRC)),(DST),(LEN)); \ 00294 if (haveGlock) \ 00295 AFS_GLOCK(); \ 00296 } while(0) 00297 00298 #define AFS_COPYINSTR(SRC,DST,LEN,CNT,CODE) \ 00299 do { \ 00300 int haveGlock = ISAFS_GLOCK(); \ 00301 if (haveGlock) \ 00302 AFS_GUNLOCK(); \ 00303 CODE = copyinstr(__U((SRC)),(DST),(LEN),(CNT)); \ 00304 if (haveGlock) \ 00305 AFS_GLOCK(); \ 00306 } while(0) 00307 00308 #define AFS_COPYOUT(SRC,DST,LEN,CODE) \ 00309 do { \ 00310 int haveGlock = ISAFS_GLOCK(); \ 00311 if (haveGlock) \ 00312 AFS_GUNLOCK(); \ 00313 CODE = copyout((SRC),__U((DST)),(LEN)); \ 00314 if (haveGlock) \ 00315 AFS_GLOCK(); \ 00316 } while(0) 00317 00318 #if defined(AFS_DARWIN80_ENV) 00319 #define AFS_UIOMOVE(SRC,LEN,RW,UIO,CODE) \ 00320 do { \ 00321 int haveGlock = ISAFS_GLOCK(); \ 00322 if (haveGlock) \ 00323 AFS_GUNLOCK(); \ 00324 uio_setrw((UIO),(RW)); \ 00325 CODE = uiomove((SRC),(LEN),(UIO)); \ 00326 if (haveGlock) \ 00327 AFS_GLOCK(); \ 00328 } while(0) 00329 #else 00330 #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) 00331 #define AFS_UIOMOVE(SRC,LEN,RW,UIO,CODE) \ 00332 do { \ 00333 int haveGlock = ISAFS_GLOCK(); \ 00334 if (haveGlock) \ 00335 AFS_GUNLOCK(); \ 00336 (UIO)->uio_rw = (RW); \ 00337 CODE = uiomove((SRC),(LEN),(UIO)); \ 00338 if (haveGlock) \ 00339 AFS_GLOCK(); \ 00340 } while(0) 00341 #else 00342 #define AFS_UIOMOVE(SRC,LEN,RW,UIO,CODE) \ 00343 do { \ 00344 int haveGlock = ISAFS_GLOCK(); \ 00345 if (haveGlock) \ 00346 AFS_GUNLOCK(); \ 00347 CODE = uiomove((SRC),(LEN),(RW),(UIO)); \ 00348 if (haveGlock) \ 00349 AFS_GLOCK(); \ 00350 } while(0) 00351 #endif 00352 #endif /* AFS_DARWIN80_ENV */ 00353 00354 #else /* AFS_GLOBAL_SUNLOCK */ 00355 00356 #define AFS_COPYIN(SRC,DST,LEN,CODE) \ 00357 do { \ 00358 CODE = copyin(__U((SRC)),(DST),(LEN)); \ 00359 } while(0) 00360 00361 #define AFS_COPYINSTR(SRC,DST,LEN,CNT,CODE) \ 00362 do { \ 00363 CODE = copyinstr(__U((SRC)),(DST),(LEN),(CNT)); \ 00364 } while(0) 00365 00366 #define AFS_COPYOUT(SRC,DST,LEN,CODE) \ 00367 do { \ 00368 CODE = copyout((SRC),__U((DST)),(LEN)); \ 00369 } while(0) 00370 00371 #if defined(AFS_DARWIN80_ENV) 00372 #define AFS_UIOMOVE(SRC,LEN,RW,UIO,CODE) \ 00373 do { \ 00374 uio_setrw((UIO),(RW)); \ 00375 CODE = uiomove((SRC),(LEN),(UIO)); \ 00376 } while(0) 00377 #elif defined(AFS_DARWIN_ENV) || (defined(AFS_XBSD_ENV) && !defined(AFS_NBSD40_ENV)) 00378 #define AFS_UIOMOVE(SRC,LEN,RW,UIO,CODE) \ 00379 do { \ 00380 (UIO)->uio_rw = (RW); \ 00381 CODE = uiomove((SRC),(LEN),(UIO)); \ 00382 } while(0) 00383 #else 00384 #define AFS_UIOMOVE(SRC,LEN,RW,UIO,CODE) \ 00385 do { \ 00386 CODE = uiomove((SRC),(LEN),(RW),(UIO)); \ 00387 } while(0) 00388 #endif 00389 00390 #endif /* AFS_GLOBAL_SUNLOCK */ 00391 00392 #ifdef AFS_DARWIN80_ENV 00393 #define AFS_UIO_OFFSET(uio) uio_offset(uio) 00394 #define AFS_UIO_RESID(uio) (int)uio_resid(uio) 00395 #define AFS_UIO_SETOFFSET(uio, off) uio_setoffset(uio, off) 00396 #define AFS_UIO_SETRESID(uio, val) uio_setresid(uio, val) 00397 #else 00398 #define AFS_UIO_OFFSET(uio) (uio)->uio_offset 00399 #define AFS_UIO_RESID(uio) (uio)->uio_resid 00400 #define AFS_UIO_SETOFFSET(uio, off) (uio)->uio_offset = off 00401 #define AFS_UIO_SETRESID(uio, val) (uio)->uio_resid = val 00402 #endif 00403 00404 00405 /* 00406 * encapsulation of kernel data structure accesses 00407 */ 00408 #ifndef UKERNEL 00409 #define setuerror(erval) u.u_error = (erval) 00410 #define getuerror() u.u_error 00411 #endif 00412 00413 /* Macros for vcache/vnode and vfs arguments to vnode and vfs ops. 00414 * These are required for IRIX 6.4 and later, which pass behavior pointers. 00415 * Note that the _CONVERT routines get the ";" here so that argument lists 00416 * can have arguments after the OSI_x_CONVERT macro is called. 00417 */ 00418 #define OSI_VN_ARG(V) V 00419 #define OSI_VN_DECL(V) struct vnode *V 00420 #define OSI_VN_CONVERT(V) 00421 #define OSI_VC_ARG(V) V 00422 #define OSI_VC_DECL(V) struct vcache *V 00423 #define OSI_VC_CONVERT(V) 00424 #define OSI_VFS_ARG(V) V 00425 #define OSI_VFS_DECL(V) struct vfs *V 00426 #define OSI_VFS_CONVERT(V) 00427 00428 00429 /* 00430 ** Macro for Solaris 2.6 returns 1 if file is larger than 2GB; else returns 0 00431 */ 00432 #define AfsLargeFileUio(uio) 0 00433 #define AfsLargeFileSize(pos, off) 0 00434 00435 /* Now include system specific OSI header file. It will redefine macros 00436 * defined here as required by the OS. 00437 */ 00438 #include "osi_machdep.h" 00439 00440 /* Declare any structures which use these macros after the OSI implementation 00441 * has had the opportunity to redefine them. 00442 */ 00443 extern afs_ucred_t afs_osi_cred, *afs_osi_credp; 00444 00445 #ifndef osi_curcred 00446 #define osi_curcred() (u.u_cred) 00447 #endif 00448 00449 #endif /* _AFS_OSI_ */