afs: increase idledead time
[openafs.git] / src / afs / afs.h
index 0c3b1c0..4c4873b 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright 2000, International Business Machines Corporation and others.
  * All Rights Reserved.
- * 
+ *
  * This software has been released under the terms of the IBM Public
  * License.  For details, see the LICENSE file in the top-level source
  * directory or online at http://www.openafs.org/dl/license10.html
  */
 #ifdef KDUMP_KERNEL
 #include <afs/afs_args.h>
+#include <afs/afs_consts.h>
 #else
 #include "afs/afs_args.h"
+#include "afs/afs_consts.h"
 #endif
 
+/*
+ * afs_fsfragsize cannot be less than 1023, or some cache-tracking
+ * calculations will be incorrect (since we track cache usage in kb).
+ * Some filesystems have fundamental blocksizes less than 1k, and
+ * normally we would tune afs_fsfragsize to be fragsize-1, but we must
+ * make sure to check that afs_fsfragsize does not go below this value.
+ */
+#define AFS_MIN_FRAGSIZE 1023
 
 /* Upper bound on number of iovecs out uio routines will deal with. */
 #define        AFS_MAXIOVCNT       16
@@ -43,7 +53,7 @@ extern int afs_shuttingdown;
 #if     defined(AFS_HPUX102_ENV)
 #define AFS_FLOCK       k_flock
 #else
-#if     defined(AFS_SUN56_ENV) || (defined(AFS_LINUX24_ENV) && !(defined(AFS_LINUX26_ENV) && defined(AFS_LINUX_64BIT_KERNEL)))
+#if     defined(AFS_SUN5_ENV) || (defined(AFS_LINUX24_ENV) && !(defined(AFS_LINUX26_ENV) && defined(AFS_LINUX_64BIT_KERNEL)))
 #define AFS_FLOCK       flock64
 #else
 #define AFS_FLOCK       flock
@@ -61,9 +71,6 @@ extern int afs_shuttingdown;
 
 /* The basic defines for the Andrew file system
     better keep things powers of two so "& (foo-1)" hack works for masking bits */
-#define        MAXHOSTS        13      /* max hosts per single volume */
-#define        OMAXHOSTS        8      /* backwards compatibility */
-#define MAXCELLHOSTS    8      /* max vldb servers per cell */
 #define        NBRS            15      /* max number of queued daemon requests */
 #define        NUSERS          16      /* hash table size for unixuser table */
 #define        NSERVERS        16      /* hash table size for server table */
@@ -75,18 +82,20 @@ extern int afs_shuttingdown;
 #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 16      /* max that current constants allow */
+#define MAXNUMSYSNAMES 32      /* max that current constants allow */
 #define        NOTOKTIMEOUT    (2*3600)        /* time after which to timeout conns sans tokens */
 #define        NOPAG           0xffffffff
-#define AFS_NCBRS      300     /* max # of call back return entries */
-#define AFS_MAXCBRSCALL        16      /* max to return in a given call */
+
+
+
+#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        AFS_NRXPACKETS  80
 #define        AFS_RXDEADTIME  50
 #define AFS_HARDDEADTIME       120
-#define        AFS_IDLEDEADTIME        50
+#define        AFS_IDLEDEADTIME        1200
 #define AFS_BLKBITS    12
 #define AFS_BLKSIZE    (1 << AFS_BLKBITS)
 
@@ -97,7 +106,7 @@ extern afs_int32 afs_rx_idledead;
 struct sysname_info {
     char *name;
     short offset;
-    char index, allocked;
+    signed char index, allocked;
 };
 
 /* flags to use with AFSOP_CACHEINIT */
