source: gpfs_3.1_ker2.6.20/lpp/mmfs/src/ibm-linux/cxiTypes-plat.h @ 16

Last change on this file since 16 was 16, checked in by rock, 16 years ago
File size: 25.8 KB
Line 
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 */
332typedef UInt64  cxiDev_t;        /* user space dev_t definition */
333
334typedef int cxiVmid_t;          // dummy on Linux
335typedef UIntPtr cxiVmhandle_t;  // try this for now
336
337/* Time types equivalent to linux definitions of time_t
338 * and suseconds_t.
339 */
340typedef long int cxiNSec_t;
341typedef long int cxiTime_t;
342
343/* Type used as parameter of ATOMIC_ADD, etc.  */
344typedef int    *atomic_p;
345/* Type used as parameter of ATOMIC_ADDLP, etc.  */
346typedef long   *atomic_l;
347
348/* File offset */
349typedef long long offset_t;
350
351/* Complex system types */
352struct xmem
353{
354  int x;
355};
356
357/* Cross-memory descriptor */
358typedef 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. */
380struct 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 */
403typedef 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 */
416typedef 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 */
423typedef 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 */
430typedef cxiPid_t gpfs_Kpid_t;
431
432/* GPFS file types.  These match the AIX vtype definitions from vnode.h */
433enum cxiVtype { cxiVNON, cxiVREG, cxiVDIR, cxiVBLK, cxiVCHR, cxiVLNK,
434                cxiVSOCK, cxiVBAD, cxiVFIFO, cxiVMPC };
435#define cxiVUNDEF cxiVNON   /* undefined is same as nothing */
436typedef 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 */
473typedef 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 */
548typedef 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
558typedef struct cxiWaitList_t
559{
560  struct cxiWaitList_t *nextP;
561  struct cxiWaitList_t *prevP; 
562} cxiWaitList_t;
563
564typedef 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 */
580typedef 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
611typedef 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 */
628struct cxiDiskInfo_t
629{
630  Int64 totalSectors;      /* number of sectors on disk */
631  int sectorSize;          /* size of each physical sector in bytes */
632};
633
634typedef struct ucontext cxiSigContext_t;
635typedef struct siginfo cxiSigInfo_t;
636
637/* Type that should always correspond to the system ino_t */
638typedef 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 */
642typedef unsigned long cxiIntrState_t;
643
644/* Work request for mmap pager kproc */
645typedef 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 */
Note: See TracBrowser for help on using the repository browser.