afs: Set AFS_VFSFSID to a numerical value
[openafs.git] / src / afs / afs.h
index 413106c..407eb89 100644 (file)
@@ -20,6 +20,9 @@
 #include "afs/afs_consts.h"
 #endif
 
+/* jhash.h is a standalone header and is fine to pull into kernel code. */
+#include <opr/jhash.h>
+
 /*
  * afs_fsfragsize cannot be less than 1023, or some cache-tracking
  * calculations will be incorrect (since we track cache usage in kb).
 /* Upper bound on number of iovecs out uio routines will deal with. */
 #define        AFS_MAXIOVCNT       16
 
-
-extern int afs_shuttingdown;
+enum afs_shutdown_state {
+    AFS_RUNNING = 0,
+    AFS_FLUSHING_CB = 1,
+    AFS_SHUTDOWN = 2,
+};
+extern enum afs_shutdown_state afs_shuttingdown;
 
 /*
  * Macros to uniquely identify the AFS vfs struct
  */
 #define        AFS_VFSMAGIC            0x1234
-#if defined(AFS_SUN5_ENV) || defined(AFS_HPUX90_ENV) || defined(AFS_LINUX20_ENV)
-#define        AFS_VFSFSID             99
-#else
-#if defined(AFS_SGI_ENV)
-#define AFS_VFSFSID            afs_fstype
+
+#if defined(UKERNEL)
+# if defined(AFS_USR_AIX_ENV) || defined(AFS_USR_SGI_ENV)
+#  define AFS_VFSFSID          AFS_MOUNT_AFS
+# else
+#  define AFS_VFSFSID          99
+# endif
+#elif defined(AFS_SUN5_ENV) || defined(AFS_HPUX90_ENV) || defined(AFS_LINUX20_ENV)
+# define AFS_VFSFSID           99
+#elif defined(AFS_SGI_ENV)
+# define AFS_VFSFSID           afs_fstype
 #else
-#define        AFS_VFSFSID             AFS_MOUNT_AFS
-#endif
+# define AFS_VFSFSID           AFS_MOUNT_AFS
 #endif
+/* use this value for reporting total space, free space, etc.
+ * fake a high number to satisfy programs that use the statfs call to make sure
+ * that there's enough space in the device partition before storing something
+ * there. keep it just under 2^31, to try and be safe about not breaking
+ * stuff that looks at the amount of free space. */
+#define AFS_VFS_FAKEFREE (2147483647)
 
 /* Moved from VNOPS/afs_vnop_flocks so can be used in prototypes */
 #if     defined(AFS_HPUX102_ENV)
@@ -76,32 +94,35 @@ extern int afs_shuttingdown;
 #define        NSERVERS        16      /* hash table size for server table */
 #define        NVOLS           64      /* hash table size for volume table */
 #define        NFENTRIES       256     /* hash table size for disk volume table */
-#define        VCSIZE         1024     /* stat cache hash table size */
-#define        DCSIZE          512     /* disk cache hash table size */
+#define VCSIZEBITS     16      /* log of stat cache hash table size */
+#define        VCSIZE          (opr_jhash_size(VCSIZEBITS))
 #define CBRSIZE                512     /* call back returns hash table size */
 #define        PIGGYSIZE       1350    /* max piggyback size */
 #define        MAXVOLS         128     /* max vols we can store */
 #define        MAXSYSNAME      128     /* max sysname (i.e. @sys) size */
 #define MAXNUMSYSNAMES 32      /* max that current constants allow */
+#define MAXROOTVOLNAMELEN      64      /* max length of root volume name */
 #define        NOTOKTIMEOUT    (2*3600)        /* time after which to timeout conns sans tokens */
 #define        NOPAG           0xffffffff
 
 
 
 #define AFS_MAXCBRSCALL        32      /* max to return in a given call (must be <= AFSCBMAX) */
-#define        AFS_SALLOC_LOW_WATER    250     /* Min free blocks before allocating more */
-#define        AFS_LRALLOCSIZ  4096    /* "Large" allocated size */
 #define        VCACHE_FREE     5
+#define VCACHE_DYNAMIC_STRESSED 10000
+#define VCACHE_STRESS_LOGINTERVAL (60*60*4) /* 4 hours */
 #define        AFS_NRXPACKETS  80
 #define        AFS_RXDEADTIME  50
 #define AFS_HARDDEADTIME       120
