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 */ |
---|