[16] | 1 | /*************************************************************************** |
---|
| 2 | * |
---|
| 3 | * Copyright (C) 2001 International Business Machines |
---|
| 4 | * All rights reserved. |
---|
| 5 | * |
---|
| 6 | * This file is part of the GPFS mmfslinux kernel module. |
---|
| 7 | * |
---|
| 8 | * Redistribution and use in source and binary forms, with or without |
---|
| 9 | * modification, are permitted provided that the following conditions |
---|
| 10 | * are met: |
---|
| 11 | * |
---|
| 12 | * 1. Redistributions of source code must retain the above copyright notice, |
---|
| 13 | * this list of conditions and the following disclaimer. |
---|
| 14 | * 2. Redistributions in binary form must reproduce the above copyright |
---|
| 15 | * notice, this list of conditions and the following disclaimer in the |
---|
| 16 | * documentation and/or other materials provided with the distribution. |
---|
| 17 | * 3. The name of the author may not be used to endorse or promote products |
---|
| 18 | * derived from this software without specific prior written |
---|
| 19 | * permission. |
---|
| 20 | * |
---|
| 21 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
---|
| 22 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
---|
| 23 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
---|
| 24 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
---|
| 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
---|
| 26 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; |
---|
| 27 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
---|
| 28 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
---|
| 29 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
---|
| 30 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
---|
| 31 | * |
---|
| 32 | *************************************************************************** */ |
---|
| 33 | /* @(#)09 1.126 src/avs/fs/mmfs/ts/kernext/ibm-linux/cxiTypes-plat.h, mmfs, avs_rgpfs24, rgpfs240610b 11/15/05 13:25:02 */ |
---|
| 34 | /* |
---|
| 35 | * Definitions for system dependent types, Linux version |
---|
| 36 | * |
---|
| 37 | * Contents: |
---|
| 38 | * system dependent types |
---|
| 39 | * |
---|
| 40 | */ |
---|
| 41 | |
---|
| 42 | |
---|
| 43 | #ifndef _h_cxiTypes_plat |
---|
| 44 | #define _h_cxiTypes_plat |
---|
| 45 | |
---|
| 46 | #ifndef _h_cxiTypes |
---|
| 47 | #error Platform header (XXX-plat.h) should not be included directly |
---|
| 48 | #endif |
---|
| 49 | |
---|
| 50 | /* Use system types.h except in portability kernel code */ |
---|
| 51 | #if !defined(GPFS_GPL) || !defined(_KERNEL) |
---|
| 52 | #include <sys/types.h> |
---|
| 53 | #endif |
---|
| 54 | |
---|
| 55 | /* Suffix of a routine declaration to tell GCC to pass parameters in |
---|
| 56 | registers */ |
---|
| 57 | #ifdef GPFS_ARCH_I386 |
---|
| 58 | #define REGPARMS __attribute__((regparm(3))) |
---|
| 59 | #else |
---|
| 60 | #define REGPARMS |
---|
| 61 | #endif |
---|
| 62 | |
---|
| 63 | /* Inline functions to byte-swap integers of various sizes. These use |
---|
| 64 | assembler helpers on some architectures. If the input parameter is |
---|
| 65 | a constant, the GCC compiler will generate better code by compile-time |
---|
| 66 | optimization of a (complicated) expression involving shifts and masks |
---|
| 67 | rather than calling the inline asm code. */ |
---|
| 68 | #ifdef GPFS_ARCH_I386 |
---|
| 69 | static inline const UInt16 _asm_swap16(UInt16 val) |
---|
| 70 | { /* "q" means any of regs AX-DX, which are the only ones that can be |
---|
| 71 | addressed as bytes */ |
---|
| 72 | __asm__("xchgb %b0,%h0 # _asm_swap16" \ |
---|
| 73 | : "=q" (val) \ |
---|
| 74 | : "0" (val)); |
---|
| 75 | return val; |
---|
| 76 | } |
---|
| 77 | static inline UInt16 ByteSwap16(UInt16 val) |
---|
| 78 | { |
---|
| 79 | return __builtin_constant_p(val) |
---|
| 80 | ? _ByteSwap16(val) |
---|
| 81 | : _asm_swap16(val); |
---|
| 82 | } |
---|
| 83 | #else |
---|
| 84 | static inline UInt16 ByteSwap16(UInt16 val) |
---|
| 85 | { |
---|
| 86 | return _ByteSwap16(val); |
---|
| 87 | } |
---|
| 88 | #endif |
---|
| 89 | |
---|
| 90 | |
---|
| 91 | #if defined(GPFS_ARCH_I386) || defined(GPFS_ARCH_X86_64) |
---|
| 92 | static inline const UInt32 _asm_swap32(UInt32 val) |
---|
| 93 | { |
---|
| 94 | __asm__("bswap %0 # _asm_swap32" \ |
---|
| 95 | : "=r" (val) \ |
---|
| 96 | : "0" (val)); |
---|
| 97 | return val; |
---|
| 98 | } |
---|
| 99 | static inline UInt32 ByteSwap32(UInt32 val) |
---|
| 100 | { |
---|
| 101 | return __builtin_constant_p(val) |
---|
| 102 | ? _ByteSwap32(val) |
---|
| 103 | : _asm_swap32(val); |
---|
| 104 | } |
---|
| 105 | #elif defined(GPFS_ARCH_IA64) |
---|
| 106 | static inline UInt32 ByteSwap32(UInt32 val) |
---|
| 107 | { |
---|
| 108 | UInt64 swapval1 = (UInt64)val, swapval2; |
---|
| 109 | __asm__("shl %0=%1,32;;" |
---|
| 110 | : "=r"(swapval2) |
---|
| 111 | : "r"(swapval1) ); |
---|
| 112 | __asm__("mux1 %0=%1,@rev" |
---|
| 113 | : "=r"(swapval1) |
---|
| 114 | : "r"(swapval2) ); |
---|
| 115 | return (UInt32)swapval1; |
---|
| 116 | } |
---|
| 117 | #else |
---|
| 118 | static inline UInt32 ByteSwap32(UInt32 val) |
---|
| 119 | { |
---|
| 120 | return _ByteSwap32(val); |
---|
| 121 | } |
---|
| 122 | #endif |
---|
| 123 | |
---|
| 124 | |
---|
| 125 | #ifdef GPFS_ARCH_I386 |
---|
| 126 | /* Use an external assembler routine to do the swap, since inline |
---|
| 127 | assembler either generates poor code or incorrect code in some cases. |
---|
| 128 | The inline asembler is preserved in tasking/i386/swap.S. */ |
---|
| 129 | EXTERNC const UInt64 _asm_swap64(UInt64 val) REGPARMS; |
---|
| 130 | static inline UInt64 ByteSwap64(UInt64 val) |
---|
| 131 | { |
---|
| 132 | return __builtin_constant_p(val) |
---|
| 133 | ? _ByteSwap64(val) |
---|
| 134 | : _asm_swap64(val); |
---|
| 135 | } |
---|
| 136 | #elif defined(GPFS_ARCH_IA64) |
---|
| 137 | static inline UInt64 ByteSwap64(UInt64 val) |
---|
| 138 | { |
---|
| 139 | UInt64 swapval; |
---|
| 140 | __asm__("mux1 %0=%1,@rev" |
---|
| 141 | : "=r"(swapval) |
---|
| 142 | : "r"(val) ); |
---|
| 143 | return swapval; |
---|
| 144 | } |
---|
| 145 | #elif defined(GPFS_ARCH_X86_64) |
---|
| 146 | static inline UInt64 ByteSwap64(UInt64 val) |
---|
| 147 | { |
---|
| 148 | UInt64 swapval = val; |
---|
| 149 | __asm__("bswap %0" |
---|
| 150 | : "=r"(swapval) |
---|
| 151 | : "0"(swapval) ); |
---|
| 152 | return swapval; |
---|
| 153 | } |
---|
| 154 | #else |
---|
| 155 | static inline UInt64 ByteSwap64(UInt64 val) |
---|
| 156 | { |
---|
| 157 | return _ByteSwap64(val); |
---|
| 158 | } |
---|
| 159 | #endif /* GPFS_ARCH_I386 */ |
---|
| 160 | |
---|
| 161 | |
---|
| 162 | /* On little-endian machines, declare classes for big-endian integers |
---|
| 163 | of various sizes. Each class provides operator= and integer cast |
---|
| 164 | operators, so the compiler will insert code to do conversions |
---|
| 165 | automatically when evaluating expressions involving big-endian |
---|
| 166 | integers. When passing a BigEndIntxx as a value parameter to a |
---|
| 167 | function without a prototype for its arguments, be sure to explicitly |
---|
| 168 | cast to the corresponding native arithmetic type. Otherwise, passing |
---|
| 169 | the class instance by value will result in the wrong byte order in |
---|
| 170 | the called routine. This most often occurs with printf and related |
---|
| 171 | functions. Notice that the code generated by TRACEn macros already |
---|
| 172 | contains such an explicit cast, so no case is needed in the source |
---|
| 173 | code. */ |
---|
| 174 | #ifdef __cplusplus |
---|
| 175 | # ifdef GPFS_LITTLE_ENDIAN |
---|
| 176 | |
---|
| 177 | class BigEndInt16 |
---|
| 178 | { |
---|
| 179 | private: |
---|
| 180 | Int16 val16; |
---|
| 181 | |
---|
| 182 | public: |
---|
| 183 | operator Int16() const |
---|
| 184 | { return ByteSwap16(val16); } |
---|
| 185 | BigEndInt16 operator=(Int16 newVal16) |
---|
| 186 | { val16 = ByteSwap16(newVal16); return *this; } |
---|
| 187 | int operator==(BigEndInt16 rhs) const |
---|
| 188 | { return val16 == rhs.val16; } |
---|
| 189 | int operator!=(BigEndInt16 rhs) const |
---|
| 190 | { return val16 != rhs.val16; } |
---|
| 191 | BigEndInt16 operator+=(Int16 inc) |
---|
| 192 | { val16 = ByteSwap16(ByteSwap16(val16)+inc); return *this; } |
---|
| 193 | BigEndInt16 operator-=(Int16 inc) |
---|
| 194 | { val16 = ByteSwap16(ByteSwap16(val16)-inc); return *this; } |
---|
| 195 | BigEndInt16 operator&=(Int16 mask) |
---|
| 196 | { val16 &= ByteSwap16(mask); return *this; } |
---|
| 197 | BigEndInt16 operator|=(Int16 mask) |
---|
| 198 | { val16 |= ByteSwap16(mask); return *this; } |
---|
| 199 | }; |
---|
| 200 | |
---|
| 201 | class BigEndUInt16 |
---|
| 202 | { |
---|
| 203 | private: |
---|
| 204 | UInt16 uval16; |
---|
| 205 | |
---|
| 206 | public: |
---|
| 207 | operator UInt16() const |
---|
| 208 | { return ByteSwap16(uval16); } |
---|
| 209 | BigEndUInt16 operator=(UInt16 newVal16) |
---|
| 210 | { uval16 = ByteSwap16(newVal16); return *this; } |
---|
| 211 | int operator==(BigEndUInt16 rhs) const |
---|
| 212 | { return uval16 == rhs.uval16; } |
---|
| 213 | int operator!=(BigEndUInt16 rhs) const |
---|
| 214 | { return uval16 != rhs.uval16; } |
---|
| 215 | BigEndUInt16 operator+=(UInt16 inc) |
---|
| 216 | { uval16 = ByteSwap16(ByteSwap16(uval16)+inc); return *this; } |
---|
| 217 | BigEndUInt16 operator-=(UInt16 inc) |
---|
| 218 | { uval16 = ByteSwap16(ByteSwap16(uval16)-inc); return *this; } |
---|
| 219 | BigEndUInt16 operator&=(UInt16 mask) |
---|
| 220 | { uval16 &= ByteSwap16(mask); return *this; } |
---|
| 221 | BigEndUInt16 operator|=(UInt16 mask) |
---|
| 222 | { uval16 |= ByteSwap16(mask); return *this; } |
---|
| 223 | }; |
---|
| 224 | |
---|
| 225 | class BigEndInt32 |
---|
| 226 | { |
---|
| 227 | private: |
---|
| 228 | Int32 val32; |
---|
| 229 | |
---|
| 230 | public: |
---|
| 231 | operator Int32() const |
---|
| 232 | { return ByteSwap32(val32); } |
---|
| 233 | BigEndInt32 operator=(Int32 newVal32) |
---|
| 234 | { val32 = ByteSwap32(newVal32); return *this; } |
---|
| 235 | int operator==(BigEndInt32 rhs) const |
---|
| 236 | { return val32 == rhs.val32; } |
---|
| 237 | int operator!=(BigEndInt32 rhs) const |
---|
| 238 | { return val32 != rhs.val32; } |
---|
| 239 | BigEndInt32 operator+=(Int32 inc) |
---|
| 240 | { val32 = ByteSwap32(ByteSwap32(val32)+inc); return *this; } |
---|
| 241 | BigEndInt32 operator-=(Int32 inc) |
---|
| 242 | { val32 = ByteSwap32(ByteSwap32(val32)-inc); return *this; } |
---|
| 243 | }; |
---|
| 244 | |
---|
| 245 | class BigEndUInt32 |
---|
| 246 | { |
---|
| 247 | private: |
---|
| 248 | UInt32 uval32; |
---|
| 249 | |
---|
| 250 | public: |
---|
| 251 | operator UInt32() const |
---|
| 252 | { return ByteSwap32(uval32); } |
---|
| 253 | BigEndUInt32 operator=(UInt32 newVal32) |
---|
| 254 | { uval32 = ByteSwap32(newVal32); return *this; } |
---|
| 255 | int operator==(BigEndUInt32 rhs) const |
---|
| 256 | { return uval32 == rhs.uval32; } |
---|
| 257 | int operator!=(BigEndUInt32 rhs) const |
---|
| 258 | { return uval32 != rhs.uval32; } |
---|
| 259 | BigEndUInt32 operator+=(UInt32 inc) |
---|
| 260 | { uval32 = ByteSwap32(ByteSwap32(uval32)+inc); return *this; } |
---|
| 261 | BigEndUInt32 operator-=(UInt32 inc) |
---|
| 262 | { uval32 = ByteSwap32(ByteSwap32(uval32)-inc); return *this; } |
---|
| 263 | BigEndUInt32 operator&=(UInt32 mask) |
---|
| 264 | { uval32 &= ByteSwap32(mask); return *this; } |
---|
| 265 | BigEndUInt32 operator|=(UInt32 mask) |
---|
| 266 | { uval32 |= ByteSwap32(mask); return *this; } |
---|
| 267 | BigEndUInt32 operator^=(UInt32 mask) |
---|
| 268 | { uval32 ^= ByteSwap32(mask); return *this; } |
---|
| 269 | }; |
---|
| 270 | |
---|
| 271 | class BigEndInt64 |
---|
| 272 | { |
---|
| 273 | private: |
---|
| 274 | Int64 val64; |
---|
| 275 | |
---|
| 276 | public: |
---|
| 277 | operator Int64() const |
---|
| 278 | { return ByteSwap64(val64); } |
---|
| 279 | BigEndInt64 operator=(Int64 newVal64) |
---|
| 280 | { val64 = ByteSwap64(newVal64); return *this; } |
---|
| 281 | int operator==(BigEndInt64 rhs) const |
---|
| 282 | { return val64 == rhs.val64; } |
---|
| 283 | int operator!=(BigEndInt64 rhs) const |
---|
| 284 | { return val64 != rhs.val64; } |
---|
| 285 | BigEndInt64 operator+=(Int64 inc) |
---|
| 286 | { val64 = ByteSwap64(ByteSwap64(val64)+inc); return *this; } |
---|
| 287 | BigEndInt64 operator-=(Int64 inc) |
---|
| 288 | { val64 = ByteSwap64(ByteSwap64(val64)-inc); return *this; } |
---|
| 289 | }; |
---|
| 290 | |
---|
| 291 | class BigEndUInt64 |
---|
| 292 | { |
---|
| 293 | private: |
---|
| 294 | UInt64 uval64; |
---|
| 295 | |
---|
| 296 | public: |
---|
| 297 | operator UInt64() const |
---|
| 298 | { return ByteSwap64(uval64); } |
---|
| 299 | BigEndUInt64 operator=(UInt64 newVal64) |
---|
| 300 | { uval64 = ByteSwap64(newVal64); return *this; } |
---|
| 301 | int operator==(BigEndUInt64 rhs) const |
---|
| 302 | { return uval64 == rhs.uval64; } |
---|
| 303 | int operator!=(BigEndUInt64 rhs) const |
---|
| 304 | { return uval64 != rhs.uval64; } |
---|
| 305 | BigEndUInt64 operator+=(UInt64 inc) |
---|
| 306 | { uval64 = ByteSwap64(ByteSwap64(uval64)+inc); return *this; } |
---|
| 307 | BigEndUInt64 operator-=(UInt64 inc) |
---|
| 308 | { uval64 = ByteSwap64(ByteSwap64(uval64)-inc); return *this; } |
---|
| 309 | }; |
---|
| 310 | # else /* GPFS_LITTLE_ENDIAN */ |
---|
| 311 | typedef Int16 BigEndInt16; |
---|
| 312 | typedef UInt16 BigEndUInt16; |
---|
| 313 | typedef Int32 BigEndInt32; |
---|
| 314 | typedef UInt32 BigEndUInt32; |
---|
| 315 | typedef Int64 BigEndInt64; |
---|
| 316 | typedef UInt64 BigEndUInt64; |
---|
| 317 | # endif /* GPFS_LITTLE_ENDIAN */ |
---|
| 318 | # else /* not __cplusplus */ |
---|
| 319 | typedef Int16 BigEndInt16; |
---|
| 320 | typedef UInt16 BigEndUInt16; |
---|
| 321 | typedef Int32 BigEndInt32; |
---|
| 322 | typedef UInt32 BigEndUInt32; |
---|
| 323 | typedef Int64 BigEndInt64; |
---|
| 324 | typedef UInt64 BigEndUInt64; |
---|
| 325 | #endif /* __cplusplus */ |
---|
| 326 | |
---|
| 327 | /* GPFS stores special file device numbers as 32 bit values |
---|
| 328 | * (the original AIX dev_t size). The cxiDev_t type is 64 bits |
---|
| 329 | * since this is the size of the user space dev_t and the prevalent |
---|
| 330 | * type that we're always presented with from the stat structure. |
---|
| 331 | */ |
---|
| 332 | typedef UInt64 cxiDev_t; /* user space dev_t definition */ |
---|
| 333 | |
---|
| 334 | typedef int cxiVmid_t; // dummy on Linux |
---|
| 335 | typedef UIntPtr cxiVmhandle_t; // try this for now |
---|
| 336 | |
---|
| 337 | /* Time types equivalent to linux definitions of time_t |
---|
| 338 | * and suseconds_t. |
---|
| 339 | */ |
---|
| 340 | typedef long int cxiNSec_t; |
---|
| 341 | typedef long int cxiTime_t; |
---|
| 342 | |
---|
| 343 | /* Type used as parameter of ATOMIC_ADD, etc. */ |
---|
| 344 | typedef int *atomic_p; |
---|
| 345 | /* Type used as parameter of ATOMIC_ADDLP, etc. */ |
---|
| 346 | typedef long *atomic_l; |
---|
| 347 | |
---|
| 348 | /* File offset */ |
---|
| 349 | typedef long long offset_t; |
---|
| 350 | |
---|
| 351 | /* Complex system types */ |
---|
| 352 | struct xmem |
---|
| 353 | { |
---|
| 354 | int x; |
---|
| 355 | }; |
---|
| 356 | |
---|
| 357 | /* Cross-memory descriptor */ |
---|
| 358 | typedef struct |
---|
| 359 | { |
---|
| 360 | /* Pointer to buffer descriptor object in kernel address space */ |
---|
| 361 | struct cxiKernelIOBufferDesc_t *kibdP; |
---|
| 362 | } cxiXmem_t; |
---|
| 363 | |
---|
| 364 | #ifdef _KERNEL |
---|
| 365 | #define CXIXMEM_TO_XMEM(_XMEM, _CXIXMEM) \ |
---|
| 366 | { \ |
---|
| 367 | memcpy(_XMEM, _CXIXMEM, sizeof(cxiXmem_t)); \ |
---|
| 368 | }; |
---|
| 369 | #endif |
---|
| 370 | |
---|
| 371 | /* Describes address space of a cxiUio_t buffer. |
---|
| 372 | * User address space buffers get extra validity |
---|
| 373 | * checking to ensure they are indeed in user space. |
---|
| 374 | */ |
---|
| 375 | #define UIO_SYSSPACE 1 |
---|
| 376 | #define UIO_USERSPACE 0 |
---|
| 377 | |
---|
| 378 | /* Structure representing a buffer in user space that needs to be accessed |
---|
| 379 | from kernel code. */ |
---|
| 380 | struct cxiUio_t |
---|
| 381 | { |
---|
| 382 | struct cxiIovec_t *uio_iov; /* ptr to array of iovec structs */ |
---|
| 383 | unsigned long uio_iovcnt; /* #iovec elements remaining to be processed */ |
---|
| 384 | unsigned long uio_iovdcnt;/* #iovec elements already processed */ |
---|
| 385 | offset_t uio_offset; /* byte offset in file/dev to read/write */ |
---|
| 386 | long uio_resid; /* #bytes left in data area */ |
---|
| 387 | short uio_segflg; /* description of which address space in use */ |
---|
| 388 | long uio_fmode; /* copy of file modes from open file struct */ |
---|
| 389 | cxiXmem_t *uio_xmem; /* dummy field for AIX compatibility */ |
---|
| 390 | }; |
---|
| 391 | |
---|
| 392 | #define UIO_XMEM 0 |
---|
| 393 | |
---|
| 394 | |
---|
| 395 | /* First parameter on return call to cxiFillDir(). This structure |
---|
| 396 | * describes the operating systems' filldir() routine and any uninterpreted |
---|
| 397 | * arguments that need to be passed back to it. The cxiFillDir() routine |
---|
| 398 | * has a static set of parameters that are passed to it, whereas the |
---|
| 399 | * Linux filldir() routine has changed signatures for different kernel |
---|
| 400 | * levels. We thus use cxiFillDir() in the portability layer to map |
---|
| 401 | * the arguments correctly to the Linux filldir(). |
---|
| 402 | */ |
---|
| 403 | typedef struct cxiFillDirArg_t |
---|
| 404 | { |
---|
| 405 | void *fnP; |
---|
| 406 | void *argP; |
---|
| 407 | } cxiFillDirArg_t; |
---|
| 408 | |
---|
| 409 | /* Callback function to return directory entries. |
---|
| 410 | * Called by readddir for each directory entry to be returned to the user. |
---|
| 411 | * Should return zero if the entry still fits in the user's buffer; |
---|
| 412 | * otherwise a negative value should be returned. The 'offset' parameter |
---|
| 413 | * is the logical offset of the current entry, i.e., a seekdir to that |
---|
| 414 | * offset followed by a readdir will return the same directory entry again. |
---|
| 415 | */ |
---|
| 416 | typedef int (*cxiFillDir_t)(void *, const char *, int, offset_t, ino_t); |
---|
| 417 | #define CALL_FILLDIR(fnP, argP, nameP, namelen, offset, ino) \ |
---|
| 418 | (*fnP)(argP, nameP, namelen, offset, ino) |
---|
| 419 | |
---|
| 420 | #define GPFS_DIR_EOF 0x7FFFFFFF |
---|
| 421 | |
---|
| 422 | /* Advisory locking types and defines */ |
---|
| 423 | typedef cxiFlock_t eflock_t; |
---|
| 424 | #define MNT_NFS 2 |
---|
| 425 | #define MNT_NFS3 18 |
---|
| 426 | #define MNT_RFS4 36 |
---|
| 427 | |
---|
| 428 | /* Define analagous kernel types here for now */ |
---|
| 429 | /* These should ONLY be used for typecasting kernel service call parms */ |
---|
| 430 | typedef cxiPid_t gpfs_Kpid_t; |
---|
| 431 | |
---|
| 432 | /* GPFS file types. These match the AIX vtype definitions from vnode.h */ |
---|
| 433 | enum cxiVtype { cxiVNON, cxiVREG, cxiVDIR, cxiVBLK, cxiVCHR, cxiVLNK, |
---|
| 434 | cxiVSOCK, cxiVBAD, cxiVFIFO, cxiVMPC }; |
---|
| 435 | #define cxiVUNDEF cxiVNON /* undefined is same as nothing */ |
---|
| 436 | typedef enum cxiVtype cxiVtype_t; |
---|
| 437 | |
---|
| 438 | /* Maximum size defined within Linux kernel for spinlock_t |
---|
| 439 | * We abstract this class to just a hunk of storage and let the OS |
---|
| 440 | * specific piece handle the implementation. |
---|
| 441 | */ |
---|
| 442 | #ifdef DEBUG_SPINLOCK |
---|
| 443 | # if defined (GPFS_ARCH_I386) |
---|
| 444 | # define SPINLOCK_T_SIZE 8 |
---|
| 445 | # elif defined(GPFS_ARCH_POWER) |
---|
| 446 | # define SPINLOCK_T_SIZE 12 |
---|
| 447 | # elif defined(GPFS_ARCH_IA64) |
---|
| 448 | # define SPINLOCK_T_SIZE 4 |
---|
| 449 | # elif defined(GPFS_ARCH_PPC64) |
---|
| 450 | # define SPINLOCK_T_SIZE 16 |
---|
| 451 | # elif defined(GPFS_ARCH_X86_64) |
---|
| 452 | # define SPINLOCK_T_SIZE 8 |
---|
| 453 | # endif |
---|
| 454 | #else |
---|
| 455 | #if defined(GPFS_ARCH_PPC64) && (LINUX_KERNEL_VERSION >= 2042100) |
---|
| 456 | #define SPINLOCK_T_SIZE 8 |
---|
| 457 | #elif defined(GPFS_ARCH_X86_64) |
---|
| 458 | /* Same size as DEBUG_SPINLOCK |
---|
| 459 | * Changing this size requires an adjustment of CXINODE_SIZE |
---|
| 460 | */ |
---|
| 461 | #define SPINLOCK_T_SIZE 8 |
---|
| 462 | #elif defined(GPFS_ARCH_I386) |
---|
| 463 | /* Same size as DEBUG_SPINLOCK */ |
---|
| 464 | #define SPINLOCK_T_SIZE 8 |
---|
| 465 | #else |
---|
| 466 | #define SPINLOCK_T_SIZE 4 |
---|
| 467 | #endif |
---|
| 468 | #endif |
---|
| 469 | |
---|
| 470 | /* Base VFS node class portion that is OS specific. |
---|
| 471 | * Consult gpfsNode_t for full definition |
---|
| 472 | */ |
---|
| 473 | typedef struct cxiNode_t |
---|
| 474 | { |
---|
| 475 | void *osNodeP; /* pointer to operating system specific inode */ |
---|
| 476 | enum cxiVtype nType; /* directory, link, file, dev */ |
---|
| 477 | int mapReadCount; /* count of map for read */ |
---|
| 478 | int mapWriteCount; /* count of map for write */ |
---|
| 479 | int readCount; /* total opens for read */ |
---|
| 480 | int icValid; /* CXI_IC_XXX flags (see definitions below) */ |
---|
| 481 | int xinfo; /* Extended info bits (see va_xinfo definition) */ |
---|
| 482 | void *nfsP; /* nfs information */ |
---|
| 483 | unsigned long ctFlags; |
---|
| 484 | cxiThreadId createRaceLoserThreadId; /* Set if file exist */ |
---|
| 485 | } cxiNode_t; |
---|
| 486 | |
---|
| 487 | /* various ctFlags */ |
---|
| 488 | #define mmapFlush 1 /* True if nopage/mmFlush in progress */ |
---|
| 489 | #define destroyIfDelInode 2 /* True if file should be destroyed |
---|
| 490 | in gpfs_s_delete_inode */ |
---|
| 491 | #define invalidateCalled 4 /* True if OSNode on hash chain has |
---|
| 492 | been invalidated on this pass. */ |
---|
| 493 | #define pruneDCacheNeeded 8 |
---|
| 494 | |
---|
| 495 | #define SetCtFlag(cnP,flag_bit) cxiSetBit(&(cnP)->ctFlags,flag_bit) |
---|
| 496 | #define ClearCtFlag(cnP,flag_bit) cxiClearBit(&(cnP)->ctFlags,flag_bit) |
---|
| 497 | #define TestCtFlag(cnP,flag_bit) cxiTestBit(&(cnP)->ctFlags,flag_bit) |
---|
| 498 | |
---|
| 499 | /* Size of a full gpfsNode_t */ |
---|
| 500 | #ifdef GPFS_ARCH_I386 |
---|
| 501 | # define CXINODE_SIZE (176 + SPINLOCK_T_SIZE) |
---|
| 502 | #endif |
---|
| 503 | |
---|
| 504 | #ifdef GPFS_ARCH_POWER |
---|
| 505 | # define CXINODE_SIZE (176 + SPINLOCK_T_SIZE) |
---|
| 506 | #endif |
---|
| 507 | |
---|
| 508 | #ifdef GPFS_ARCH_IA64 |
---|
| 509 | # define CXINODE_SIZE (260 + SPINLOCK_T_SIZE) |
---|
| 510 | #endif |
---|
| 511 | |
---|
| 512 | #ifdef GPFS_ARCH_PPC64 |
---|
| 513 | # if LINUX_KERNEL_VERSION < 2042100 |
---|
| 514 | # define CXINODE_SIZE (236 + SPINLOCK_T_SIZE) |
---|
| 515 | # else |
---|
| 516 | # define CXINODE_SIZE (232 + SPINLOCK_T_SIZE) |
---|
| 517 | # endif |
---|
| 518 | #endif |
---|
| 519 | #ifdef GPFS_ARCH_X86_64 |
---|
| 520 | /* Changing the non-debug size of SPINLOCK_T_SIZE |
---|
| 521 | * requires an adjustment of CXINODE_SIZE in order |
---|
| 522 | * to account for padding due to single or double word |
---|
| 523 | * alignment requirements of the architecture. |
---|
| 524 | */ |
---|
| 525 | # define CXINODE_SIZE (232 + SPINLOCK_T_SIZE) |
---|
| 526 | #endif |
---|
| 527 | |
---|
| 528 | /* Access OS dependent portion of cxiNode */ |
---|
| 529 | #define GNP_IS_DIR(GNP) ((GNP)->nType == cxiVDIR) |
---|
| 530 | #define GNP_IS_FILE(GNP) ((GNP)->nType == cxiVREG) |
---|
| 531 | #define GNP_IS_LINK(GNP) ((GNP)->nType == cxiVLNK) |
---|
| 532 | |
---|
| 533 | #define GNP_IS_STEALABLE(GNP) ((GNP)->osNodeP == NULL) |
---|
| 534 | #define GNP_RDCOUNT(GNP) ((GNP)->readCount) |
---|
| 535 | #define GNP_EXCOUNT(GNP) 0 |
---|
| 536 | #define GNP_MAP_RDCOUNT(GNP) ((GNP)->mapReadCount) |
---|
| 537 | #define GNP_MAP_WRCOUNT(GNP) ((GNP)->mapWriteCount) |
---|
| 538 | #define GNP_MAP_SEG(GNP) 0 |
---|
| 539 | #define GNP_CHANNEL(GNP) 0 |
---|
| 540 | #define GNP_TO_VP(GNP) ((struct inode *)((GNP)->osNodeP)) |
---|
| 541 | #define GP_TO_GNP(x) ((gpfsNode_t *)((x))) |
---|
| 542 | |
---|
| 543 | /* d_off and name length of Linux struct dirent */ |
---|
| 544 | #define CXI_DIR_D_OFFSET(deP) deP->d_off |
---|
| 545 | #define CXI_DIR_D_NAMLEN(deP) strlen(deP->d_name) |
---|
| 546 | |
---|
| 547 | /* Parameter passed to find_actor and read_inode2 through iget4 */ |
---|
| 548 | typedef struct cxiIGetArg_t |
---|
| 549 | { |
---|
| 550 | cxiIno_t extInodeNum; |
---|
| 551 | UInt32 inodeNum; |
---|
| 552 | UInt32 snapId; |
---|
| 553 | UInt32 filesetId; |
---|
| 554 | struct cxiVattr_t *vattrP; |
---|
| 555 | Boolean readInodeCalled; |
---|
| 556 | } cxiIGetArg_t; |
---|
| 557 | |
---|
| 558 | typedef struct cxiWaitList_t |
---|
| 559 | { |
---|
| 560 | struct cxiWaitList_t *nextP; |
---|
| 561 | struct cxiWaitList_t *prevP; |
---|
| 562 | } cxiWaitList_t; |
---|
| 563 | |
---|
| 564 | typedef struct cxiWaitEvent_t |
---|
| 565 | { |
---|
| 566 | /* List of wait elements. Wakeup is FIFO ordered with entries |
---|
| 567 | * entering the list at prevP and the first to be awaken at |
---|
| 568 | * nextP. |
---|
| 569 | */ |
---|
| 570 | cxiWaitList_t waitList; |
---|
| 571 | |
---|
| 572 | char lword[SPINLOCK_T_SIZE]; |
---|
| 573 | |
---|
| 574 | } cxiWaitEvent_t; |
---|
| 575 | |
---|
| 576 | #define LOCK_ALLOC_PIN 0 /* not used */ |
---|
| 577 | #define LOCK_ALLOC_PAGED 1 /* not used */ |
---|
| 578 | |
---|
| 579 | /* Needs to be changed to cxi name XXX */ |
---|
| 580 | typedef struct Simple_lock |
---|
| 581 | { |
---|
| 582 | int slCount; |
---|
| 583 | volatile unsigned int slState; |
---|
| 584 | |
---|
| 585 | /* Pointer into stack of owning thread. This is |
---|
| 586 | * sufficient to compute which thread owns the mutex. |
---|
| 587 | */ |
---|
| 588 | char* slOwnerP; |
---|
| 589 | |
---|
| 590 | cxiWaitEvent_t slEvent; |
---|
| 591 | } Simple_lock; |
---|
| 592 | |
---|
| 593 | |
---|
| 594 | /* Kernel-only mutexes. Largest possible size (including debug) */ |
---|
| 595 | #ifdef GPFS_ARCH_I386 |
---|
| 596 | #define GPFS_LINUX_SEM_SIZE 36 |
---|
| 597 | #endif |
---|
| 598 | #ifdef GPFS_ARCH_POWER |
---|
| 599 | #define GPFS_LINUX_SEM_SIZE 36 |
---|
| 600 | #endif |
---|
| 601 | #ifdef GPFS_ARCH_IA64 |
---|
| 602 | #define GPFS_LINUX_SEM_SIZE 56 |
---|
| 603 | #endif |
---|
| 604 | #ifdef GPFS_ARCH_PPC64 |
---|
| 605 | #define GPFS_LINUX_SEM_SIZE 32 |
---|
| 606 | #endif |
---|
| 607 | #ifdef GPFS_ARCH_X86_64 |
---|
| 608 | #define GPFS_LINUX_SEM_SIZE 32 |
---|
| 609 | #endif |
---|
| 610 | |
---|
| 611 | typedef struct cxiBlockingMutex_t |
---|
| 612 | { |
---|
| 613 | /* Space to store a Linux struct semaphore. If a semaphore does not fit |
---|
| 614 | in the space provided, the implementation should use this space as a |
---|
| 615 | pointer to a dynamically-allocated semaphore. */ |
---|
| 616 | char bmSem[GPFS_LINUX_SEM_SIZE]; |
---|
| 617 | |
---|
| 618 | /* Pointer into stack of owning thread. This is sufficient to compute |
---|
| 619 | which thread owns the mutex. */ |
---|
| 620 | char* bmOwnerP; |
---|
| 621 | |
---|
| 622 | /* Index of the name of this mutex */ |
---|
| 623 | int lockNameIndex; |
---|
| 624 | } cxiBlockingMutex_t; |
---|
| 625 | |
---|
| 626 | |
---|
| 627 | /* Structure encapsulating information about a particular physical disk */ |
---|
| 628 | struct cxiDiskInfo_t |
---|
| 629 | { |
---|
| 630 | Int64 totalSectors; /* number of sectors on disk */ |
---|
| 631 | int sectorSize; /* size of each physical sector in bytes */ |
---|
| 632 | }; |
---|
| 633 | |
---|
| 634 | typedef struct ucontext cxiSigContext_t; |
---|
| 635 | typedef struct siginfo cxiSigInfo_t; |
---|
| 636 | |
---|
| 637 | /* Type that should always correspond to the system ino_t */ |
---|
| 638 | typedef Int32 cxiInoSys_t; |
---|
| 639 | |
---|
| 640 | /* type to store disable_lock result. On Linux this is a machine |
---|
| 641 | state word, and should be unsigned long */ |
---|
| 642 | typedef unsigned long cxiIntrState_t; |
---|
| 643 | |
---|
| 644 | /* Work request for mmap pager kproc */ |
---|
| 645 | typedef struct _cxibuf_t |
---|
| 646 | { |
---|
| 647 | struct _cxibuf_t *av_forw; /* forward pointer */ |
---|
| 648 | struct _cxibuf_t *av_back; /* backward pointer */ |
---|
| 649 | struct page *pageP; /* pointer to the page being processed */ |
---|
| 650 | struct cxiNode_t *b_vp; |
---|
| 651 | struct MMFSVInfo *vinfoP; /* used by sendfile */ |
---|
| 652 | struct gpfsVfsData_t *privVfsP; |
---|
| 653 | caddr_t b_baddr; /* not used */ |
---|
| 654 | unsigned long b_flags; /* operation flag: see definitions below */ |
---|
| 655 | unsigned long b_blkno; /* file offset in PAGE_SIZE units */ |
---|
| 656 | int b_bcount; |
---|
| 657 | int b_error; |
---|
| 658 | void *b_inodeP; |
---|
| 659 | } cxibuf_t; |
---|
| 660 | |
---|
| 661 | /* b_flags flags. */ |
---|
| 662 | #define B_WRITE (long)0x0000 /* non-read pseudo-flag */ |
---|
| 663 | #define B_READ (long)0x0001 /* read when I/O occurs */ |
---|
| 664 | #define B_ERROR (long)0x0004 /* error detected */ |
---|
| 665 | #define B_ASYNC (long)0x0100 /* don't wait for I/O completion */ |
---|
| 666 | #define B_PFSTORE (long)0x2000 /* store operation */ |
---|
| 667 | #define B_PFPROT (long)0x4000 /* protection violation */ |
---|
| 668 | #define B_PFEOF (long)0x10000 /* check for ref. beyond end-of-file */ |
---|
| 669 | #define B_SENDFILE (long)0x20000 /* read from sendfile */ |
---|
| 670 | |
---|
| 671 | |
---|
| 672 | /* Define macros to cause code to be placed far away from the spot |
---|
| 673 | where it normally would be generated. This is typically used on |
---|
| 674 | whichever branch of an if is expected not to be executed in the common |
---|
| 675 | case. Moving rarely executed code away from the mainline code can help |
---|
| 676 | reduce I-cache misses, and therefore improve performance. Every |
---|
| 677 | BEGIN_FAR_CODE directive must be matched by an END_FAR_CODE directive, |
---|
| 678 | and they may not be nested. If FAR_CODE is not #defined, these macros |
---|
| 679 | are NOOPs. Use of the FAR_CODE option is not compatible with -g, and |
---|
| 680 | requires compiler options -fno-exceptions and -fno-defer-pop to insure |
---|
| 681 | that correct code is generated. */ |
---|
| 682 | #ifdef FAR_CODE |
---|
| 683 | # if defined(GPFS_ARCH_I386) |
---|
| 684 | # ifndef FAR_TRACE |
---|
| 685 | # error "-DFAR_CODE requires -DFAR_TRACE" |
---|
| 686 | # endif |
---|
| 687 | # define BEGIN_FAR_CODE __asm__( \ |
---|
| 688 | " jmp 9f\n" \ |
---|
| 689 | ".section .text.far,\"ax\"\n" \ |
---|
| 690 | "9:\n" \ |
---|
| 691 | ); |
---|
| 692 | # define END_FAR_CODE __asm__( \ |
---|
| 693 | " jmp 8f\n" \ |
---|
| 694 | ".section .text,\"ax\"\n" \ |
---|
| 695 | "8:\n" \ |
---|
| 696 | ); |
---|
| 697 | # elif defined(GPFS_ARCH_IA64) |
---|
| 698 | # ifndef FAR_TRACE |
---|
| 699 | # error "-DFAR_CODE requires -DFAR_TRACE" |
---|
| 700 | # endif |
---|
| 701 | /* Changing sections in the middle of a function is apparently a |
---|
| 702 | fairly bad thing to do for IA64 (screws up unwinding information, |
---|
| 703 | probably the debugging information, and also insn binding) and causes |
---|
| 704 | the gnu assembler to spew when optimizations are turned on. |
---|
| 705 | The gcc __buildin_expect(x,0) directive may be an alternative |
---|
| 706 | in the future, but this currently doesn't provide any performance |
---|
| 707 | enhancements with gcc 3.2, so we'll do nothing for now. */ |
---|
| 708 | #if 0 |
---|
| 709 | # define BEGIN_FAR_CODE __asm__( \ |
---|
| 710 | " (p0) br.cond.sptk.few 9f\n" \ |
---|
| 711 | ".section .text.far,\"ax\"\n" \ |
---|
| 712 | "9:\n" \ |
---|
| 713 | ); |
---|
| 714 | # define END_FAR_CODE __asm__( \ |
---|
| 715 | " (p0) br.cond.sptk.many 8f\n" \ |
---|
| 716 | ".section .text,\"ax\"\n" \ |
---|
| 717 | "8:\n" \ |
---|
| 718 | ); |
---|
| 719 | #endif |
---|
| 720 | # define BEGIN_FAR_CODE |
---|
| 721 | # define END_FAR_CODE |
---|
| 722 | # else |
---|
| 723 | # define BEGIN_FAR_CODE |
---|
| 724 | # define END_FAR_CODE |
---|
| 725 | # endif /* GPFS_ARCH_I386 */ |
---|
| 726 | #else |
---|
| 727 | # define BEGIN_FAR_CODE |
---|
| 728 | # define END_FAR_CODE |
---|
| 729 | #endif /* FAR_TRACE */ |
---|
| 730 | |
---|
| 731 | #ifndef EXTERNC |
---|
| 732 | #ifdef __cplusplus |
---|
| 733 | #define EXTERNC extern "C" |
---|
| 734 | #else |
---|
| 735 | #define EXTERNC extern |
---|
| 736 | #endif |
---|
| 737 | #endif /* EXTERNC */ |
---|
| 738 | |
---|
| 739 | /* |
---|
| 740 | Some macros to help catching certain problems at compile time vs at |
---|
| 741 | run time, to save time on unnecessary recompiles and reboots. This |
---|
| 742 | can be accomplished when operating on static data that has known (to |
---|
| 743 | the compiler) values at compile time, notably complex structure sizes. |
---|
| 744 | */ |
---|
| 745 | |
---|
| 746 | /* |
---|
| 747 | This macro asserts that both arguments have the same value. If the |
---|
| 748 | assertion is false, a compiler error about conflicting function |
---|
| 749 | declarations will be produced. |
---|
| 750 | */ |
---|
| 751 | |
---|
| 752 | #define STATIC_DBGASSERT(_a, _b) \ |
---|
| 753 | EXTERNC void __static_assert_dummy_func(int __FoO[][2]); \ |
---|
| 754 | EXTERNC void __static_assert_dummy_func(int __FoO[][_a/_b+_b/_a]); |
---|
| 755 | |
---|
| 756 | /* |
---|
| 757 | This macro could be used to trick g++ into telling you what is the |
---|
| 758 | size of a particular data type at compile time. It takes one argument |
---|
| 759 | that should be a valid argument for a sizeof operation, and produces |
---|
| 760 | a compiler error that will have size of the object included in the |
---|
| 761 | message. Only to be used during development, has to be disabled for |
---|
| 762 | the build to work. |
---|
| 763 | */ |
---|
| 764 | |
---|
| 765 | #define TELLSIZEOF(_a) \ |
---|
| 766 | EXTERNC void __static_tellsizeof_dummy_func(int __FoO[][1]); \ |
---|
| 767 | EXTERNC void __static_tellsizeof_dummy_func(int __FoO[][sizeof(_a)]); |
---|
| 768 | |
---|
| 769 | #endif /* _h_cxiTypes_plat */ |
---|