-#define        AFS_IDLEDEADTIME        50
+#define        AFS_IDLEDEADTIME        1200
+#define AFS_IDLEDEADTIME_REP    180 /* more than fs's cb dead time */
 #define AFS_BLKBITS    12
 #define AFS_BLKSIZE    (1 << AFS_BLKBITS)
 
 extern afs_int32 afs_rx_deadtime;
 extern afs_int32 afs_rx_harddead;
 extern afs_int32 afs_rx_idledead;
+extern afs_int32 afs_rx_idledead_rep;
 
 struct sysname_info {
     char *name;
@@ -129,13 +150,12 @@ struct sysname_info {
 #define        BOP_FETCH       1       /* parm1 is chunk to get */
 #define        BOP_STORE       2       /* parm1 is chunk to store */
 #define        BOP_PATH        3       /* parm1 is path, parm2 is chunk to fetch */
-
-#if defined(AFS_CACHE_BYPASS)
 #define        BOP_FETCH_NOCACHE       4   /* parms are: vnode ptr, offset, segment ptr, addr, cred ptr */
-#endif
 #ifdef AFS_DARWIN_ENV
 #define        BOP_MOVE        5        /* ptr1 afs_uspc_param ptr2 sname ptr3 dname */
 #endif
+#define BOP_PARTIAL_STORE 6     /* parm1 is chunk to store */
+#define BOP_INVALIDATE_SEGMENTS 7 /* no parms: just uses the 'bp->vc' vcache */
 
 #define        B_DONTWAIT      1       /* On failure return; don't wait */
 
@@ -153,7 +173,8 @@ struct brequest {
     afs_ucred_t *cred; /* credentials to use for operation */
     afs_size_t size_parm[BPARMS];      /* random parameters */
     void *ptr_parm[BPARMS];    /* pointer parameters */
-    afs_int32 code;            /* return code */
+    afs_int32 code_raw;                /* return code from AFS routines */
+    afs_int32 code_checkcode;  /* the afs_CheckCode-translated code */
     short refCount;            /* use counter for this structure */
     char opcode;               /* what to do (store, fetch, etc) */
     char flags;                        /* free, etc */
@@ -177,7 +198,7 @@ struct VenusFid {
     struct AFSFid Fid;
 };
 
-/* Temporary struct to be passed between afs_fid and afs_vget; in SunOS4.x we can only pass a maximum of 10 bytes for a handle (we ideally need 16!) */
+/* Temporary struct to be passed between afs_fid and afs_vget */
 struct SmallFid {
     afs_int32 Volume;
     afs_int32 CellAndUnique;
@@ -245,6 +266,7 @@ struct vrequest {
     char tokenError;            /* a token error other than expired. */
     char idleError;             /* the server idled too long */
     char skipserver[AFS_MAXHOSTS];
+    afs_int32 lasterror[AFS_MAXHOSTS];
 };
 #define VOLMISSING 1
 #define VOLBUSY 2
@@ -383,6 +405,8 @@ struct unixuser {
 struct sa_conn_vector;
 typedef struct sa_conn_vector * p_sa_conn_vector; /* forward decl */
 
+#define CONN_REPLICATED 0x1
+
 struct afs_conn {
     int refCount;
     int activated;
@@ -406,6 +430,7 @@ struct sa_conn_vector {
     struct srvAddr *srvr;      /* server associated with this conn */
     short refCount;            /* reference count for allocation */
     unsigned short port;       /* port associated with this connection */
+    int flags;
 
     /* next connection to return when all in cvec are fully utilized */
     int select_index; 
@@ -438,6 +463,7 @@ struct srvAddr {
     struct srvAddr *next_sa;   /* another interface on same host */
     struct server *server;     /* back to parent */
     struct sa_conn_vector *conns;   /* All user connections to this server */
+    struct afs_conn *natping;
     afs_int32 sa_ip;           /* Host addr in network byte order */
     u_short sa_iprank;         /* indiv ip address priority */
     u_short sa_portal;         /* port addr in network byte order */
@@ -565,6 +591,7 @@ struct chservinfo {
 #define VBackup                        4       /* is this a backup volume? */
 #define VForeign               8       /* this is a non-afs volume */
 #define VPartVisible           16      /* Volume's partition is visible on the client */
+#define VHardMount             32      /* we are hard-mount waiting for the vol */
 
 enum repstate { not_busy, end_not_busy = 6, rd_busy, rdwr_busy, offline };
 
@@ -584,7 +611,7 @@ struct volume {
     afs_int32 roVol;
     afs_int32 backVol;
     afs_int32 rwVol;           /* For r/o vols, original read/write volume. */
-    afs_int32 accessTime;      /* last time we used it */
+    afs_int32 setupTime;       /* time volume was setup from vldb info */
     afs_int32 vtix;            /* volume table index */
     afs_int32 copyDate;                /* copyDate field, for tracking vol releases */
     afs_int32 expireTime;      /* for per-volume callbacks... */
@@ -622,7 +649,7 @@ struct SimpleLocks {
 #define CCore          0x00000010      /* storing a core file, needed since we don't get an open */
 #define CDirty         0x00000020      /* file has been modified since first open (... O_RDWR) */
 #define CSafeStore     0x00000040      /* close must wait for store to finish (should be in fd) */
-#define CMAPPED                0x00000080      /* Mapped files; primarily used by SunOS 4.0.x */
+#define CMAPPED                0x00000080      /* Mapped files */
 #define CNSHARE                0x00000100      /* support O_NSHARE semantics */
 #define CLied          0x00000200
 #define CTruth         0x00000400
@@ -642,15 +669,14 @@ struct SimpleLocks {
 #define CBulkStat      0x00020000      /* loaded by a bulk stat, and not ref'd since */
 #define CUnlinkedDel   0x00040000
 #define CVFlushed      0x00080000
-#ifdef AFS_LINUX22_ENV
-#define CPageWrite      0x00200000      /* to detect vm deadlock - linux */
-#elif defined(AFS_SGI_ENV)
+#if defined(AFS_SGI_ENV)
 #define CWritingUFS    0x00200000      /* to detect vm deadlock - used by sgi */
 #elif defined(AFS_DARWIN80_ENV)
 #define CEvent          0x00200000      /* to preclude deadlock when sending events */
 #endif
 #define CCreating      0x00400000      /* avoid needless store after open truncate */
 #define CPageHog       0x00800000      /* AIX - dumping large cores is a page hog. */
+#define CCorrupt       0x01000000      /* corrupt dir already reported */
 #define CDCLock                0x02000000      /* Vnode lock held over call to GetDownD */
 #define CBulkFetching  0x04000000      /* stats are being fetched by bulk stat */
 #define CExtendedFile  0x08000000      /* extended file via ftruncate call. */
@@ -681,7 +707,6 @@ struct SimpleLocks {
 
 /*... to be continued ...  */
 
-#if defined(AFS_CACHE_BYPASS)
 /* vcache (file) cachingStates bits */
 #define FCSDesireBypass   0x1  /* This file should bypass the cache */
 #define FCSBypass         0x2  /* This file is currently NOT being cached */
@@ -695,11 +720,12 @@ struct SimpleLocks {
                                                                                 * lock vcache (it's already locked) */
 #define TRANSSetManualBit              0x4     /* The Transition routine should set FCSManuallySet so that
                                                                         * filename checking does not override pioctl requests */
-#endif /* AFS_CACHE_BYPASS */
 
 #define        CPSIZE      2
 #if defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV)
 #define vrefCount   v->v_usecount
+#elif defined(AFS_SUN511_ENV)
+# define vrefCount v->v_count
 #else
 #define vrefCount   v.v_count
 #endif /* AFS_XBSD_ENV */
@@ -721,9 +747,9 @@ struct SimpleLocks {
 #else
 #define VREFCOUNT(v)           ((v)->vrefCount)
 #define VREFCOUNT_GT(v,y)     ((v)->vrefCount > (y))
-#define VREFCOUNT_SET(v, c)    (v)->vrefCount = c;
-#define VREFCOUNT_DEC(v)       (v)->vrefCount--;
-#define VREFCOUNT_INC(v)       (v)->vrefCount++;
+#define VREFCOUNT_SET(v, c)    (v)->vrefCount = c
+#define VREFCOUNT_DEC(v)       (v)->vrefCount--
+#define VREFCOUNT_INC(v)       (v)->vrefCount++
 #define d_unhash(d) list_empty(&(d)->d_hash)
 #define dget_locked(d) dget(d)
 #endif
@@ -747,7 +773,7 @@ struct nbvdata {
 };
 #define VTOAFS(v) ((((struct nbvdata *)((v)->v_data)))->afsvc)
 #define AFSTOV(vc) ((vc)->v)
-#elif defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV) || (defined(AFS_LINUX22_ENV) && !defined(STRUCT_SUPER_OPERATIONS_HAS_ALLOC_INODE))
+#elif defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_SUN511_ENV) || (defined(AFS_LINUX22_ENV) && !defined(STRUCT_SUPER_OPERATIONS_HAS_ALLOC_INODE))
 #define VTOAFS(v) ((struct vcache *)(v)->v_data)
 #define AFSTOV(vc) ((vc)->v)
 #else
@@ -796,6 +822,11 @@ struct fvcache {
     struct afs_vnuniq oldParent;
 };
 
+/* Values for 'mvstat' in struct vcache */
+#define AFS_MVSTAT_FILE (0x0) /* regular file or directory */
+#define AFS_MVSTAT_MTPT (0x1) /* mountpoint */
+#define AFS_MVSTAT_ROOT (0x2) /* volume root dir */
+
 #ifdef AFS_SUN5_ENV
 /*
  * This is for the multiPage field in struct vcache. Each one of these
@@ -816,7 +847,7 @@ struct multiPage_range {
  * !(avc->nextfree) && !avc->vlruq.next => (FreeVCList == avc->nextfree)
  */
 struct vcache {
-#if defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV) || (defined(AFS_LINUX22_ENV) && !defined(STRUCT_SUPER_OPERATIONS_HAS_ALLOC_INODE))
+#if defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_SUN511_ENV) || (defined(AFS_LINUX22_ENV) && !defined(STRUCT_SUPER_OPERATIONS_HAS_ALLOC_INODE))
     struct vnode *v;
 #else
     struct vnode v;            /* Has reference count in v.v_count */
@@ -846,9 +877,6 @@ struct vcache {
     krwlock_t rwlock;
     struct cred *credp;
 #endif
-#ifdef AFS_BOZONLOCK_ENV
-    afs_bozoLock_t pvnLock;    /* see locks.x */
-#endif
 #ifdef AFS_AIX32_ENV
     afs_lock_t pvmlock;
     vmhandle_t vmh;
@@ -873,7 +901,15 @@ struct vcache {
 #endif
 #endif
 
-    struct VenusFid *mvid;     /* Either parent dir (if root) or root (if mt pt) */
+    union {
+       char *silly_name;        /* For sillyrenamed regular files, the silly
+                                 * name the file was renamed to. */
+       struct VenusFid *target_root; /* For mountpoints, the fid of the root dir
+                                      * in the target volume. */
+       struct VenusFid *parent; /* For root dir vcaches, the fid of the
+                                 * parent dir. */
+    } mvid;
+
     char *linkData;            /* Link data if a symlink. */
     afs_hyper_t flushDV;       /* data version last flushed from text */
     afs_hyper_t mapDV;         /* data version last flushed from map */
@@ -890,16 +926,15 @@ struct vcache {
     short execsOrWriters;      /* The number of execs (if < 0) or writers (if > 0) of
                                 * this file. */
     short flockCount;          /* count of flock readers, or -1 if writer */
-    char mvstat;               /* 0->normal, 1->mt pt, 2->root. */
+    char mvstat;               /* see the AFS_MVSTAT_* constants */
+
+    char cachingStates;                        /* Caching policies for this file */
+    afs_uint32 cachingTransitions;             /* # of times file has flopped between caching and not */
 
-#if defined(AFS_CACHE_BYPASS)
-       char cachingStates;                     /* Caching policies for this file */
-       afs_uint32 cachingTransitions;          /* # of times file has flopped between caching and not */
 #if defined(AFS_LINUX24_ENV)
-       off_t next_seq_offset;  /* Next sequential offset (used by prefetch/readahead) */
-#else
-       off_t next_seq_blk_offset; /* accounted in blocks for Solaris & IRIX */
-#endif
+    off_t next_seq_offset;     /* Next sequential offset (used by prefetch/readahead) */
+#elif defined(AFS_SUN5_ENV) || defined(AFS_SGI65_ENV)
+    off_t next_seq_blk_offset; /* accounted in blocks for Solaris & IRIX */
 #endif
 
 #if    defined(AFS_SUN5_ENV)
@@ -926,6 +961,13 @@ struct vcache {
 #if defined(AFS_LINUX26_ENV)
     cred_t *cred;              /* last writer's cred */
 #endif
+#ifdef AFS_LINUX24_ENV
+    struct dentry *target_link; /* dentry we prefer, when we are redirecting
+                                 * all requests due to duplicate dentry aliases.
+                                 * See LINUX/osi_vnodeops.c. Note that this is
+                                 * NOT an actual reference to a dentry, so this
+                                 * pointer MUST NOT be dereferenced on its own. */
+#endif
     afs_int32 vc_error;                /* stash write error for this vnode. */
     int xlatordv;              /* Used by nfs xlator */
     afs_ucred_t *uncred;
@@ -937,7 +979,19 @@ struct vcache {
 #if !defined(UKERNEL)
     void *vpacRock;            /* used to read or write in visible partitions */
 #endif
+    afs_uint32 lastBRLWarnTime; /* last time we warned about byte-range locks */
+#ifdef AFS_LINUX26_ENV
+    spinlock_t pagewriter_lock;
+    struct list_head pagewriters;      /* threads that are writing vm pages */
+#endif
+};
+
+#ifdef AFS_LINUX26_ENV
+struct pagewriter {
+    struct list_head link;
+    pid_t writer;
 };
+#endif
 
 #define        DONT_CHECK_MODE_BITS    0
 #define        CHECK_MODE_BITS         1
@@ -1283,7 +1337,7 @@ struct afs_FetchOutput {
        avc->f.states |= CCore; /* causes close to be called later */ \
                                                                       \
        /* The cred and vnode holds will be released in afs_FlushActiveVcaches */  \
-       AFS_FAST_HOLD(avc);     /* So it won't disappear */           \
+       osi_Assert(osi_vnhold(avc) == 0);       /* So it won't disappear */        \
        CRKEEP(avc, acred); /* Should use a better place for the creds */ \
     }                                                                         \
     else {                                                                    \
@@ -1295,26 +1349,10 @@ struct afs_FetchOutput {
 
 #define        AFS_ZEROS   64          /* zero buffer */
 
-/*#define afs_DirtyPages(avc)  (((avc)->f.states & CDirty) || osi_VMDirty_p((avc)))*/
 #define        afs_DirtyPages(avc)     ((avc)->f.states & CDirty)
 
 #define afs_InReadDir(avc) (((avc)->f.states & CReadDir) && (avc)->readdir_pid == MyPidxx2Pid(MyPidxx))
 
-/* The PFlush algorithm makes use of the fact that Fid.Unique is not used in
-  below hash algorithms.  Change it if need be so that flushing algorithm
-  doesn't move things from one hash chain to another
-*/
-/* extern int afs_dhashsize; */
-#define        DCHash(v, c)    ((((v)->Fid.Vnode + (v)->Fid.Volume + (c))) & (afs_dhashsize-1))
-       /*Vnode, Chunk -> Hash table index */
-#define        DVHash(v)       ((((v)->Fid.Vnode + (v)->Fid.Volume )) & (afs_dhashsize-1))
-       /*Vnode -> Other hash table index */
-/* don't hash on the cell, our callback-breaking code sometimes fails to compute
-    the cell correctly, and only scans one hash bucket */
-#define        VCHash(fid)     (((fid)->Fid.Volume + (fid)->Fid.Vnode) & (VCSIZE-1))
-/* Hash only on volume to speed up volume callbacks. */
-#define VCHashV(fid) ((fid)->Fid.Volume & (VCSIZE-1))
-
 extern struct dcache **afs_indexTable; /*Pointers to in-memory dcache entries */
 extern afs_int32 *afs_indexUnique;     /*dcache entry Fid.Unique */
 extern afs_int32 *afs_dvnextTbl;       /*Dcache hash table links */
@@ -1381,9 +1419,14 @@ extern struct brequest afs_brs[NBRS];    /* request structures */
     (((rw) == UIO_WRITE) ? afs_write(avc, uio, io, cred, 1) : afs_read(avc, uio, cred, 1))
 
 /* Cache size truncation uses the following low and high water marks:
- * If the cache is more than 95% full (CM_DCACHECOUNTFREEPCT), the cache
- * truncation daemon is awakened and will free up space until the cache is 85%
- * (CM_DCACHESPACEFREEPCT - CM_DCACHEEXTRAPCT) full.
+ * If the cache is more than 90% full by space (CM_DCACHESPACEFREEPCT) or
+ * 95% full by # of chunks (CM_DCACHECOUNTFREEPCT), the cache truncation
+ * daemon is awakened and will start freeing space. The cache truncation
+ * daemon will continue to free space until the cache is at most 85% full
+ * by space (CM_DCACHESPACEFREEPCT - CM_DCACHEEXTRAPCT). The cache truncation
+ * daemon will also try to free space until the cache is at most 90% full by
+ * chunks (CM_DCACHECOUNTFREEPCT - CM_DCACHEEXTRAPCT), but the 85% space limit
+ * is the only limit that we must hit.
  * afs_UFSWrite and afs_GetDCache (when it needs to fetch data) will wait on
  * afs_WaitForCacheDrain if the cache is 98% (CM_WAITFORDRAINPCT) full.
  * afs_GetDownD wakes those processes once the cache is 95% full
@@ -1402,7 +1445,7 @@ extern struct brequest afs_brs[NBRS];     /* request structures */
 
 #define afs_CacheIsTooFull() \
     (afs_blocksUsed - afs_blocksDiscarded > \
-       PERCENT(CM_DCACHECOUNTFREEPCT, afs_cacheBlocks) || \
+       PERCENT(CM_DCACHESPACEFREEPCT, afs_cacheBlocks) || \
      afs_freeDCCount - afs_discardDCCount < \
        PERCENT(100 - CM_DCACHECOUNTFREEPCT, afs_cacheFiles))
 
@@ -1492,12 +1535,8 @@ struct afs_fakestat_state {
 };
 
 extern int afs_fakestat_enable;
-
-#ifdef AFS_MAXVCOUNT_ENV
+extern int afs_rmtsys_enable;
 extern int afsd_dynamic_vcaches;
-#else
-#define afsd_dynamic_vcaches 0
-#endif
 
 /*
  * Wrappers for access to credentials structure members
@@ -1558,4 +1597,36 @@ struct afssysa {
 extern int Afs_syscall(struct afssysa *uap, rval_t *rvp);
 #endif /* AFS_SUN5_ENV */
 
+/*
+ * Various definitions for osi_sleep and its event hash table
+ * DFBSD has no osi_sleep, and HPUX has its own hack for this stuff
+ */
+#define AFS_EVHASHSIZE 128     /* size of afs_evhasht, must be power of 2 */
+
+typedef struct afs_event {
+    struct afs_event *next;    /* next in hash chain */
+    char *event;               /* lwp event: an address */
+    int refcount;              /* Is it in use? */
+    int seq;                   /* Sequence number: this is incremented
+                                * by wakeup calls; wait will not return until
+                                * it changes */
+#if defined(AFS_AIX_ENV)
+    tid_t cond;
+#elif defined(AFS_DARWIN_ENV)
+# ifdef AFS_DARWIN80_ENV
+    lck_mtx_t *lck;
+    thread_t owner;
+# endif
+    /* no cond member */
+#elif defined(AFS_FBSD_ENV) || defined(AFS_OBSD_ENV)
+    int cond;                  /* "all this gluck should probably be replaced by CVs" */
+#elif defined(AFS_LINUX24_ENV)
+    wait_queue_head_t cond;
+#elif defined(AFS_NBSD_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV)
+    kcondvar_t cond;           /* Currently associated condition variable */
+#endif
+} afs_event_t;
+
+extern afs_event_t *afs_evhasht[AFS_EVHASHSIZE];       /* Hash table for events */
+
 #endif /* _AFS_H_ */