@@ -111,7 +120,7 @@ struct sysname_info {
 #define AFS_SYNC       1
 #define AFS_VMSYNC_INVAL 2     /* sync and invalidate pages */
 #define AFS_LASTSTORE   4
-
+#define AFS_VMSYNC      8       /* sync pages but do not invalidate */
 
 /* background request structure */
 #define        BPARMS          4
@@ -120,6 +129,10 @@ 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 */
+#define        BOP_FETCH_NOCACHE       4   /* parms are: vnode ptr, offset, segment ptr, addr, cred ptr */
+#ifdef AFS_DARWIN_ENV
+#define        BOP_MOVE        5        /* ptr1 afs_uspc_param ptr2 sname ptr3 dname */
+#endif
 
 #define        B_DONTWAIT      1       /* On failure return; don't wait */
 
@@ -134,7 +147,7 @@ struct sysname_info {
 #define        BUWAIT          4       /* someone is waiting for BUVALID */
 struct brequest {
     struct vcache *vc;         /* vnode to use, with vrefcount bumped */
-    struct AFS_UCRED *cred;    /* credentials to use for operation */
+    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 */
@@ -170,27 +183,65 @@ struct SmallFid {
 /* The actual number of bytes in the SmallFid, not the sizeof struct. */
 #define SIZEOF_SMALLFID 10
 
+/* Queues
+ * ------
+ *
+ *  Circular queues, implemented with pointers. Structures may contain as many
+ *  queues as required, which may be located at any point within the structure,
+ *  providing the QEntry macro is used to translate between a queue pointer, and
+ *  the address of its containing structure
+ */
 
-/*
-  * Queues implemented with both pointers and short offsets into a disk file.
-  */
 struct afs_q {
     struct afs_q *next;
     struct afs_q *prev;
 };
 
+#define QZero(e)    ((e)->prev = (e)->next = NULL)
+#define        QInit(q)    ((q)->prev = (q)->next = (q))
+#define        QAdd(q,e)   ((e)->next = (q)->next, (e)->prev = (q), \
+                       (q)->next->prev = (e), (q)->next = (e))
+#define        QRemove(e)  ((e)->next->prev = (e)->prev, (e)->prev->next = (e)->next, (e)->prev = NULL, (e)->next = NULL)
+#define        QNext(e)    ((e)->next)
+#define QPrev(e)    ((e)->prev)
+#define QEmpty(q)   ((q)->prev == (q))
+/* this one takes q1 and sticks it on the end of q2 - that is, the other end, not the end
+ * that things are added onto.  q1 shouldn't be empty, it's silly */
+#define QCat(q1,q2) ((q2)->prev->next = (q1)->next, (q1)->next->prev=(q2)->prev, (q1)->prev->next=(q2), (q2)->prev=(q1)->prev, (q1)->prev=(q1)->next=(q1))
+
+/* Given a pointer to an afs_q within a structure, go back to the address of
+ * the parent structure
+ */
+
+#define QEntry(queue, structure, member) \
+       ((structure *)((char *)(queue)-(char *)(&((structure *)NULL)->member)))
+
+/* And implement operations for individual lists in terms of the above macro */
+
+#define QTOV(e)            QEntry(e, struct vcache, vlruq)
+#define QTOC(e)            QEntry(e, struct cell, lruq)
+#define QTOVH(e)    QEntry(e, struct vcache, vhashq)
+
+/*!
+ * List of free slot numbers
+ */
+struct afs_slotlist {
+    afs_uint32 slot;
+    struct afs_slotlist *next;
+};
+
 struct vrequest {
     afs_int32 uid;             /* user id making the request */
     afs_int32 busyCount;       /* how many busies we've seen so far */
     afs_int32 flags;           /* things like O_SYNC, O_NONBLOCK go here */
-    char initd;                        /* if non-zero, non-uid fields meaningful */
+    char initd;                        /* if non-zero, Error fields meaningful */
     char accessError;          /* flags for overriding error return code */
     char volumeError;          /* encountered a missing or busy volume */
     char networkError;         /* encountered network problems */
     char permWriteError;       /* fileserver returns permenent error. */
     char tokenError;            /* a token error other than expired. */
     char idleError;             /* the server idled too long */
-    char skipserver[MAXHOSTS];
+    char skipserver[AFS_MAXHOSTS];
 };
 #define VOLMISSING 1
 #define VOLBUSY 2
@@ -208,6 +259,16 @@ struct afs_cbr {
     struct AFSFid fid;
 };
 
+#ifdef AFS_LINUX22_ENV
+/* On Linux, we have to be able to allocate the storage for this using
+ * kmalloc, as otherwise we may deadlock. So, it needs to be able to fit
+ * in a single page
+ */
+# define AFS_NCBRS     PAGE_SIZE/sizeof(struct afs_cbr)
+#else
+# define AFS_NCBRS     1024    /* max # of call back return entries */
+#endif
+
 /* cellinfo file magic number */
 #define AFS_CELLINFO_MAGIC     0xf32817cd
 
@@ -217,13 +278,14 @@ struct afs_cbr {
 #define CNoAFSDB               0x08    /* never bother trying AFSDB */
 #define CHasVolRef             0x10    /* volumes were referenced */
 #define CLinkedCell            0x20    /* has a linked cell in lcellp */
+#define CHush                   0x40    /* don't display until referenced */
 
 struct cell {
     struct afs_q lruq;         /* lru q next and prev */
     char *cellName;            /* char string name of cell */
     afs_int32 cellIndex;       /* sequence number */
     afs_int32 cellNum;         /* semi-permanent cell number */
-    struct server *cellHosts[MAXCELLHOSTS];    /* volume *location* hosts */
+    struct server *cellHosts[AFS_MAXCELLHOSTS];        /* volume *location* hosts */
     struct cell *lcellp;       /* Associated linked cell */
     u_short fsport;            /* file server port */
     u_short vlport;            /* volume server port */
@@ -264,6 +326,10 @@ struct cell_alias {
  */
 #define TMP_UPAGNotReferenced  128
 
+/* unixuser notify events */
+#define UTokensObtained 1
+#define UTokensDropped  2
+
 /* values for afs_gcpags */
 enum { AFS_GCPAGS_NOTCOMPILED = 0, AFS_GCPAGS_OK =
        1, AFS_GCPAGS_USERDISABLED, AFS_GCPAGS_EPROC0, AFS_GCPAGS_EPROCN,
@@ -279,32 +345,71 @@ extern char afs_cachebasedir[1024];
 extern afs_int32 afs_numcachefiles;
 extern afs_int32 afs_numfilesperdir;
 
+struct rxkadToken {
+    afs_int32 ticketLen;
+    char * ticket;
+    struct ClearToken clearToken;
+};
+
+union tokenUnion {
+    struct rxkadToken rxkad;
+};
+
+struct tokenJar {
+    struct tokenJar *next;
+    int type;
+    union tokenUnion content;
+};
+
 struct unixuser {
     struct unixuser *next;     /* next hash pointer */
     afs_int32 uid;             /* search based on uid and cell */
     afs_int32 cell;
-    afs_int32 vid;             /* corresponding vice id in specified cell */
+    afs_int32 viceId;          /* Optional viced ID corresponding to current tokens */
     short refCount;            /* reference count for allocation */
     char states;               /* flag info */
     afs_int32 tokenTime;       /* last time tokens were set, used for timing out conn data */
-    afs_int32 stLen;           /* ticket length (if kerberos, includes kvno at head) */
-    char *stp;                 /* pointer to ticket itself */
-    struct ClearToken ct;
+    struct tokenJar *tokens;
     struct afs_exporter *exporter;     /* more info about the exporter for the remote user */
     void *cellinfo;             /* pointer to cell info (PAG manager only) */
+    afs_rwlock_t lock;
 };
 
-struct conn {
-    /* Per-connection block. */
-    struct conn *next;         /* Next dude same server. */
+#define CVEC_LEN 3 /* per-user connection pool */
+
+struct sa_conn_vector;
+typedef struct sa_conn_vector * p_sa_conn_vector; /* forward decl */
+
+struct afs_conn {
+    int refCount;
+    int activated;
+    char forceConnectFS; /* Should we try again with these tokens? */
+    struct rx_connection *id; /* RPC connid */
+    struct sa_conn_vector *parent; /* the con_vector which contains us */
+};
+
+/* An sa_conn_vector replaces the erstwhile list of conn
+   structures maintained by the cache manager.  The sa_conn_vector
+   contains a C array of connections which, if non-zero, represent
+   connections to AFS servers.
+*/
+
+struct sa_conn_vector {
+    /* linked-list machinery */
+    struct sa_conn_vector *next;
+
+    /* AFS conn-identifying info */
     struct unixuser *user;     /* user validated with respect to. */
-    struct rx_connection *id;  /* RPC connid. */
     struct srvAddr *srvr;      /* server associated with this conn */
     short refCount;            /* reference count for allocation */
     unsigned short port;       /* port associated with this connection */
-    char forceConnectFS;       /* Should we try again with these tokens? */
-};
 
+    /* next connection to return when all in cvec are fully utilized */
+    int select_index; 
+    
+    /* connections vector */
+    struct afs_conn cvec[CVEC_LEN];
+};
 
 #define SQNULL -1
 
@@ -314,44 +419,22 @@ struct conn {
     || (a)->Fid.Volume != (b)->Fid.Volume \
     || (a)->Cell != (b)->Cell)
 
-#define        FidMatches(afid,tvc) ((tvc)->fid.Fid.Vnode == (afid)->Fid.Vnode && \
-       (tvc)->fid.Fid.Volume == (afid)->Fid.Volume && \
-       (tvc)->fid.Cell == (afid)->Cell && \
-       ( (tvc)->fid.Fid.Unique == (afid)->Fid.Unique || \
-        (!(afid)->Fid.Unique && ((tvc)->states & CUnique))))
+#define        FidMatches(afid,tvc) ((tvc)->f.fid.Fid.Vnode == (afid)->Fid.Vnode && \
+       (tvc)->f.fid.Fid.Volume == (afid)->Fid.Volume && \
+       (tvc)->f.fid.Cell == (afid)->Cell && \
+       ( (tvc)->f.fid.Fid.Unique == (afid)->Fid.Unique || \
+        (!(afid)->Fid.Unique && ((tvc)->f.states & CUnique))))
 
 
-/*
-  * Operations on circular queues implemented with pointers.  Note: these queue
-  * objects are always located at the beginning of the structures they are linking.
-  */
-#define        QInit(q)    ((q)->prev = (q)->next = (q))
-#define        QAdd(q,e)   ((e)->next = (q)->next, (e)->prev = (q), \
-                       (q)->next->prev = (e), (q)->next = (e))
-#define        QRemove(e)  ((e)->next->prev = (e)->prev, (e)->prev->next = (e)->next, (e)->prev = NULL, (e)->next = NULL)
-#define        QNext(e)    ((e)->next)
-#define QPrev(e)    ((e)->prev)
-#define QEmpty(q)   ((q)->prev == (q))
-/* this one takes q1 and sticks it on the end of q2 - that is, the other end, not the end
- * that things are added onto.  q1 shouldn't be empty, it's silly */
-#define QCat(q1,q2) ((q2)->prev->next = (q1)->next, (q1)->next->prev=(q2)->prev, (q1)->prev->next=(q2), (q2)->prev=(q1)->prev, (q1)->prev=(q1)->next=(q1))
-/*
- * Do lots of address arithmetic to go from vlruq to the base of the vcache
- * structure.  Don't move struct vnode, since we think of a struct vcache as
- * a specialization of a struct vnode
- */
-#define        QTOV(e)     ((struct vcache *)(((char *) (e)) - (((char *)(&(((struct vcache *)(e))->vlruq))) - ((char *)(e)))))
-#define        QTOC(e)     ((struct cell *)((char *) (e)))
-#define        QTOVH(e)   ((struct vcache *)(((char *) (e)) - (((char *)(&(((struct vcache *)(e))->vhashq))) - ((char *)(e)))))
-
 #define        SRVADDR_MH      1
 #define        SRVADDR_ISDOWN  0x20    /* same as SRVR_ISDOWN */
 #define  SRVADDR_NOUSE    0x40 /* Don't use this srvAddr */
+
 struct srvAddr {
     struct srvAddr *next_bkt;  /* next item in hash bucket */
     struct srvAddr *next_sa;   /* another interface on same host */
     struct server *server;     /* back to parent */
-    struct conn *conns;                /* All user connections to this server */
+    struct sa_conn_vector *conns;   /* All user connections to this server */
     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 */
@@ -373,9 +456,13 @@ struct srvAddr {
 #define        SRVR_ISGONE                     0x80
 #define        SNO_INLINEBULK                  0x100
 #define SNO_64BIT                       0x200
+#define SCAPS_KNOWN                    0x400
+
+#define SRV_CAPABILITIES(ts) \
+{ if ( !(ts->flags & SCAPS_KNOWN)) afs_GetCapabilities(ts); ts->capabilities; }
 
-#define afs_serverSetNo64Bit(s) ((s)->srvr->server->flags |= SNO_64BIT)
-#define afs_serverHasNo64Bit(s) ((s)->srvr->server->flags & SNO_64BIT)
+#define afs_serverSetNo64Bit(s) (((struct sa_conn_vector*)(s)->parent)->srvr->server->flags |= SNO_64BIT)
+#define afs_serverHasNo64Bit(s) (((struct sa_conn_vector*)(s)->parent)->srvr->server->flags & SNO_64BIT)
 
 struct server {
     union {
@@ -404,11 +491,12 @@ struct server {
     afs_int32 sumOfDowntimes;  /* Total downtime experienced, in seconds */
     struct srvAddr *addr;
     afs_uint32 flags;          /* Misc flags */
+    afs_int32 capabilities;
 };
 
 #define        afs_PutServer(servp, locktype)
 
-/* structs for some pioctls  - these are (or should be) 
+/* structs for some pioctls  - these are (or should be)
  * also in venus.h
  */
 struct spref {
@@ -471,11 +559,10 @@ struct chservinfo {
 /* state bits for volume */
 #define VRO                    1       /* volume is readonly */
 #define VRecheck               2       /* recheck volume info with server */
-#define        VBackup                 4       /* is this a backup volume? */
-#define        VForeign                8       /* this is a non-afs volume */
-#define VResort         16     /* server order was rearranged, sort when able */
-#define VMoreReps       32     /* This volume has more replicas than we are   */
-                            /* keeping track of now -- check with VLDB     */
+#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 };
 
@@ -487,8 +574,8 @@ struct volume {
     afs_rwlock_t lock;         /* the lock for this structure */
     afs_int32 volume;          /* This volume's ID number. */
     char *name;                        /* This volume's name, or 0 if unknown */
-    struct server *serverHost[MAXHOSTS];       /* servers serving this volume */
-    enum repstate status[MAXHOSTS];    /* busy, offline, etc */
+    struct server *serverHost[AFS_MAXHOSTS];   /* servers serving this volume */
+    enum repstate status[AFS_MAXHOSTS];        /* busy, offline, etc */
     struct VenusFid dotdot;    /* dir to access as .. */
     struct VenusFid mtpoint;   /* The mount point for this volume. */
     afs_int32 rootVnode, rootUnique;   /* Volume's root fid */
@@ -537,19 +624,15 @@ struct SimpleLocks {
 #define CNSHARE                0x00000100      /* support O_NSHARE semantics */
 #define CLied          0x00000200
 #define CTruth         0x00000400
-#ifdef AFS_OSF_ENV
-#define CWired         0x00000800      /* OSF hack only */
-#else
-#ifdef AFS_DARWIN80_ENV
+
+#if defined(AFS_DARWIN80_ENV)
 #define CDeadVnode        0x00000800
-#else
-#ifdef AFS_DARWIN_ENV
+#elif defined(AFS_DARWIN_ENV)
 #define CUBCinit        0x00000800
 #else
 #define CWRITE_IGN     0x00000800      /* Next OS hack only */
 #endif
-#endif
-#endif
+
 #define CUnique                0x00001000      /* vc's uniquifier - latest unifiquier for fid */
 #define CForeign       0x00002000      /* this is a non-afs vcache */
 #define CReadDir       0x00004000      /* readdir in progress */
@@ -557,21 +640,26 @@ struct SimpleLocks {
 #define CBulkStat      0x00020000      /* loaded by a bulk stat, and not ref'd since */
 #define CUnlinkedDel   0x00040000
 #define CVFlushed      0x00080000
-#define CCore1         0x00100000      /* osf1 core file; not same as CCore above */
+#ifdef AFS_LINUX22_ENV
+#define CPageWrite      0x00200000      /* to detect vm deadlock - linux */
+#elif 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 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. */
 #define CVInit          0x10000000      /* being initialized */
+#define CMetaDirty     0x20000000      /* vnode meta-data needs to be flushed */
+#define CPartVisible   0x40000000      /* fileserver partition visible on client */
 
 /* vcache vstate bits */
 #define VRevokeWait   0x1
 #define VPageCleaning 0x2      /* Solaris - Cache Trunc Daemon sez keep out */
 
-#if defined(AFS_DISCON_ENV)
-
 /* Dirty disconnected vcache flags. */
 #define VDisconSetTime         0x00000001      /* set time. */
 #define VDisconSetMode         0x00000002      /* set mode. */
@@ -582,14 +670,28 @@ struct SimpleLocks {
 #define VDisconWriteFlush      0x00000800      /* Write op on normal fsync/flush. */
 #define VDisconWriteOsiFlush   0x00001000      /* Write op on osi flush. */
 
-#define VDisconShadowed                0x00002000      /* Shadowed dir. */
-#define VDisconRemove          0x00004000      /* Remove vnop. */
-#define VDisconCreate          0x00008000      /* Create vnop. */
+#define VDisconRemove          0x00002000      /* Remove vnop. */
+#define VDisconCreate          0x00004000      /* Create vnop. */
+#define VDisconCreated         0x00008000      /* A file that was created during
+                                                  this resync operation */
 #define VDisconRename          0x00010000      /* Rename vnop. */
 #define VDisconRenameSameDir   0x00020000      /* Rename in same dir. */
 
 /*... to be continued ...  */
-#endif
+
+/* vcache (file) cachingStates bits */
+#define FCSDesireBypass   0x1  /* This file should bypass the cache */
+#define FCSBypass         0x2  /* This file is currently NOT being cached */
+#define FCSManuallySet    0x4  /* The bypass flags were set, or reset, manually (via pioctl)
+                                                                  and should not be overridden by the file's name */
+
+/* Flag values used by the Transition routines */
+#define TRANSChangeDesiredBit          0x1     /* The Transition routine should set or
+                                                                                * reset the FCSDesireBypass bit */
+#define TRANSVcacheIsLocked                    0x2     /* The Transition routine does not need to
+                                                                                * lock vcache (it's already locked) */
+#define TRANSSetManualBit              0x4     /* The Transition routine should set FCSManuallySet so that
+                                                                        * filename checking does not override pioctl requests */
 
 #define        CPSIZE      2
 #if defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV)
@@ -600,6 +702,9 @@ struct SimpleLocks {
 
 #if defined(AFS_DARWIN80_ENV)
 #define VREFCOUNT_GT(v, y)    vnode_isinuse(AFSTOV(v), (y))
+#elif defined(AFS_FBSD_ENV)
+#define VREFCOUNT(v)           (vrefcnt(AFSTOV(v)))
+#define VREFCOUNT_GT(v, y)     (vrefcnt(AFSTOV(v)) > y)
 #elif defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV)
 #define VREFCOUNT(v)          ((v)->vrefCount)
 #define VREFCOUNT_GT(v, y)    (AFSTOV(v)->v_usecount > (y))
@@ -631,7 +736,14 @@ extern afs_int32 vmPageHog;        /* counter for # of vnodes which are page hogs. */
 #if defined(AFS_DARWIN80_ENV)
 #define VTOAFS(v) ((struct vcache *)vnode_fsnode((v)))
 #define AFSTOV(vc) ((vc)->v)
-#elif defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV) || (defined(AFS_LINUX22_ENV) && !defined(STRUCT_SUPER_HAS_ALLOC_INODE))
+#elif defined(AFS_NBSD40_ENV)
+struct nbvdata {
+    struct genfs_node gfsn;
+    struct vcache *afsvc;
+};
+#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))
 #define VTOAFS(v) ((struct vcache *)(v)->v_data)
 #define AFSTOV(vc) ((vc)->v)
 #else
@@ -639,36 +751,13 @@ extern afs_int32 vmPageHog;       /* counter for # of vnodes which are page hogs. */
 #define AFSTOV(V) (&(V)->v)
 #endif
 
-/* INVARIANTs: (vlruq.next != NULL) == (vlruq.prev != NULL)
- *             nextfree => !vlruq.next && ! vlruq.prev
- * !(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_HAS_ALLOC_INODE))
-    struct vnode *v;
-#else
-    struct vnode v;            /* Has reference count in v.v_count */
-#endif
-    struct afs_q vlruq;                /* lru q next and prev */
-#if !defined(AFS_LINUX22_ENV)
-    struct vcache *nextfree;   /* next on free list (if free) */
-#endif
-    struct vcache *hnext;      /* Hash next */
-    struct afs_q vhashq;       /* Hashed per-volume list */
-
-#if defined(AFS_DISCON_ENV)
-    /*! Next element in afs_DDirtyVCList. Lock it with afs_DDirtyVCListLock. */
-    struct vcache *ddirty_next;
-    /*! Disconnected flags for this vcache element. */
-    uint32_t ddirty_flags;
-    /*! Shadow vnode + unique keep the shadow dir location. */
-    afs_uint32 shVnode;
-    afs_uint32 shUnique;
-    /*! The old parent FID for renamed vnodes. */
-    afs_uint32 oldVnode;
-    afs_uint32 oldUnique;
-#endif
+struct afs_vnuniq {
+    afs_uint32 vnode;
+    afs_uint32 unique;
+};
 
+/* VCache elements which are kept on disk, and in the kernel */
+struct fvcache {
     struct VenusFid fid;
     struct mstat {
        afs_size_t Length;
@@ -684,6 +773,65 @@ struct vcache {
        /* vnode type is in v.v_type */
 #endif
     } m;
+    struct afs_vnuniq parent;
+
+    /*! Truncate file to this position at the next store */
+    afs_size_t truncPos;
+
+    /*! System:AnyUser's access to this. */
+    afs_int32 anyAccess;
+
+    /*! state bits */
+    afs_uint32 states;
+
+    /*! Disconnected flags for this vcache element. */
+    afs_uint32 ddirty_flags;
+    /*! Shadow vnode + unique keep the shadow dir location. */
+    struct afs_vnuniq shadow;
+    /*! The old parent FID for renamed vnodes */
+    struct afs_vnuniq oldParent;
+};
+
+#ifdef AFS_SUN5_ENV
+/*
+ * This is for the multiPage field in struct vcache. Each one of these
+ * represents an outstanding getpage request that is larger than a single page.
+ * Recording these is necessary to prevent afs_GetOnePage from trying to evict
+ * a dcache entry that an earlier afs_GetOnePage call got in the same getpage
+ * request. See osi_VM_MultiPageConflict and afs_getpage.
+ */
+struct multiPage_range {
+    struct afs_q q;
+    offset_t off;    /**< offset of getpage request */
+    u_int len;       /**< length of getpage request */
+};
+#endif
+
+/* INVARIANTs: (vlruq.next != NULL) == (vlruq.prev != NULL)
+ *             nextfree => !vlruq.next && ! vlruq.prev
+ * !(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))
+    struct vnode *v;
+#else
+    struct vnode v;            /* Has reference count in v.v_count */
+#endif
+    struct afs_q vlruq;                /* lru q next and prev */
+#if !defined(AFS_LINUX22_ENV)
+    struct vcache *nextfree;   /* next on free list (if free) */
+#endif
+    struct vcache *hnext;      /* Hash next */
+    struct afs_q vhashq;       /* Hashed per-volume list */
+    /*! Queue of dirty vcaches. Lock with afs_disconDirtyLock */
+    struct afs_q dirtyq;
+    /*! Queue of vcaches with shadow entries. Lock with afs_disconDirtyLock */
+    struct afs_q shadowq;
+    /*! Queue of vcaches with dirty metadata. Locked by afs_xvcdirty */
+    struct afs_q metadirty;
+    /*! Vcaches slot number in the disk backup. Protected by tvc->lock */
+    afs_uint32 diskSlot;
+    struct fvcache f;
     afs_rwlock_t lock;         /* The lock on the vcache contents. */
 #if    defined(AFS_SUN5_ENV)
     /* Lock used to protect the activeV, multipage, and vstates fields.
@@ -716,20 +864,19 @@ struct vcache {
     struct lock__bsd__ rwlock;
 #endif
 #ifdef AFS_XBSD_ENV
+#if !defined(AFS_DFBSD_ENV) && !defined(AFS_NBSD_ENV)
     struct lock rwlock;
 #endif
-    afs_int32 parentVnode;     /* Parent dir, if a file. */
-    afs_int32 parentUnique;
+#endif
+
     struct VenusFid *mvid;     /* Either parent dir (if root) or root (if mt pt) */
     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 */
-    afs_size_t truncPos;       /* truncate file to this position at next store */
     struct server *callback;   /* The callback host, if any */
     afs_uint32 cbExpires;      /* time the callback expires */
     struct afs_q callsort;     /* queue in expiry order, sort of */
     struct axscache *Access;   /* a list of cached access bits */
-    afs_int32 anyAccess;       /* System:AnyUser's access to this. */
     afs_int32 last_looker;     /* pag/uid from last lookup here */
 #if    defined(AFS_SUN5_ENV)
     afs_int32 activeV;
@@ -740,16 +887,22 @@ struct vcache {
                                 * this file. */
     short flockCount;          /* count of flock readers, or -1 if writer */
     char mvstat;               /* 0->normal, 1->mt pt, 2->root. */
-    afs_uint32 states;         /* state bits */
+
+    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) */
+#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)
     afs_uint32 vstates;                /* vstate bits */
 #endif                         /* defined(AFS_SUN5_ENV) */
     struct dcache *dchint;
     struct dcache *dcreaddir;  /* dcache for in-progress readdir */
     unsigned int readdir_pid;   /* pid of the thread in readdir */
-#ifdef AFS_LINUX22_ENV
-    u_short mapcnt;            /* Number of mappings of this file. */
-#endif
 #if defined(AFS_SGI_ENV)
     daddr_t lastr;             /* for read-ahead */
 #ifdef AFS_SGI64_ENV
@@ -765,12 +918,19 @@ struct vcache {
     struct bhv_desc vc_bhv_desc;       /* vnode's behavior data. */
 #endif
 #endif                         /* AFS_SGI_ENV */
+#if defined(AFS_LINUX26_ENV)
+    cred_t *cred;              /* last writer's cred */
+#endif
     afs_int32 vc_error;                /* stash write error for this vnode. */
     int xlatordv;              /* Used by nfs xlator */
-    struct AFS_UCRED *uncred;
+    afs_ucred_t *uncred;
     int asynchrony;            /* num kbytes to store behind */
 #ifdef AFS_SUN5_ENV
-    short multiPage;           /* count of multi-page getpages in progress */
+    struct afs_q multiPage;    /* list of multiPage_range structs */
+#endif
+    int protocol;              /* RX_FILESERVER, RX_OSD, ... defined in afsint.xg */
+#if !defined(UKERNEL)
+    void *vpacRock;            /* used to read or write in visible partitions */
 #endif
 };
 
@@ -903,13 +1063,35 @@ struct cm_initparams {
 #define        IFFree          2       /* index entry in freeDCList */
 #define        IFDataMod       4       /* file needs to be written out */
 #define        IFFlag          8       /* utility flag */
-#define        IFDirtyPages    16
+#define        IFDirtyPages    16      /* Solaris-only. contains dirty pages */
 #define        IFAnyPages      32
 #define        IFDiscarded     64      /* index entry in discardDCList */
 
+#ifdef AFS_DARWIN100_ENV
+typedef user_addr_t iparmtype; /* 64 bit */
+typedef user_addr_t uparmtype; /* 64 bit */
+#else
+typedef char * uparmtype;
+#ifdef AFS_SGI65_ENV
+typedef afs_uint32 iparmtype;
+#else
+typedef long iparmtype;
+#endif
+#endif
+
+#if SIZEOF_VOID_P == SIZEOF_UNSIGNED_INT
+# define uintptrsz unsigned int
+#elif SIZEOF_VOID_P == SIZEOF_UNSIGNED_LONG
+# define uintptrsz unsigned long
+#elif SIZEOF_VOID_P == SIZEOF_UNSIGNED_LONG_LONG
+# define uintptrsz unsigned long long
+#else
+# error "Unable to determine casting for pointers"
+#endif
+
 struct afs_ioctl {
-    char *in;                  /* input buffer */
-    char *out;                 /* output buffer */
+    uparmtype in;              /* input buffer */
+    uparmtype out;             /* output buffer */
     short in_size;             /* Size of input buffer <= 2K */
     short out_size;            /* Maximum size of output buffer, <= 2K */
 };
@@ -930,45 +1112,55 @@ struct afs_ioctl32 {
 /* CacheItems file has a header of type struct afs_fheader
  * (keep aligned properly). Since we already have sgi_62 clients running
  * with a 32 bit inode, a change is required to the header so that
- * they can distinguish the old 32 bit inode CacheItems file and zap it 
+ * they can distinguish the old 32 bit inode CacheItems file and zap it
  * instead of using it.
  */
 struct afs_fheader {
 #define AFS_FHMAGIC        0x7635abaf  /* uses version number */
     afs_int32 magic;
-#if defined(AFS_SUN57_64BIT_ENV)
-#define AFS_CI_VERSION 3
-#else
-#define AFS_CI_VERSION 2
-#endif
+#define AFS_CI_VERSION 4
     afs_int32 version;
+    afs_uint32 dataSize;
     afs_int32 firstCSize;
     afs_int32 otherCSize;
 };
 
-#if defined(AFS_SGI61_ENV) || defined(AFS_SUN57_64BIT_ENV)
+#if defined(AFS_CACHE_VNODE_PATH)
+typedef char *afs_ufs_dcache_id_t;
+#elif defined(AFS_SGI61_ENV) || defined(AFS_SUN5_64BIT_ENV)
 /* Using ino64_t here so that user level debugging programs compile
  * the size correctly.
  */
-#define afs_inode_t ino64_t
-#else
-#if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_S390X_LINUX24_ENV)
-#define afs_inode_t long
-#else
-#if defined(AFS_AIX51_ENV) || defined(AFS_HPUX1123_ENV)
-#define afs_inode_t ino_t
-#else
-#define afs_inode_t afs_int32
-#endif
+typedef ino64_t afs_ufs_dcache_id_t;
+#elif defined(AFS_LINUX26_ENV)
+#define MAX_FH_LEN 10
+typedef union {
+#if defined(NEW_EXPORT_OPS)
+    struct fid fh;
 #endif
+    __u32 raw[MAX_FH_LEN];
+} afs_ufs_dcache_id_t;
+extern int cache_fh_type;
+extern int cache_fh_len;
+#elif defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_S390X_LINUX24_ENV)
+typedef long afs_ufs_dcache_id_t;
+#elif defined(AFS_AIX51_ENV) || defined(AFS_HPUX1123_ENV)
+typedef ino_t afs_ufs_dcache_id_t;
+#else
+typedef afs_int32 afs_ufs_dcache_id_t;
 #endif
 
+typedef afs_int32 afs_mem_dcache_id_t;
+
+typedef union {
+    afs_ufs_dcache_id_t ufs;
+    afs_mem_dcache_id_t mem;
+} afs_dcache_id_t;
 
-#ifdef KERNEL
 /* it does not compile outside kernel */
 struct buffer {
   afs_int32 fid;              /* is adc->index, the cache file number */
-  afs_inode_t inode;          /* is adc->f.inode, the inode number of the cac\
+  afs_dcache_id_t inode;          /* is adc->f.inode, the inode number of the cac\
                                 he file */
   afs_int32 page;
   afs_int32 accesstime;
@@ -977,9 +1169,6 @@ struct buffer {
   char lockers;
   char dirty;
   char hashIndex;
-#if defined(AFS_USEBUFFERS)
-  struct buf *bufp;
-#endif
   afs_rwlock_t lock;          /* the lock for this structure */
 };
 
@@ -989,11 +1178,10 @@ struct fcache {
     afs_int32 modTime;         /* last time this entry was modified */
     afs_hyper_t versionNo;     /* Associated data version number */
     afs_int32 chunk;           /* Relative chunk number */
-    afs_inode_t inode;         /* Unix inode for this chunk */
+    afs_dcache_id_t inode;             /* Unix inode for this chunk */
     afs_int32 chunkBytes;      /* Num bytes in this chunk */
     char states;               /* Has this chunk been modified? */
 };
-#endif
 
 /* magic numbers to specify the cache type */
 
@@ -1052,6 +1240,12 @@ struct memCacheEntry {
   char *data;                 /* bytes */
 };
 
+struct afs_FetchOutput {
+    struct AFSVolSync tsync;
+    struct AFSFetchStatus OutStatus;
+    struct AFSCallBack CallBack;
+};
+
 /* macro to mark a dcache entry as bad */
 #define ZapDCE(x) \
     do { \
@@ -1061,11 +1255,11 @@ struct memCacheEntry {
     } while(0)
 
 /* FakeOpen and Fake Close used to be real subroutines.  They're only used in
- * sun_subr and afs_vnodeops, and they're very frequently called, so I made 
+ * sun_subr and afs_vnodeops, and they're very frequently called, so I made
  * them into macros.  They do:
  * FakeOpen:  fake the file being open for writing.  avc->lock must be held
  * in write mode.  Having the file open for writing is like having a DFS
- * write-token: you're known to have the best version of the data around, 
+ * write-token: you're known to have the best version of the data around,
  * and so the CM won't let it be overwritten by random server info.
  * FakeClose:  undo the effects of FakeOpen, noting that we want to ensure
  * that a real close eventually gets done.  We use CCore to achieve this if
@@ -1081,10 +1275,10 @@ struct memCacheEntry {
 #define afs_FakeClose(avc, acred) \
 { if (avc->execsOrWriters == 1) {  \
        /* we're the last writer, just use CCore flag */   \
-       avc->states |= CCore;   /* causes close to be called later */ \
+       avc->f.states |= CCore; /* causes close to be called later */ \
                                                                       \
        /* The cred and vnode holds will be released in afs_FlushActiveVcaches */  \
-       VN_HOLD(AFSTOV(avc));   /* So it won't disappear */           \
+       AFS_FAST_HOLD(avc);     /* So it won't disappear */           \
        CRKEEP(avc, acred); /* Should use a better place for the creds */ \
     }                                                                         \
     else {                                                                    \
@@ -1096,10 +1290,10 @@ struct memCacheEntry {
 
 #define        AFS_ZEROS   64          /* zero buffer */
 
-/*#define afs_DirtyPages(avc)  (((avc)->states & CDirty) || osi_VMDirty_p((avc)))*/
-#define        afs_DirtyPages(avc)     ((avc)->states & CDirty)
+/*#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)->states & CReadDir) && (avc)->readdir_pid == MyPidxx)
+#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
@@ -1142,16 +1336,16 @@ extern struct brequest afs_brs[NBRS];   /* request structures */
 #define        FVHash(acell,avol)  (((avol)+(acell)) & (NFENTRIES-1))
 
 /* Performance hack - we could replace VerifyVCache2 with the appropriate
- * GetVCache incantation, and could eliminate even this code from afs_UFSRead 
+ * GetVCache incantation, and could eliminate even this code from afs_UFSRead
  * by making intentionally invalidating quick.stamp in the various callbacks
  * expiration/breaking code */
 #ifdef AFS_DARWIN_ENV
 #define afs_VerifyVCache(avc, areq)  \
-  (((avc)->states & CStatd) ? (osi_VM_Setup(avc, 0), 0) : \
+  (((avc)->f.states & CStatd) ? (osi_VM_Setup(avc, 0), 0) : \
    afs_VerifyVCache2((avc),areq))
 #else
 #define afs_VerifyVCache(avc, areq)  \
-  (((avc)->states & CStatd) ? 0 : afs_VerifyVCache2((avc),areq))
+  (((avc)->f.states & CStatd) ? 0 : afs_VerifyVCache2((avc),areq))
 #endif
 
 #define DO_STATS 1             /* bits used by FindVCache */
@@ -1159,6 +1353,11 @@ extern struct brequest afs_brs[NBRS];    /* request structures */
 #define IS_SLOCK 4
 #define IS_WLOCK 8
 
+/* values for adown value of afs_LoopServers */
+#define AFS_LS_UP 0
+#define AFS_LS_DOWN 1
+#define AFS_LS_ALL 2
+
 /* values for flag param of afs_CheckVolumeNames */
 #define AFS_VOLCHECK_EXPIRED   0x1     /* volumes whose callbacks have expired */
 #define AFS_VOLCHECK_BUSY      0x2     /* volumes which were marked busy */
@@ -1169,16 +1368,12 @@ extern struct brequest afs_brs[NBRS];   /* request structures */
 
 #define        AFS_FSPORT          ((unsigned short) htons(7000))
 #define        AFS_VLPORT          ((unsigned short) htons(7003))
-
-#define        afs_read(avc, uio, acred, albn, abpp, nolock) \
-        (*(afs_cacheType->vread))(avc, uio, acred, albn, abpp, nolock)
-#define        afs_write(avc, uio, aio, acred, nolock) \
-        (*(afs_cacheType->vwrite))(avc, uio, aio, acred, nolock)
+#define AFS_RXOSDPORT      ((unsigned short) htons(7011))
 
 #define        afs_rdwr(avc, uio, rw, io, cred) \
-    (((rw) == UIO_WRITE) ? afs_write(avc, uio, io, cred, 0) : afs_read(avc, uio, cred, 0, 0, 0))
+    (((rw) == UIO_WRITE) ? afs_write(avc, uio, io, cred, 0) : afs_read(avc, uio, cred, 0))
 #define        afs_nlrdwr(avc, uio, rw, io, cred) \
-    (((rw) == UIO_WRITE) ? afs_write(avc, uio, io, cred, 1) : afs_read(avc, uio, cred, 0, 0, 1))
+    (((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
@@ -1212,7 +1407,7 @@ extern struct brequest afs_brs[NBRS];     /* request structures */
 #define refpanic(foo) if (afs_norefpanic) \
         { printf( foo ); afs_norefpanic++;} else osi_Panic( foo )
 
-/* 
+/*
 ** these are defined in the AIX source code sys/fs_locks.h but are not
 ** defined anywhere in the /usr/include directory
 */
@@ -1226,11 +1421,7 @@ extern struct brequest afs_brs[NBRS];    /* request structures */
 #if defined(AFS_SGI62_ENV) || defined(AFS_HAVE_VXFS) || defined(AFS_DARWIN_ENV)
 #define afs_vnodeToInumber(V) VnodeToIno(V)
 #else
-#ifdef AFS_DECOSF_ENV
-#define afs_vnodeToInumber(V) osi_vnodeToInumber(V)
-#else
 #define afs_vnodeToInumber(V) (VTOI(V)->i_number)
-#endif /* AFS_DECOSF_ENV */
 #endif /* AFS_SGI62_ENV */
 #endif
 
@@ -1238,28 +1429,52 @@ extern struct brequest afs_brs[NBRS];   /* request structures */
 #ifndef afs_vnodeToDev
 #if defined(AFS_SGI62_ENV) || defined(AFS_HAVE_VXFS) || defined(AFS_DARWIN_ENV)
 #define afs_vnodeToDev(V) VnodeToDev(V)
-#elif defined(AFS_DECOSF_ENV)
-#define afs_vnodeToDev(V) osi_vnodeToDev(V)
+#elif defined(UKERNEL)
+#define afs_vnodeToDev(V) (VTOI(V) ? (VTOI(V)->i_dev) : (-1))
 #else
 #define afs_vnodeToDev(V) (VTOI(V)->i_dev)
 #endif
 #endif
 
-
-/* Note: this should agree with the definition in kdump.c */
-#if     defined(AFS_OSF_ENV)
-#if     !defined(UKERNEL)
-#define AFS_USEBUFFERS  1
-#endif
-#endif
-
-#if !defined(UKERNEL) && !defined(HAVE_STRUCT_BUF)
 /* declare something so that prototypes don't flip out */
-/* appears struct buf stuff is only actually passed around as a pointer, 
+/* appears struct buf stuff is only actually passed around as a pointer,
    except with libuafs, in which case it is actually defined */
 
 struct buf;
-#endif
+
+struct rxfs_storeVariables {
+    struct rx_call *call;
+    struct vcache *vcache;
+    char *tbuffer;
+    struct iovec *tiov;
+    afs_int32 tnio;
+    afs_int32 hasNo64bit;
+    struct AFSStoreStatus InStatus;
+};
+
+struct storeOps {
+    int (*prepare)(void *rock, afs_uint32 size, afs_uint32 *bytestoxfer);
+    int (*read)(void *rock, struct osi_file *tfile, afs_uint32 offset,
+        afs_uint32 tlen, afs_uint32 *bytesread);
+    int (*write)(void *rock, afs_uint32 tlen, afs_uint32 *byteswritten);
+    int (*status)(void *rock);
+    int (*padd)(void *rock, afs_uint32 tlen);
+    int (*close)(void *rock, struct AFSFetchStatus *OutStatus,
+        afs_int32 *doProcessFS);
+    int (*destroy)(void **rock, afs_int32 error);
+    int (*storeproc)(struct storeOps *, void *, struct dcache *, int *,
+                    afs_size_t *);
+};
+
+struct fetchOps {
+    int (*more)(void *rock, afs_int32 *length, afs_uint32 *moredata);
+    int (*read)(void *rock, afs_uint32 tlen, afs_uint32 *bytesread);
+    int (*write)(void *rock, struct osi_file *fp, afs_uint32 offset,
+        afs_uint32 tlen, afs_uint32 *byteswritten);
+    int (*close)(void *rock, struct vcache *avc, struct dcache *adc,
+        struct afs_FetchOutput *Outputs);
+    int (*destroy)(void **rock, afs_int32 error);
+};
 
 /* fakestat support: opaque storage for afs_EvalFakeStat to remember
  * what vcache should be released.
@@ -1272,4 +1487,102 @@ struct afs_fakestat_state {
 };
 
 extern int afs_fakestat_enable;
+
+#ifdef AFS_MAXVCOUNT_ENV
+extern int afsd_dynamic_vcaches;
+#else
+#define afsd_dynamic_vcaches 0
+#endif
+
+/*
+ * Wrappers for access to credentials structure members
+ * Linux uses the kernel cred structure if available, with the
+ * wrappers defined in LINUX/osi_machdep.h
+ */
+#if defined(AFS_NBSD40_ENV)
+/* in osi_machdep.h as expected */
+#elif defined (AFS_DARWIN110_ENV)
+#define afs_cr_uid(cred) kauth_cred_getuid((kauth_cred_t)(cred))
+#define afs_cr_gid(cred) kauth_cred_getgid((kauth_cred_t)(cred))
+#elif !(defined(AFS_LINUX26_ENV) && defined(STRUCT_TASK_STRUCT_HAS_CRED))
+#define afs_cr_uid(cred) ((cred)->cr_uid)
+#define afs_cr_gid(cred) ((cred)->cr_gid)
+#if !defined(AFS_OBSD_ENV)
+#define afs_cr_ruid(cred) ((cred)->cr_ruid)
+#define afs_cr_rgid(cred) ((cred)->cr_rgid)
+#endif
+
+#if !defined(AFS_DARWIN110_ENV)
+static_inline void
+afs_set_cr_uid(afs_ucred_t *cred, uid_t uid) {
+    cred->cr_uid = uid;
+}
+static_inline void
+afs_set_cr_gid(afs_ucred_t *cred, gid_t gid) {
+    cred->cr_gid = gid;
+}
+#if !defined(AFS_OBSD_ENV)
+static_inline void
+afs_set_cr_ruid(afs_ucred_t *cred, uid_t uid) {
+    cred->cr_ruid = uid;
+}
+static_inline void
+afs_set_cr_rgid(afs_ucred_t *cred, gid_t gid) {
+    cred->cr_rgid = gid;
+}
+#endif /* ! AFS_OBSD_ENV */
+#endif /* ! AFS_DARWIN110_ENV */
+#endif
+
+#ifdef AFS_SUN5_ENV
+
+/** The 32 bit OS expects the members of this structure to be 32 bit
+ * quantities and the 64 bit OS expects them as 64 bit quanties. Hence
+ * to accomodate both, *long* is used instead of afs_int32
+ */
+
+struct afssysa {
+    long syscall;
+    long parm1;
+    long parm2;
+    long parm3;
+    long parm4;
+    long parm5;
+    long parm6;
+};
+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 and SUNOS have 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_ */