afsd -dynroot-sparse mode for hushed cells
[openafs.git] / src / afs / afs.h
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #ifndef _AFS_H_
11 #define _AFS_H_
12 /*
13  * AFS system call opcodes
14  */
15 #ifdef KDUMP_KERNEL
16 #include <afs/afs_args.h>
17 #include <afs/afs_consts.h>
18 #else
19 #include "afs/afs_args.h"
20 #include "afs/afs_consts.h"
21 #endif
22
23 /*
24  * afs_fsfragsize cannot be less than 1023, or some cache-tracking
25  * calculations will be incorrect (since we track cache usage in kb).
26  * Some filesystems have fundamental blocksizes less than 1k, and
27  * normally we would tune afs_fsfragsize to be fragsize-1, but we must
28  * make sure to check that afs_fsfragsize does not go below this value.
29  */
30 #define AFS_MIN_FRAGSIZE 1023
31
32 /* Upper bound on number of iovecs out uio routines will deal with. */
33 #define AFS_MAXIOVCNT       16
34
35
36 extern int afs_shuttingdown;
37
38 /*
39  * Macros to uniquely identify the AFS vfs struct
40  */
41 #define AFS_VFSMAGIC            0x1234
42 #if defined(AFS_SUN5_ENV) || defined(AFS_HPUX90_ENV) || defined(AFS_LINUX20_ENV)
43 #define AFS_VFSFSID             99
44 #else
45 #if defined(AFS_SGI_ENV)
46 #define AFS_VFSFSID             afs_fstype
47 #else
48 #define AFS_VFSFSID             AFS_MOUNT_AFS
49 #endif
50 #endif
51
52 /* Moved from VNOPS/afs_vnop_flocks so can be used in prototypes */
53 #if     defined(AFS_HPUX102_ENV)
54 #define AFS_FLOCK       k_flock
55 #else
56 #if     defined(AFS_SUN56_ENV) || (defined(AFS_LINUX24_ENV) && !(defined(AFS_LINUX26_ENV) && defined(AFS_LINUX_64BIT_KERNEL)))
57 #define AFS_FLOCK       flock64
58 #else
59 #define AFS_FLOCK       flock
60 #endif /* AFS_SUN65_ENV */
61 #endif /* AFS_HPUX102_ENV */
62
63 /* The following are various levels of afs debugging */
64 #define AFSDEB_GENERAL          1       /* Standard debugging */
65 #define AFSDEB_NETWORK          2       /* low level afs networking */
66 #define AFSDEB_RX               4       /* RX debugging */
67 #define AFSDEB_VNLAYER          8       /* interface layer to AFS (aixops, gfsops, etc) */
68
69 /* generic undefined vice id */
70 #define UNDEFVID            (-1)
71
72 /* The basic defines for the Andrew file system
73     better keep things powers of two so "& (foo-1)" hack works for masking bits */
74 #define NBRS            15      /* max number of queued daemon requests */
75 #define NUSERS          16      /* hash table size for unixuser table */
76 #define NSERVERS        16      /* hash table size for server table */
77 #define NVOLS           64      /* hash table size for volume table */
78 #define NFENTRIES       256     /* hash table size for disk volume table */
79 #define VCSIZE         1024     /* stat cache hash table size */
80 #define DCSIZE          512     /* disk cache hash table size */
81 #define CBRSIZE         512     /* call back returns hash table size */
82 #define PIGGYSIZE       1350    /* max piggyback size */
83 #define MAXVOLS         128     /* max vols we can store */
84 #define MAXSYSNAME      128     /* max sysname (i.e. @sys) size */
85 #define MAXNUMSYSNAMES  32      /* max that current constants allow */
86 #define NOTOKTIMEOUT    (2*3600)        /* time after which to timeout conns sans tokens */
87 #define NOPAG           0xffffffff
88 #define AFS_NCBRS       300     /* max # of call back return entries */
89 #define AFS_MAXCBRSCALL 16      /* max to return in a given call */
90 #define AFS_SALLOC_LOW_WATER    250     /* Min free blocks before allocating more */
91 #define AFS_LRALLOCSIZ  4096    /* "Large" allocated size */
92 #define VCACHE_FREE     5
93 #define AFS_NRXPACKETS  80
94 #define AFS_RXDEADTIME  50
95 #define AFS_HARDDEADTIME        120
96 #define AFS_IDLEDEADTIME        50
97 #define AFS_BLKBITS     12
98 #define AFS_BLKSIZE     (1 << AFS_BLKBITS)
99
100 extern afs_int32 afs_rx_deadtime;
101 extern afs_int32 afs_rx_harddead;
102 extern afs_int32 afs_rx_idledead;
103
104 struct sysname_info {
105     char *name;
106     short offset;
107     char index, allocked;
108 };
109
110 /* flags to use with AFSOP_CACHEINIT */
111 #define AFSCALL_INIT_MEMCACHE        0x1        /* use a memory-based cache */
112
113 /* below here used only for kernel procedures */
114 #ifdef KERNEL
115 /* Store synchrony flags - SYNC means that data should be forced to server's
116  * disk immediately upon completion. */
117 #define AFS_ASYNC       0
118 #define AFS_SYNC        1
119 #define AFS_VMSYNC_INVAL 2      /* sync and invalidate pages */
120 #define AFS_LASTSTORE   4
121 #define AFS_VMSYNC      8       /* sync pages but do not invalidate */
122
123 /* background request structure */
124 #define BPARMS          4
125
126 #define BOP_NOOP        0       /* leave 0 unused */
127 #define BOP_FETCH       1       /* parm1 is chunk to get */
128 #define BOP_STORE       2       /* parm1 is chunk to store */
129 #define BOP_PATH        3       /* parm1 is path, parm2 is chunk to fetch */
130
131 #if defined(AFS_CACHE_BYPASS)
132 #define BOP_FETCH_NOCACHE       4   /* parms are: vnode ptr, offset, segment ptr, addr, cred ptr */
133 #endif
134 #ifdef AFS_DARWIN_ENV
135 #define BOP_MOVE        5        /* ptr1 afs_uspc_param ptr2 sname ptr3 dname */
136 #endif
137
138 #define B_DONTWAIT      1       /* On failure return; don't wait */
139
140 /* protocol is: refCount is incremented by user to take block out of free pool.
141     Next, BSTARTED is set when daemon finds request.  This prevents
142     other daemons from picking up the same request.  Finally, when
143     request is done, refCount is zeroed.  BDONE and BWAIT are used by
144     dudes waiting for operation to proceed to a certain point before returning.
145 */
146 #define BSTARTED        1       /* request picked up by a daemon */
147 #define BUVALID         2       /* code is valid (store) */
148 #define BUWAIT          4       /* someone is waiting for BUVALID */
149 struct brequest {
150     struct vcache *vc;          /* vnode to use, with vrefcount bumped */
151     afs_ucred_t *cred;  /* credentials to use for operation */
152     afs_size_t size_parm[BPARMS];       /* random parameters */
153     void *ptr_parm[BPARMS];     /* pointer parameters */
154     afs_int32 code;             /* return code */
155     short refCount;             /* use counter for this structure */
156     char opcode;                /* what to do (store, fetch, etc) */
157     char flags;                 /* free, etc */
158     afs_int32 ts;               /* counter "timestamp" */
159 };
160
161 struct SecretToken {
162     char data[56];
163 };
164
165 struct ClearToken {
166     afs_int32 AuthHandle;
167     char HandShakeKey[8];
168     afs_int32 ViceId;
169     afs_int32 BeginTimestamp;
170     afs_int32 EndTimestamp;
171 };
172
173 struct VenusFid {
174     afs_int32 Cell;             /* better sun packing if at end of structure */
175     struct AFSFid Fid;
176 };
177
178 /* 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!) */
179 struct SmallFid {
180     afs_int32 Volume;
181     afs_int32 CellAndUnique;
182     u_short Vnode;
183 };
184 /* The actual number of bytes in the SmallFid, not the sizeof struct. */
185 #define SIZEOF_SMALLFID 10
186
187 /* Queues 
188  * ------
189  *
190  *  Circular queues, implemented with pointers. Structures may contain as many
191  *  queues as required, which may be located at any point within the structure,
192  *  providing the QEntry macro is used to translate between a queue pointer, and
193  *  the address of its containing structure
194  */
195
196 struct afs_q {
197     struct afs_q *next;
198     struct afs_q *prev;
199 };
200
201 #define QZero(e)    ((e)->prev = (e)->next = NULL)
202 #define QInit(q)    ((q)->prev = (q)->next = (q))
203 #define QAdd(q,e)   ((e)->next = (q)->next, (e)->prev = (q), \
204                         (q)->next->prev = (e), (q)->next = (e))
205 #define QRemove(e)  ((e)->next->prev = (e)->prev, (e)->prev->next = (e)->next, (e)->prev = NULL, (e)->next = NULL)
206 #define QNext(e)    ((e)->next)
207 #define QPrev(e)    ((e)->prev)
208 #define QEmpty(q)   ((q)->prev == (q))
209 /* this one takes q1 and sticks it on the end of q2 - that is, the other end, not the end
210  * that things are added onto.  q1 shouldn't be empty, it's silly */
211 #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))
212
213 /* Given a pointer to an afs_q within a structure, go back to the address of
214  * the parent structure
215  */
216
217 #define QEntry(queue, structure, member) \
218         ((structure *)((char *)(queue)-(char *)(&((structure *)NULL)->member)))
219
220 /* And implement operations for individual lists in terms of the above macro */
221
222 #define QTOV(e)     QEntry(e, struct vcache, vlruq)
223 #define QTOC(e)     QEntry(e, struct cell, lruq)
224 #define QTOVH(e)    QEntry(e, struct vcache, vhashq)
225
226 /*!
227  * List of free slot numbers
228  */
229 struct afs_slotlist {
230     afs_uint32 slot;
231     struct afs_slotlist *next;
232 };
233
234 struct vrequest {
235     afs_int32 uid;              /* user id making the request */
236     afs_int32 busyCount;        /* how many busies we've seen so far */
237     afs_int32 flags;            /* things like O_SYNC, O_NONBLOCK go here */
238     char initd;                 /* if non-zero, Error fields meaningful */
239     char accessError;           /* flags for overriding error return code */
240     char volumeError;           /* encountered a missing or busy volume */
241     char networkError;          /* encountered network problems */
242     char permWriteError;        /* fileserver returns permenent error. */
243     char tokenError;            /* a token error other than expired. */
244     char idleError;             /* the server idled too long */
245     char skipserver[AFS_MAXHOSTS];
246 };
247 #define VOLMISSING 1
248 #define VOLBUSY 2
249
250 /* structure linked off of a server to keep track of queued returned
251  * callbacks.  Sent asynchronously when we run a little low on free dudes.
252  */
253 struct afs_cbr {
254     struct afs_cbr **pprev;
255     struct afs_cbr *next;
256
257     struct afs_cbr **hash_pprev;
258     struct afs_cbr *hash_next;
259
260     struct AFSFid fid;
261 };
262
263 /* cellinfo file magic number */
264 #define AFS_CELLINFO_MAGIC      0xf32817cd
265
266 /* cell flags */
267 #define CNoSUID                 0x02    /* disable suid bit for this cell */
268 #define CLinkedCell4            0x04    /* reserved for ADDCELL2 pioctl */
269 #define CNoAFSDB                0x08    /* never bother trying AFSDB */
270 #define CHasVolRef              0x10    /* volumes were referenced */
271 #define CLinkedCell             0x20    /* has a linked cell in lcellp */
272 #define CHush                   0x40    /* don't display until referenced */
273
274 struct cell {
275     struct afs_q lruq;          /* lru q next and prev */
276     char *cellName;             /* char string name of cell */
277     afs_int32 cellIndex;        /* sequence number */
278     afs_int32 cellNum;          /* semi-permanent cell number */
279     struct server *cellHosts[AFS_MAXCELLHOSTS]; /* volume *location* hosts */
280     struct cell *lcellp;        /* Associated linked cell */
281     u_short fsport;             /* file server port */
282     u_short vlport;             /* volume server port */
283     short states;               /* state flags */
284     time_t timeout;             /* data expire time, if non-zero */
285     struct cell_name *cnamep;   /* pointer to our cell_name */
286     afs_rwlock_t lock;          /* protects cell data */
287     unsigned char cellHandle[16];       /* deterministic handle for this cell */
288 };
289
290 struct cell_name {
291     struct cell_name *next;
292     afs_int32 cellnum;
293     char *cellname;
294     char used;
295 };
296
297 struct cell_alias {
298     struct cell_alias *next;
299     afs_int32 index;
300     char *alias;
301     char *cell;
302 };
303
304 #define afs_PutCell(cellp, locktype)
305
306 /* the unixuser flag bit definitions */
307 #define UHasTokens      1       /* are the st and ct fields valid (ever set)? */
308 #define UTokensBad      2       /* are tokens bad? */
309 #define UPrimary        4       /* on iff primary identity */
310 #define UNeedsReset     8       /* needs afs_ResetAccessCache call done */
311 #define UPAGCounted    16       /* entry seen during PAG search (for stats) */
312 #define UNFSGetCreds   32       /* getting creds for NFS client */
313 /* A flag used by afs_GCPAGs to keep track of
314  * which entries in afs_users need to be deleted.
315  * The lifetime of its presence in the table is the
316  * lifetime of the afs_GCPAGs function.
317  */
318 #define TMP_UPAGNotReferenced   128
319
320 /* unixuser notify events */
321 #define UTokensObtained 1
322 #define UTokensDropped  2
323
324 /* values for afs_gcpags */
325 enum { AFS_GCPAGS_NOTCOMPILED = 0, AFS_GCPAGS_OK =
326         1, AFS_GCPAGS_USERDISABLED, AFS_GCPAGS_EPROC0, AFS_GCPAGS_EPROCN,
327     AFS_GCPAGS_EEQPID, AFS_GCPAGS_EINEXACT, AFS_GCPAGS_EPROCEND,
328     AFS_GCPAGS_EPROCWALK, AFS_GCPAGS_ECREDWALK, AFS_GCPAGS_EPIDCHECK,
329     AFS_GCPAGS_ENICECHECK
330 };
331
332 extern afs_int32 afs_gcpags;
333 extern afs_int32 afs_gcpags_procsize;
334 extern afs_int32 afs_bkvolpref;
335 extern char afs_cachebasedir[1024];
336 extern afs_int32 afs_numcachefiles;
337 extern afs_int32 afs_numfilesperdir;
338
339 struct unixuser {
340     struct unixuser *next;      /* next hash pointer */
341     afs_int32 uid;              /* search based on uid and cell */
342     afs_int32 cell;
343     afs_int32 vid;              /* corresponding vice id in specified cell */
344     short refCount;             /* reference count for allocation */
345     char states;                /* flag info */
346     afs_int32 tokenTime;        /* last time tokens were set, used for timing out conn data */
347     afs_int32 stLen;            /* ticket length (if kerberos, includes kvno at head) */
348     char *stp;                  /* pointer to ticket itself */
349     struct ClearToken ct;
350     struct afs_exporter *exporter;      /* more info about the exporter for the remote user */
351     void *cellinfo;             /* pointer to cell info (PAG manager only) */
352 };
353
354 struct afs_conn {
355     /* Per-connection block. */
356     struct afs_conn *next;              /* Next dude same server. */
357     struct unixuser *user;      /* user validated with respect to. */
358     struct rx_connection *id;   /* RPC connid. */
359     struct srvAddr *srvr;       /* server associated with this conn */
360     short refCount;             /* reference count for allocation */
361     unsigned short port;        /* port associated with this connection */
362     char forceConnectFS;        /* Should we try again with these tokens? */
363 };
364
365
366 #define SQNULL -1
367
368 /* Fid comparison routines */
369 #define FidCmp(a,b) ((a)->Fid.Unique != (b)->Fid.Unique \
370     || (a)->Fid.Vnode != (b)->Fid.Vnode \
371     || (a)->Fid.Volume != (b)->Fid.Volume \
372     || (a)->Cell != (b)->Cell)
373
374 #define FidMatches(afid,tvc) ((tvc)->f.fid.Fid.Vnode == (afid)->Fid.Vnode && \
375         (tvc)->f.fid.Fid.Volume == (afid)->Fid.Volume && \
376         (tvc)->f.fid.Cell == (afid)->Cell && \
377         ( (tvc)->f.fid.Fid.Unique == (afid)->Fid.Unique || \
378          (!(afid)->Fid.Unique && ((tvc)->f.states & CUnique))))
379
380
381 #define SRVADDR_MH      1
382 #define SRVADDR_ISDOWN  0x20    /* same as SRVR_ISDOWN */
383 #define  SRVADDR_NOUSE    0x40  /* Don't use this srvAddr */
384 struct srvAddr {
385     struct srvAddr *next_bkt;   /* next item in hash bucket */
386     struct srvAddr *next_sa;    /* another interface on same host */
387     struct server *server;      /* back to parent */
388     struct afs_conn *conns;             /* All user connections to this server */
389     afs_int32 sa_ip;            /* Host addr in network byte order */
390     u_short sa_iprank;          /* indiv ip address priority */
391     u_short sa_portal;          /* port addr in network byte order */
392     u_char sa_flags;
393 };
394
395 /*
396  * Values used in the flags field of the server structure below.
397  *
398  *      AFS_SERVER_FLAG_ACTIVATED Has the server ever had a user connection
399  *                                associated with it?
400  */
401 #define AFS_SERVER_FLAG_ACTIVATED       0x01
402 #define SNO_LHOSTS                      0x04
403 #define SYES_LHOSTS                     0x08
404 #define SVLSRV_UUID                     0x10
405 #define SRVR_ISDOWN                     0x20
406 #define SRVR_MULTIHOMED                 0x40
407 #define SRVR_ISGONE                     0x80
408 #define SNO_INLINEBULK                  0x100
409 #define SNO_64BIT                       0x200
410 #define SCAPS_KNOWN                     0x400
411
412 #define SRV_CAPABILITIES(ts) \
413 { if ( !(ts->flags & SCAPS_KNOWN)) afs_GetCapabilities(ts); ts->capabilities; }
414
415 #define afs_serverSetNo64Bit(s) ((s)->srvr->server->flags |= SNO_64BIT)
416 #define afs_serverHasNo64Bit(s) ((s)->srvr->server->flags & SNO_64BIT)
417
418 struct server {
419     union {
420         struct {
421             afsUUID suuid;
422             afs_int32 addr_uniquifier;
423             afs_int32 spares[2];
424         } _srvUuid;
425         struct {
426             struct srvAddr haddr;
427         } _srvId;
428     } _suid;
429 #define sr_uuid         _suid._srvUuid.suuid
430 #define sr_addr_uniquifier      _suid._srvUuid.addr_uniquifier
431 #define sr_host         _suid._srvId.haddr.ip
432 #define sr_portal       _suid._srvId.haddr.portal
433 #define sr_rank         _suid._srvId.haddr.ip_rank
434 #define sr_flags        _suid._srvId.haddr.flags
435 #define sr_conns        _suid._srvId.haddr.conns
436     struct server *next;        /* Ptr to next server in hash chain */
437     struct cell *cell;          /* Cell in which this host resides */
438     struct afs_cbr *cbrs;       /* Return list of callbacks */
439     afs_int32 activationTime;   /* Time when this record was first activated */
440     afs_int32 lastDowntimeStart;        /* Time when last downtime incident began */
441     afs_int32 numDowntimeIncidents;     /* # (completed) downtime incidents */
442     afs_int32 sumOfDowntimes;   /* Total downtime experienced, in seconds */
443     struct srvAddr *addr;
444     afs_uint32 flags;           /* Misc flags */
445     afs_int32 capabilities;
446 };
447
448 #define afs_PutServer(servp, locktype)
449
450 /* structs for some pioctls  - these are (or should be) 
451  * also in venus.h
452  */
453 struct spref {
454     struct in_addr host;
455     unsigned short rank;
456 };
457
458 struct sprefrequest_33 {
459     unsigned short offset;
460     unsigned short num_servers;
461 };
462
463
464 struct sprefrequest {           /* new struct for 3.4 */
465     unsigned short offset;
466     unsigned short num_servers;
467     unsigned short flags;
468 };
469 #define DBservers 1
470
471 struct sprefinfo {
472     unsigned short next_offset;
473     unsigned short num_servers;
474     struct spref servers[1];    /* we overrun this array intentionally... */
475 };
476
477 struct setspref {
478     unsigned short flags;
479     unsigned short num_servers;
480     struct spref servers[1];    /* we overrun this array intentionally... */
481 };
482 /* struct for GAG pioctl
483  */
484 struct gaginfo {
485     afs_uint32 showflags, logflags, logwritethruflag, spare[3];
486     unsigned char spare2[128];
487 };
488 #define GAGUSER    1
489 #define GAGCONSOLE 2
490 #define logwritethruON  1
491
492 struct rxparams {
493     afs_int32 rx_initReceiveWindow, rx_maxReceiveWindow, rx_initSendWindow,
494         rx_maxSendWindow, rxi_nSendFrags, rxi_nRecvFrags, rxi_OrphanFragSize;
495     afs_int32 rx_maxReceiveSize, rx_MyMaxSendSize;
496     afs_uint32 spare[21];
497 };
498
499 /* struct for checkservers */
500
501 struct chservinfo {
502     int magic;
503     char tbuffer[128];
504     int tsize;
505     afs_int32 tinterval;
506     afs_int32 tflags;
507 };
508
509
510 /* state bits for volume */
511 #define VRO                     1       /* volume is readonly */
512 #define VRecheck                2       /* recheck volume info with server */
513 #define VBackup                 4       /* is this a backup volume? */
514 #define VForeign                8       /* this is a non-afs volume */
515 #define VResort         16      /* server order was rearranged, sort when able */
516 #define VMoreReps       32      /* This volume has more replicas than we are   */
517                              /* keeping track of now -- check with VLDB     */
518
519 enum repstate { not_busy, end_not_busy = 6, rd_busy, rdwr_busy, offline };
520
521 struct volume {
522     /* One structure per volume, describing where the volume is located
523      * and where its mount points are. */
524     struct volume *next;        /* Next volume in hash list. */
525     afs_int32 cell;             /* the cell in which the volume resides */
526     afs_rwlock_t lock;          /* the lock for this structure */
527     afs_int32 volume;           /* This volume's ID number. */
528     char *name;                 /* This volume's name, or 0 if unknown */
529     struct server *serverHost[AFS_MAXHOSTS];    /* servers serving this volume */
530     enum repstate status[AFS_MAXHOSTS]; /* busy, offline, etc */
531     struct VenusFid dotdot;     /* dir to access as .. */
532     struct VenusFid mtpoint;    /* The mount point for this volume. */
533     afs_int32 rootVnode, rootUnique;    /* Volume's root fid */
534     afs_int32 roVol;
535     afs_int32 backVol;
536     afs_int32 rwVol;            /* For r/o vols, original read/write volume. */
537     afs_int32 accessTime;       /* last time we used it */
538     afs_int32 vtix;             /* volume table index */
539     afs_int32 copyDate;         /* copyDate field, for tracking vol releases */
540     afs_int32 expireTime;       /* for per-volume callbacks... */
541     short refCount;             /* reference count for allocation */
542     char states;                /* here for alignment reasons */
543 };
544
545 #define afs_PutVolume(av, locktype) ((av)->refCount--)
546
547 /* format of an entry in volume info file */
548 struct fvolume {
549     afs_int32 cell;             /* cell for this entry */
550     afs_int32 volume;           /* volume */
551     afs_int32 next;             /* has index */
552     struct VenusFid dotdot;     /* .. value */
553     struct VenusFid mtpoint;    /* mt point's fid */
554     afs_int32 rootVnode, rootUnique;    /* Volume's root fid */
555 };
556
557 struct SimpleLocks {
558     struct SimpleLocks *next;
559     int type;
560     afs_int32 boff, eoff;
561     afs_int32 pid;
562 #if     defined(AFS_AIX32_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV)
563     afs_int32 sysid;
564 #endif
565 };
566
567 /* vcache state bits */
568 #define CStatd          0x00000001      /* has this file ever been stat'd? */
569 #define CBackup         0x00000002      /* file is on a backup volume */
570 #define CRO             0x00000004      /* is it on a read-only volume */
571 #define CMValid         0x00000008      /* is the mount point info valid? */
572 #define CCore           0x00000010      /* storing a core file, needed since we don't get an open */
573 #define CDirty          0x00000020      /* file has been modified since first open (... O_RDWR) */
574 #define CSafeStore      0x00000040      /* close must wait for store to finish (should be in fd) */
575 #define CMAPPED         0x00000080      /* Mapped files; primarily used by SunOS 4.0.x */
576 #define CNSHARE         0x00000100      /* support O_NSHARE semantics */
577 #define CLied           0x00000200
578 #define CTruth          0x00000400
579
580 #if defined(AFS_DARWIN80_ENV)
581 #define CDeadVnode        0x00000800
582 #elif defined(AFS_DARWIN_ENV)
583 #define CUBCinit        0x00000800
584 #else
585 #define CWRITE_IGN      0x00000800      /* Next OS hack only */
586 #endif
587
588 #define CUnique         0x00001000      /* vc's uniquifier - latest unifiquier for fid */
589 #define CForeign        0x00002000      /* this is a non-afs vcache */
590 #define CReadDir        0x00004000      /* readdir in progress */
591 #define CUnlinked       0x00010000
592 #define CBulkStat       0x00020000      /* loaded by a bulk stat, and not ref'd since */
593 #define CUnlinkedDel    0x00040000
594 #define CVFlushed       0x00080000
595 #ifdef AFS_LINUX22_ENV
596 #define CPageWrite      0x00200000      /* to detect vm deadlock - linux */
597 #elif defined(AFS_SGI_ENV)
598 #define CWritingUFS     0x00200000      /* to detect vm deadlock - used by sgi */
599 #elif defined(AFS_DARWIN80_ENV)
600 #define CEvent          0x00200000      /* to preclude deadlock when sending events */
601 #endif
602 #define CCreating       0x00400000      /* avoid needless store after open truncate */
603 #define CPageHog        0x00800000      /* AIX - dumping large cores is a page hog. */
604 #define CDCLock         0x02000000      /* Vnode lock held over call to GetDownD */
605 #define CBulkFetching   0x04000000      /* stats are being fetched by bulk stat */
606 #define CExtendedFile   0x08000000      /* extended file via ftruncate call. */
607 #define CVInit          0x10000000      /* being initialized */
608 #define CMetaDirty      0x20000000      /* vnode meta-data needs to be flushed */
609
610 /* vcache vstate bits */
611 #define VRevokeWait   0x1
612 #define VPageCleaning 0x2       /* Solaris - Cache Trunc Daemon sez keep out */
613
614 #if defined(AFS_DISCON_ENV)
615
616 /* Dirty disconnected vcache flags. */
617 #define VDisconSetTime          0x00000001      /* set time. */
618 #define VDisconSetMode          0x00000002      /* set mode. */
619 /* XXX: to be continued ? */
620 #define VDisconTrunc            0x00000020      /* truncate file. */
621 #define VDisconSetAttrMask      0x0000003F      /* Masks for setattr ops. */
622 #define VDisconWriteClose       0x00000400      /* Write op on file close. */
623 #define VDisconWriteFlush       0x00000800      /* Write op on normal fsync/flush. */
624 #define VDisconWriteOsiFlush    0x00001000      /* Write op on osi flush. */
625
626 #define VDisconRemove           0x00002000      /* Remove vnop. */
627 #define VDisconCreate           0x00004000      /* Create vnop. */
628 #define VDisconCreated          0x00008000      /* A file that was created during
629                                                    this resync operation */
630 #define VDisconRename           0x00010000      /* Rename vnop. */
631 #define VDisconRenameSameDir    0x00020000      /* Rename in same dir. */
632
633 /*... to be continued ...  */
634 #endif
635
636 #if defined(AFS_CACHE_BYPASS)
637 /* vcache (file) cachingStates bits */
638 #define FCSDesireBypass   0x1   /* This file should bypass the cache */
639 #define FCSBypass         0x2   /* This file is currently NOT being cached */
640 #define FCSManuallySet    0x4   /* The bypass flags were set, or reset, manually (via pioctl)
641                                                                    and should not be overridden by the file's name */
642
643 /* Flag values used by the Transition routines */
644 #define TRANSChangeDesiredBit           0x1     /* The Transition routine should set or 
645                                                                                  * reset the FCSDesireBypass bit */
646 #define TRANSVcacheIsLocked                     0x2     /* The Transition routine does not need to
647                                                                                  * lock vcache (it's already locked) */
648 #define TRANSSetManualBit               0x4     /* The Transition routine should set FCSManuallySet so that
649                                                                          * filename checking does not override pioctl requests */       
650 #endif /* AFS_CACHE_BYPASS */
651
652 #define CPSIZE      2
653 #if defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV)
654 #define vrefCount   v->v_usecount
655 #else
656 #define vrefCount   v.v_count
657 #endif /* AFS_XBSD_ENV */
658
659 #if defined(AFS_DARWIN80_ENV)
660 #define VREFCOUNT_GT(v, y)    vnode_isinuse(AFSTOV(v), (y))
661 #elif defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV)
662 #define VREFCOUNT(v)          ((v)->vrefCount)
663 #define VREFCOUNT_GT(v, y)    (AFSTOV(v)->v_usecount > (y))
664 #elif defined(AFS_LINUX24_ENV)
665 #define VREFCOUNT(v)            atomic_read(&(AFSTOV(v)->v_count))
666 #define VREFCOUNT_GT(v, y)      (VREFCOUNT(v)>y)
667 #define VREFCOUNT_SET(v, c)     atomic_set(&(AFSTOV(v)->v_count), c)
668 #define VREFCOUNT_DEC(v)        atomic_dec(&(AFSTOV(v)->v_count))
669 #define VREFCOUNT_INC(v)        atomic_inc(&(AFSTOV(v)->v_count))
670 #else
671 #define VREFCOUNT(v)            ((v)->vrefCount)
672 #define VREFCOUNT_GT(v,y)     ((v)->vrefCount > (y))
673 #define VREFCOUNT_SET(v, c)     (v)->vrefCount = c;
674 #define VREFCOUNT_DEC(v)        (v)->vrefCount--;
675 #define VREFCOUNT_INC(v)        (v)->vrefCount++;
676 #define d_unhash(d) list_empty(&(d)->d_hash)
677 #define dget_locked(d) dget(d)
678 #endif
679
680 #define AFS_MAXDV   0x7fffffff  /* largest dataversion number */
681 #ifdef AFS_64BIT_CLIENT
682 #define AFS_NOTRUNC 0x7fffffffffffffffLL        /* largest positive int64 number */
683 #else /* AFS_64BIT_CLIENT */
684 #define AFS_NOTRUNC 0x7fffffff  /* largest dataversion number */
685 #endif /* AFS_64BIT_CLIENT */
686
687 extern afs_int32 vmPageHog;     /* counter for # of vnodes which are page hogs. */
688
689 #if defined(AFS_DARWIN80_ENV)
690 #define VTOAFS(v) ((struct vcache *)vnode_fsnode((v)))
691 #define AFSTOV(vc) ((vc)->v)
692 #elif defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV) || (defined(AFS_LINUX22_ENV) && !defined(STRUCT_SUPER_OPERATIONS_HAS_ALLOC_INODE))
693 #define VTOAFS(v) ((struct vcache *)(v)->v_data)
694 #define AFSTOV(vc) ((vc)->v)
695 #else
696 #define VTOAFS(V) ((struct vcache *)(V))
697 #define AFSTOV(V) (&(V)->v)
698 #endif
699
700 struct afs_vnuniq {
701     afs_uint32 vnode;
702     afs_uint32 unique;
703 };
704
705 /* VCache elements which are kept on disk, and in the kernel */
706 struct fvcache {
707     struct VenusFid fid;
708     struct mstat {
709         afs_size_t Length;
710         afs_hyper_t DataVersion;
711         afs_uint32 Date;
712         afs_uint32 Owner;
713         afs_uint32 Group;
714         afs_uint16 Mode;        /* XXXX Should be afs_int32 XXXX */
715         afs_uint16 LinkCount;
716 #ifdef AFS_DARWIN80_ENV
717         afs_uint16 Type;
718 #else
719         /* vnode type is in v.v_type */
720 #endif
721     } m;
722     struct afs_vnuniq parent;
723
724     /*! Truncate file to this position at the next store */
725     afs_size_t truncPos;
726
727     /*! System:AnyUser's access to this. */
728     afs_int32 anyAccess;
729
730     /*! state bits */
731     afs_uint32 states;
732
733 #if defined(AFS_DISCON_ENV)
734     /*! Disconnected flags for this vcache element. */
735     afs_uint32 ddirty_flags;
736     /*! Shadow vnode + unique keep the shadow dir location. */
737     struct afs_vnuniq shadow;
738     /*! The old parent FID for renamed vnodes */
739     struct afs_vnuniq oldParent;
740 #endif
741 };
742     
743 /* INVARIANTs: (vlruq.next != NULL) == (vlruq.prev != NULL)
744  *             nextfree => !vlruq.next && ! vlruq.prev
745  * !(avc->nextfree) && !avc->vlruq.next => (FreeVCList == avc->nextfree)
746  */
747 struct vcache {
748 #if defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV) || (defined(AFS_LINUX22_ENV) && !defined(STRUCT_SUPER_OPERATIONS_HAS_ALLOC_INODE))
749     struct vnode *v;
750 #else
751     struct vnode v;             /* Has reference count in v.v_count */
752 #endif
753     struct afs_q vlruq;         /* lru q next and prev */
754 #if !defined(AFS_LINUX22_ENV)
755     struct vcache *nextfree;    /* next on free list (if free) */
756 #endif
757     struct vcache *hnext;       /* Hash next */
758     struct afs_q vhashq;        /* Hashed per-volume list */
759 #if defined(AFS_DISCON_ENV)
760     /*! Queue of dirty vcaches. Lock with afs_disconDirtyLock */
761     struct afs_q dirtyq;
762     /*! Queue of vcaches with shadow entries. Lock with afs_disconDirtyLock */
763     struct afs_q shadowq;
764     /*! Queue of vcaches with dirty metadata. Locked by afs_xvcdirty */
765     struct afs_q metadirty;
766     /*! Vcaches slot number in the disk backup. Protected by tvc->lock */
767     afs_uint32 diskSlot;
768 #endif
769     struct fvcache f;
770     afs_rwlock_t lock;          /* The lock on the vcache contents. */
771 #if     defined(AFS_SUN5_ENV)
772     /* Lock used to protect the activeV, multipage, and vstates fields.
773      * Do not try to get the vcache lock when the vlock is held */
774     afs_rwlock_t vlock;
775 #endif                          /* defined(AFS_SUN5_ENV) */
776 #if     defined(AFS_SUN5_ENV)
777     krwlock_t rwlock;
778     struct cred *credp;
779 #endif
780 #ifdef AFS_BOZONLOCK_ENV
781     afs_bozoLock_t pvnLock;     /* see locks.x */
782 #endif
783 #ifdef  AFS_AIX32_ENV
784     afs_lock_t pvmlock;
785     vmhandle_t vmh;
786 #if defined(AFS_AIX51_ENV)
787     vmid_t segid;
788 #else
789     int segid;
790 #endif
791     struct ucred *credp;
792 #endif
793 #ifdef AFS_AIX_ENV
794     int ownslock;               /* pid of owner of excl lock, else 0 - defect 3083 */
795 #endif
796 #ifdef AFS_DARWIN80_ENV
797     lck_mtx_t *rwlock;
798 #elif defined(AFS_DARWIN_ENV)
799     struct lock__bsd__ rwlock;
800 #endif
801 #ifdef AFS_XBSD_ENV
802 #if !defined(AFS_DFBSD_ENV)
803     struct lock rwlock;
804 #endif
805 #endif
806
807     struct VenusFid *mvid;      /* Either parent dir (if root) or root (if mt pt) */
808     char *linkData;             /* Link data if a symlink. */
809     afs_hyper_t flushDV;        /* data version last flushed from text */
810     afs_hyper_t mapDV;          /* data version last flushed from map */
811     struct server *callback;    /* The callback host, if any */
812     afs_uint32 cbExpires;       /* time the callback expires */
813     struct afs_q callsort;      /* queue in expiry order, sort of */
814     struct axscache *Access;    /* a list of cached access bits */
815     afs_int32 last_looker;      /* pag/uid from last lookup here */
816 #if     defined(AFS_SUN5_ENV)
817     afs_int32 activeV;
818 #endif                          /* defined(AFS_SUN5_ENV) */
819     struct SimpleLocks *slocks;
820     short opens;                /* The numbers of opens, read or write, on this file. */
821     short execsOrWriters;       /* The number of execs (if < 0) or writers (if > 0) of
822                                  * this file. */
823     short flockCount;           /* count of flock readers, or -1 if writer */
824     char mvstat;                /* 0->normal, 1->mt pt, 2->root. */
825
826 #if defined(AFS_CACHE_BYPASS)
827         char cachingStates;                     /* Caching policies for this file */
828         afs_uint32 cachingTransitions;          /* # of times file has flopped between caching and not */
829 #if defined(AFS_LINUX24_ENV)
830         off_t next_seq_offset;  /* Next sequential offset (used by prefetch/readahead) */
831 #else
832         off_t next_seq_blk_offset; /* accounted in blocks for Solaris & IRIX */
833 #endif
834 #endif
835         
836 #if     defined(AFS_SUN5_ENV)
837     afs_uint32 vstates;         /* vstate bits */
838 #endif                          /* defined(AFS_SUN5_ENV) */
839     struct dcache *dchint;
840     struct dcache *dcreaddir;   /* dcache for in-progress readdir */
841     unsigned int readdir_pid;   /* pid of the thread in readdir */
842 #ifdef AFS_LINUX22_ENV
843     u_short mapcnt;             /* Number of mappings of this file. */
844 #endif
845 #if defined(AFS_SGI_ENV)
846     daddr_t lastr;              /* for read-ahead */
847 #ifdef AFS_SGI64_ENV
848     uint64_t vc_rwlockid;       /* kthread owning rwlock */
849 #else
850     short vc_rwlockid;          /* pid of process owning rwlock */
851 #endif
852     short vc_locktrips;         /* # of rwlock reacquisitions */
853     sema_t vc_rwlock;           /* vop_rwlock for afs */
854     pgno_t mapcnt;              /* # of pages mapped */
855     struct cred *cred;          /* last writer's cred */
856 #ifdef AFS_SGI64_ENV
857     struct bhv_desc vc_bhv_desc;        /* vnode's behavior data. */
858 #endif
859 #endif                          /* AFS_SGI_ENV */
860 #if defined(AFS_LINUX26_ENV)
861     cred_t *cred;               /* last writer's cred */
862 #endif
863     afs_int32 vc_error;         /* stash write error for this vnode. */
864     int xlatordv;               /* Used by nfs xlator */
865     afs_ucred_t *uncred;
866     int asynchrony;             /* num kbytes to store behind */
867 #ifdef AFS_SUN5_ENV
868     short multiPage;            /* count of multi-page getpages in progress */
869 #endif
870 };
871
872 #define DONT_CHECK_MODE_BITS    0
873 #define CHECK_MODE_BITS         1
874 #define CMB_ALLOW_EXEC_AS_READ  2       /* For the NFS xlator */
875
876 #if defined(AFS_SGI_ENV)
877 #define AVCRWLOCK(avc)          (valusema(&(avc)->vc_rwlock) <= 0)
878
879 /* SGI vnode rwlock macros and flags. */
880 #ifndef AFS_SGI62_ENV
881 /* The following are defined here. SGI 6.2 declares them in vnode.h */
882 #define VRWLOCK_READ            0
883 #define VRWLOCK_WRITE           1
884 #define VRWLOCK_WRITE_DIRECT    2
885 #endif
886
887 #ifdef AFS_SGI53_ENV
888 #ifdef AFS_SGI62_ENV
889 #define AFS_RWLOCK_T vrwlock_t
890 #else
891 #define AFS_RWLOCK_T int
892 #endif /* AFS_SGI62_ENV */
893 #ifdef AFS_SGI64_ENV
894 #include <ksys/behavior.h>
895 #define AFS_RWLOCK(V,F) \
896         afs_rwlock(&VTOAFS(V)->vc_bhv_desc, (F));
897 #define AFS_RWUNLOCK(V,F) \
898         afs_rwunlock(&VTOAFS(V)->vc_bhv_desc, (F));
899
900 #else
901 #define AFS_RWLOCK(V,F) afs_rwlock((vnode_t *)(V), (F) )
902 #define AFS_RWUNLOCK(V,F) afs_rwunlock((vnode_t *)(V), (F) )
903 #endif
904 #else /* AFS_SGI53_ENV */
905 #define AFS_RWLOCK(V,F) afs_rwlock((V))
906 #define AFS_RWUNLOCK(V,F) afs_rwunlock((V))
907 #endif /* AFS_SGI53_ENV */
908 #endif /* AFS_SGI_ENV */
909
910 struct vcxstat {
911     struct VenusFid fid;
912     afs_hyper_t DataVersion;
913     afs_rwlock_t lock;
914     afs_int32 parentVnode;
915     afs_int32 parentUnique;
916     afs_hyper_t flushDV;
917     afs_hyper_t mapDV;
918     afs_int32 truncPos;
919     afs_int32 randomUid[CPSIZE];
920     afs_int32 callback;         /* Now a pointer to 'server' struct */
921     afs_int32 cbExpires;
922     afs_int32 randomAccess[CPSIZE];
923     afs_int32 anyAccess;
924     short opens;
925     short execsOrWriters;
926     short flockCount;
927     char mvstat;
928     afs_uint32 states;
929 };
930
931 struct vcxstat2 {
932     afs_int32 callerAccess;
933     afs_int32 cbExpires;
934     afs_int32 anyAccess;
935     char mvstat;
936 };
937
938 struct sbstruct {
939     int sb_thisfile;
940     int sb_default;
941 };
942
943 /* CM inititialization parameters. What CM actually used after calculations
944  * based on passed in arguments.
945  */
946 #define CMI_VERSION 1           /* increment when adding new fields. */
947 struct cm_initparams {
948     int cmi_version;
949     int cmi_nChunkFiles;
950     int cmi_nStatCaches;
951     int cmi_nDataCaches;
952     int cmi_nVolumeCaches;
953     int cmi_firstChunkSize;
954     int cmi_otherChunkSize;
955     int cmi_cacheSize;          /* The original cache size, in 1K blocks. */
956     unsigned cmi_setTime:1;
957     unsigned cmi_memCache:1;
958     int spare[16 - 9];          /* size of struct is 16 * 4 = 64 bytes */
959 };
960
961
962 /*----------------------------------------------------------------------
963  * AFS Data cache definitions
964  *
965  * Each entry describes a Unix file on the local disk that is
966  * is serving as a cached copy of all or part of a Vice file.
967  * Entries live in circular queues for each hash table slot
968  *
969  * Which queue is this thing in?  Good question.
970  * A struct dcache entry is in the freeDSlot queue when not associated with a cache slot (file).
971  * Otherwise, it is in the DLRU queue.  The freeDSlot queue uses the lruq.next field as
972  * its "next" pointer.
973  *
974  * Cache entries in the DLRU queue are either associated with vice files, in which case
975  * they are hashed by afs_dvnextTbl and afs_dcnextTbl pointers, or they are in the freeDCList
976  * and are not associated with any vice file.  This last list uses the afs_dvnextTbl pointer for
977  * its "next" pointer.
978  *----------------------------------------------------------------------*/
979
980 #define NULLIDX     (-1)        /* null index definition */
981 /* struct dcache states bits */
982 #define DRO         1
983 #define DBackup     2
984 #define DRW         4
985 #define DWriting    8           /* file being written (used for cache validation) */
986
987 /* dcache data flags */
988 #define DFEntryMod      0x02    /* has entry itself been modified? */
989 #define DFFetching      0x04    /* file is currently being fetched */
990
991 /* dcache meta flags */
992 #define DFNextStarted   0x01    /* next chunk has been prefetched already */
993 #define DFFetchReq      0x10    /* someone is waiting for DFFetching to go on */
994
995
996 /* flags in afs_indexFlags array */
997 #define IFEverUsed      1       /* index entry has >= 1 byte of data */
998 #define IFFree          2       /* index entry in freeDCList */
999 #define IFDataMod       4       /* file needs to be written out */
1000 #define IFFlag          8       /* utility flag */
1001 #define IFDirtyPages    16      /* Solaris-only. contains dirty pages */
1002 #define IFAnyPages      32
1003 #define IFDiscarded     64      /* index entry in discardDCList */
1004
1005 #ifdef AFS_DARWIN100_ENV
1006 typedef user_addr_t iparmtype; /* 64 bit */
1007 typedef user_addr_t uparmtype; /* 64 bit */
1008 #else
1009 typedef char * uparmtype;
1010 #ifdef AFS_SGI65_ENV
1011 typedef afs_uint32 iparmtype;
1012 #else
1013 typedef long iparmtype;
1014 #endif
1015 #endif
1016
1017 #if SIZEOF_VOID_P == SIZEOF_UNSIGNED_INT
1018 # define uintptrsz unsigned int
1019 #elif SIZEOF_VOID_P == SIZEOF_UNSIGNED_LONG
1020 # define uintptrsz unsigned long
1021 #elif SIZEOF_VOID_P == SIZEOF_UNSIGNED_LONG_LONG
1022 # define uintptrsz unsigned long long
1023 #else
1024 # error "Unable to determine casting for pointers"
1025 #endif
1026
1027 struct afs_ioctl {
1028     uparmtype in;               /* input buffer */
1029     uparmtype out;              /* output buffer */
1030     short in_size;              /* Size of input buffer <= 2K */
1031     short out_size;             /* Maximum size of output buffer, <= 2K */
1032 };
1033
1034 /*
1035  * This version of afs_ioctl is required to pass in 32 bit user space
1036  * pointers into a 64 bit kernel.
1037  */
1038
1039 struct afs_ioctl32 {
1040     unsigned int in;
1041     unsigned int out;
1042     short in_size;
1043     short out_size;
1044 };
1045
1046
1047 /* CacheItems file has a header of type struct afs_fheader
1048  * (keep aligned properly). Since we already have sgi_62 clients running
1049  * with a 32 bit inode, a change is required to the header so that
1050  * they can distinguish the old 32 bit inode CacheItems file and zap it 
1051  * instead of using it.
1052  */
1053 struct afs_fheader {
1054 #define AFS_FHMAGIC         0x7635abaf  /* uses version number */
1055     afs_int32 magic;
1056 #define AFS_CI_VERSION 4
1057     afs_int32 version;
1058     afs_uint32 dataSize;
1059     afs_int32 firstCSize;
1060     afs_int32 otherCSize;
1061 };
1062
1063 #if defined(AFS_CACHE_VNODE_PATH)
1064 typedef char *afs_ufs_dcache_id_t;
1065 #elif defined(AFS_SGI61_ENV) || defined(AFS_SUN57_64BIT_ENV)
1066 /* Using ino64_t here so that user level debugging programs compile
1067  * the size correctly.
1068  */
1069 typedef ino64_t afs_ufs_dcache_id_t;
1070 #elif defined(LINUX_USE_FH)
1071 #define MAX_FH_LEN 10
1072 typedef union {
1073      struct fid fh;
1074      __u32 raw[MAX_FH_LEN];
1075 } afs_ufs_dcache_id_t;
1076 extern int cache_fh_type;
1077 extern int cache_fh_len;
1078 #elif defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_S390X_LINUX24_ENV)
1079 typedef long afs_ufs_dcache_id_t;
1080 #elif defined(AFS_AIX51_ENV) || defined(AFS_HPUX1123_ENV)
1081 typedef ino_t afs_ufs_dcache_id_t;
1082 #else
1083 typedef afs_int32 afs_ufs_dcache_id_t;
1084 #endif
1085
1086 typedef afs_int32 afs_mem_dcache_id_t;
1087
1088 typedef union {
1089     afs_ufs_dcache_id_t ufs;
1090     afs_mem_dcache_id_t mem;
1091 } afs_dcache_id_t;
1092
1093 /* it does not compile outside kernel */
1094 struct buffer {
1095   afs_int32 fid;              /* is adc->index, the cache file number */
1096   afs_dcache_id_t inode;          /* is adc->f.inode, the inode number of the cac\
1097                                  he file */
1098   afs_int32 page;
1099   afs_int32 accesstime;
1100   struct buffer *hashNext;
1101   char *data;
1102   char lockers;
1103   char dirty;
1104   char hashIndex;
1105   afs_rwlock_t lock;          /* the lock for this structure */
1106 };
1107
1108 /* kept on disk and in dcache entries */
1109 struct fcache {
1110     struct VenusFid fid;        /* Fid for this file */
1111     afs_int32 modTime;          /* last time this entry was modified */
1112     afs_hyper_t versionNo;      /* Associated data version number */
1113     afs_int32 chunk;            /* Relative chunk number */
1114     afs_dcache_id_t inode;              /* Unix inode for this chunk */
1115     afs_int32 chunkBytes;       /* Num bytes in this chunk */
1116     char states;                /* Has this chunk been modified? */
1117 };
1118
1119 /* magic numbers to specify the cache type */
1120
1121 #define AFS_FCACHE_TYPE_UFS 0x0
1122 #define AFS_FCACHE_TYPE_MEM 0x1
1123 #define AFS_FCACHE_TYPE_NFS 0x2
1124 #define AFS_FCACHE_TYPE_EPI 0x3
1125
1126 /* kept in memory */
1127 struct dcache {
1128     struct afs_q lruq;          /* Free queue for in-memory images */
1129     struct afs_q dirty;         /* Queue of dirty entries that need written */
1130     afs_rwlock_t lock;          /* Protects validPos, some f */
1131     afs_rwlock_t tlock;         /* Atomizes updates to refCount */
1132     afs_rwlock_t mflock;        /* Atomizes accesses/updates to mflags */
1133     afs_size_t validPos;        /* number of valid bytes during fetch */
1134     afs_int32 index;            /* The index in the CacheInfo file */
1135     short refCount;             /* Associated reference count. */
1136     char dflags;                /* Data flags */
1137     char mflags;                /* Meta flags */
1138     struct fcache f;            /* disk image */
1139     afs_int32 bucket;           /* which bucket these dcache entries are in */
1140     /*
1141      * Locking rules:
1142      *
1143      * dcache.lock protects the actual contents of the cache file (in
1144      * f.inode), subfields of f except those noted below, dflags and
1145      * validPos.
1146      *
1147      * dcache.tlock is used to make atomic updates to refCount.  Zero
1148      * refCount dcache entries are protected by afs_xdcache instead of
1149      * tlock.
1150      *
1151      * dcache.mflock is used to access and update mflags.  It cannot be
1152      * held without holding the corresponding dcache.lock.  Updating
1153      * mflags requires holding dcache.lock(R) and dcache.mflock(W), and
1154      * checking for mflags requires dcache.lock(R) and dcache.mflock(R).
1155      * Note that dcache.lock(W) gives you the right to update mflags,
1156      * as dcache.mflock(W) can only be held with dcache.lock(R).
1157      *
1158      * dcache.index, dcache.f.fid, dcache.f.chunk and dcache.f.inode are
1159      * write-protected by afs_xdcache and read-protected by refCount.
1160      * Once an entry is referenced, these values cannot change, and if
1161      * it's on the free list (with refCount=0), it can be reused for a
1162      * different file/chunk.  These values can only be written while
1163      * holding afs_xdcache(W) and allocating this dcache entry (thereby
1164      * ensuring noone else has a refCount on it).
1165      */
1166 };
1167
1168 /* afs_memcache.c */
1169 struct memCacheEntry {
1170   int size;                   /* # of valid bytes in this entry */
1171   int dataSize;               /* size of allocated data area */
1172   afs_lock_t afs_memLock;
1173   char *data;                 /* bytes */
1174 };
1175
1176 struct afs_FetchOutput {
1177     struct AFSVolSync tsync;
1178     struct AFSFetchStatus OutStatus;
1179     struct AFSCallBack CallBack;
1180 };
1181
1182 /* macro to mark a dcache entry as bad */
1183 #define ZapDCE(x) \
1184     do { \
1185         (x)->f.fid.Fid.Unique = 0; \
1186         afs_indexUnique[(x)->index] = 0; \
1187         (x)->dflags |= DFEntryMod; \
1188     } while(0)
1189
1190 /* FakeOpen and Fake Close used to be real subroutines.  They're only used in
1191  * sun_subr and afs_vnodeops, and they're very frequently called, so I made 
1192  * them into macros.  They do:
1193  * FakeOpen:  fake the file being open for writing.  avc->lock must be held
1194  * in write mode.  Having the file open for writing is like having a DFS
1195  * write-token: you're known to have the best version of the data around, 
1196  * and so the CM won't let it be overwritten by random server info.
1197  * FakeClose:  undo the effects of FakeOpen, noting that we want to ensure
1198  * that a real close eventually gets done.  We use CCore to achieve this if
1199  * we would end up closing the file.  avc->lock must be held in write mode */
1200
1201 #ifdef AFS_AIX_IAUTH_ENV
1202 #define CRKEEP(V, C)  (V)->linkData = (char*)crdup((C))
1203 #else
1204 #define CRKEEP(V, C)  crhold((C)); (V)->linkData = (char*)(C)
1205 #endif
1206
1207 #define afs_FakeOpen(avc) { avc->opens++; avc->execsOrWriters++; }
1208 #define afs_FakeClose(avc, acred) \
1209 { if (avc->execsOrWriters == 1) {  \
1210         /* we're the last writer, just use CCore flag */   \
1211         avc->f.states |= CCore; /* causes close to be called later */ \
1212                                                                       \
1213         /* The cred and vnode holds will be released in afs_FlushActiveVcaches */  \
1214         AFS_FAST_HOLD(avc);     /* So it won't disappear */           \
1215         CRKEEP(avc, acred); /* Should use a better place for the creds */ \
1216     }                                                                         \
1217     else {                                                                    \
1218         /* we're not the last writer, let the last one do the store-back for us */    \
1219         avc->opens--;                                                         \
1220         avc->execsOrWriters--;                                                \
1221     }                                                                         \
1222 }
1223
1224 #define AFS_ZEROS   64          /* zero buffer */
1225
1226 /*#define afs_DirtyPages(avc)   (((avc)->f.states & CDirty) || osi_VMDirty_p((avc)))*/
1227 #define afs_DirtyPages(avc)     ((avc)->f.states & CDirty)
1228
1229 #define afs_InReadDir(avc) (((avc)->f.states & CReadDir) && (avc)->readdir_pid == MyPidxx2Pid(MyPidxx))
1230
1231 /* The PFlush algorithm makes use of the fact that Fid.Unique is not used in
1232   below hash algorithms.  Change it if need be so that flushing algorithm
1233   doesn't move things from one hash chain to another
1234 */
1235 /* extern int afs_dhashsize; */
1236 #define DCHash(v, c)    ((((v)->Fid.Vnode + (v)->Fid.Volume + (c))) & (afs_dhashsize-1))
1237         /*Vnode, Chunk -> Hash table index */
1238 #define DVHash(v)       ((((v)->Fid.Vnode + (v)->Fid.Volume )) & (afs_dhashsize-1))
1239         /*Vnode -> Other hash table index */
1240 /* don't hash on the cell, our callback-breaking code sometimes fails to compute
1241     the cell correctly, and only scans one hash bucket */
1242 #define VCHash(fid)     (((fid)->Fid.Volume + (fid)->Fid.Vnode) & (VCSIZE-1))
1243 /* Hash only on volume to speed up volume callbacks. */
1244 #define VCHashV(fid) ((fid)->Fid.Volume & (VCSIZE-1))
1245
1246 extern struct dcache **afs_indexTable;  /*Pointers to in-memory dcache entries */
1247 extern afs_int32 *afs_indexUnique;      /*dcache entry Fid.Unique */
1248 extern afs_int32 *afs_dvnextTbl;        /*Dcache hash table links */
1249 extern afs_int32 *afs_dcnextTbl;        /*Dcache hash table links */
1250 extern afs_int32 afs_cacheFiles;        /*Size of afs_indexTable */
1251 extern afs_int32 afs_cacheBlocks;       /*1K blocks in cache */
1252 extern afs_int32 afs_cacheStats;        /*Stat entries in cache */
1253 extern struct vcache *afs_vhashT[VCSIZE];       /*Stat cache hash table */
1254 extern struct afs_q afs_vhashTV[VCSIZE]; /* cache hash table on volume */
1255 extern afs_int32 afs_initState; /*Initialization state */
1256 extern afs_int32 afs_termState; /* Termination state */
1257 extern struct VenusFid afs_rootFid;     /*Root for whole file system */
1258 extern afs_int32 afs_allCBs;    /* Count of callbacks */
1259 extern afs_int32 afs_oddCBs;    /* Count of odd callbacks */
1260 extern afs_int32 afs_evenCBs;   /* Count of even callbacks */
1261 extern afs_int32 afs_allZaps;   /* Count of fid deletes */
1262 extern afs_int32 afs_oddZaps;   /* Count of odd fid deletes */
1263 extern afs_int32 afs_evenZaps;  /* Count of even fid deletes */
1264 extern struct brequest afs_brs[NBRS];   /* request structures */
1265
1266 #define UHash(auid)     ((auid) & (NUSERS-1))
1267 #define VHash(avol)     ((avol)&(NVOLS-1))
1268 #define SHash(aserv)    ((ntohl(aserv)) & (NSERVERS-1))
1269 #define FVHash(acell,avol)  (((avol)+(acell)) & (NFENTRIES-1))
1270
1271 /* Performance hack - we could replace VerifyVCache2 with the appropriate
1272  * GetVCache incantation, and could eliminate even this code from afs_UFSRead 
1273  * by making intentionally invalidating quick.stamp in the various callbacks
1274  * expiration/breaking code */
1275 #ifdef AFS_DARWIN_ENV
1276 #define afs_VerifyVCache(avc, areq)  \
1277   (((avc)->f.states & CStatd) ? (osi_VM_Setup(avc, 0), 0) : \
1278    afs_VerifyVCache2((avc),areq))
1279 #else
1280 #define afs_VerifyVCache(avc, areq)  \
1281   (((avc)->f.states & CStatd) ? 0 : afs_VerifyVCache2((avc),areq))
1282 #endif
1283
1284 #define DO_STATS 1              /* bits used by FindVCache */
1285 #define DO_VLRU 2
1286 #define IS_SLOCK 4
1287 #define IS_WLOCK 8
1288 #define FIND_CDEAD 16
1289
1290 /* values for flag param of afs_CheckVolumeNames */
1291 #define AFS_VOLCHECK_EXPIRED    0x1     /* volumes whose callbacks have expired */
1292 #define AFS_VOLCHECK_BUSY       0x2     /* volumes which were marked busy */
1293 #define AFS_VOLCHECK_MTPTS      0x4     /* mount point invalidation also */
1294 #define AFS_VOLCHECK_FORCE      0x8     /* do all forcibly */
1295
1296 #endif /* KERNEL */
1297
1298 #define AFS_FSPORT          ((unsigned short) htons(7000))
1299 #define AFS_VLPORT          ((unsigned short) htons(7003))
1300
1301 #define afs_read(avc, uio, acred, albn, abpp, nolock) \
1302         (*(afs_cacheType->vread))(avc, uio, acred, albn, abpp, nolock)
1303 #define afs_write(avc, uio, aio, acred, nolock) \
1304         (*(afs_cacheType->vwrite))(avc, uio, aio, acred, nolock)
1305
1306 #define afs_rdwr(avc, uio, rw, io, cred) \
1307     (((rw) == UIO_WRITE) ? afs_write(avc, uio, io, cred, 0) : afs_read(avc, uio, cred, 0, 0, 0))
1308 #define afs_nlrdwr(avc, uio, rw, io, cred) \
1309     (((rw) == UIO_WRITE) ? afs_write(avc, uio, io, cred, 1) : afs_read(avc, uio, cred, 0, 0, 1))
1310
1311 /* Cache size truncation uses the following low and high water marks:
1312  * If the cache is more than 95% full (CM_DCACHECOUNTFREEPCT), the cache
1313  * truncation daemon is awakened and will free up space until the cache is 85%
1314  * (CM_DCACHESPACEFREEPCT - CM_DCACHEEXTRAPCT) full.
1315  * afs_UFSWrite and afs_GetDCache (when it needs to fetch data) will wait on
1316  * afs_WaitForCacheDrain if the cache is 98% (CM_WAITFORDRAINPCT) full.
1317  * afs_GetDownD wakes those processes once the cache is 95% full
1318  * (CM_CACHESIZEDRAINEDPCT).
1319  */
1320 #define CM_MAXDISCARDEDCHUNKS   16      /* # of chunks */
1321 #define CM_DCACHECOUNTFREEPCT   95      /* max pct of chunks in use */
1322 #define CM_DCACHESPACEFREEPCT   90      /* max pct of space in use */
1323 #define CM_DCACHEEXTRAPCT        5      /* extra to get when freeing */
1324 #define CM_CACHESIZEDRAINEDPCT  95      /* wakeup processes when down to here. */
1325 #define CM_WAITFORDRAINPCT      98      /* sleep if cache is this full. */
1326
1327 /* when afs_cacheBlocks is large, settle for slightly decreased precision */
1328 #define PERCENT(p, v) \
1329     ((afs_cacheBlocks & 0xffe00000) ? ((v) / 100 * (p)) : ((p) * (v) / 100))
1330
1331 #define afs_CacheIsTooFull() \
1332     (afs_blocksUsed - afs_blocksDiscarded > \
1333         PERCENT(CM_DCACHECOUNTFREEPCT, afs_cacheBlocks) || \
1334      afs_freeDCCount - afs_discardDCCount < \
1335         PERCENT(100 - CM_DCACHECOUNTFREEPCT, afs_cacheFiles))
1336
1337 /* Handy max length of a numeric string. */
1338 #define CVBS    12              /* max afs_int32 is 2^32 ~ 4*10^9, +1 for NULL, +luck */
1339
1340 #define refpanic(foo) if (afs_norefpanic) \
1341         { printf( foo ); afs_norefpanic++;} else osi_Panic( foo )
1342
1343 /* 
1344 ** these are defined in the AIX source code sys/fs_locks.h but are not
1345 ** defined anywhere in the /usr/include directory
1346 */
1347 #if     defined(AFS_AIX41_ENV)
1348 #define VN_LOCK(vp)             simple_lock(&(vp)->v_lock)
1349 #define VN_UNLOCK(vp)           simple_unlock(&(vp)->v_lock)
1350 #endif
1351
1352 /* get a file's serial number from a vnode */
1353 #ifndef afs_vnodeToInumber
1354 #if defined(AFS_SGI62_ENV) || defined(AFS_HAVE_VXFS) || defined(AFS_DARWIN_ENV)
1355 #define afs_vnodeToInumber(V) VnodeToIno(V)
1356 #else
1357 #define afs_vnodeToInumber(V) (VTOI(V)->i_number)
1358 #endif /* AFS_SGI62_ENV */
1359 #endif
1360
1361 /* get a file's device number from a vnode */
1362 #ifndef afs_vnodeToDev
1363 #if defined(AFS_SGI62_ENV) || defined(AFS_HAVE_VXFS) || defined(AFS_DARWIN_ENV)
1364 #define afs_vnodeToDev(V) VnodeToDev(V)
1365 #elif defined(UKERNEL)
1366 #define afs_vnodeToDev(V) (VTOI(V) ? (VTOI(V)->i_dev) : (-1))
1367 #else
1368 #define afs_vnodeToDev(V) (VTOI(V)->i_dev)
1369 #endif
1370 #endif
1371
1372 /* declare something so that prototypes don't flip out */
1373 /* appears struct buf stuff is only actually passed around as a pointer, 
1374    except with libuafs, in which case it is actually defined */
1375
1376 struct buf;
1377
1378 struct rxfs_storeVariables {
1379     struct rx_call *call;
1380     struct vcache *vcache;
1381     char *tbuffer;
1382     struct iovec *tiov;
1383     afs_int32 tnio;
1384     afs_int32 hasNo64bit;
1385     struct AFSStoreStatus InStatus;
1386 };
1387
1388 struct storeOps {
1389     int (*prepare)(void *rock, afs_uint32 size, afs_uint32 *bytestoxfer);
1390     int (*read)(void *rock, struct osi_file *tfile, afs_uint32 offset,
1391         afs_uint32 tlen, afs_uint32 *bytesread);
1392     int (*write)(void *rock, afs_uint32 tlen, afs_uint32 *byteswritten);
1393     int (*status)(void *rock);
1394     int (*padd)(void *rock, afs_uint32 tlen);
1395     int (*close)(void *rock, struct AFSFetchStatus *OutStatus,
1396         afs_int32 *doProcessFS);
1397     int (*destroy)(void **rock, afs_int32 error);
1398     int (*storeproc)(struct storeOps *, void *, struct dcache *, int *,
1399                      afs_size_t *);
1400 };
1401
1402 struct fetchOps {
1403     int (*more)(void *rock, afs_int32 *length, afs_uint32 *moredata);
1404     int (*read)(void *rock, afs_uint32 tlen, afs_uint32 *bytesread);
1405     int (*write)(void *rock, struct osi_file *fp, afs_uint32 offset,
1406         afs_uint32 tlen, afs_uint32 *byteswritten);
1407     int (*close)(void *rock, struct vcache *avc, struct dcache *adc,
1408         struct afs_FetchOutput *Outputs);
1409     int (*destroy)(void **rock, afs_int32 error);
1410 };
1411
1412 /* fakestat support: opaque storage for afs_EvalFakeStat to remember
1413  * what vcache should be released.
1414  */
1415 struct afs_fakestat_state {
1416     char valid;
1417     char did_eval;
1418     char need_release;
1419     struct vcache *root_vp;
1420 };
1421
1422 extern int afs_fakestat_enable;
1423
1424 #ifdef AFS_MAXVCOUNT_ENV
1425 extern int afsd_dynamic_vcaches;
1426 #else
1427 #define afsd_dynamic_vcaches 0
1428 #endif
1429
1430 /*
1431  * Wrappers for access to credentials structure members
1432  * Linux uses the kernel cred structure if available, with the
1433  * wrappers defined in LINUX/osi_machdep.h
1434  */
1435 #if defined(AFS_NBSD40_ENV)
1436 /* in osi_machdep.h as expected */
1437 #elif !(defined(AFS_LINUX26_ENV) && defined(STRUCT_TASK_STRUCT_HAS_CRED))
1438 #define afs_cr_uid(cred) ((cred)->cr_uid)
1439 #define afs_cr_gid(cred) ((cred)->cr_gid)
1440 #define afs_cr_ruid(cred) ((cred)->cr_ruid)
1441 #define afs_cr_rgid(cred) ((cred)->cr_rgid)
1442
1443 static_inline void
1444 afs_set_cr_uid(afs_ucred_t *cred, uid_t uid) {
1445     cred->cr_uid = uid;
1446 }
1447 static_inline void
1448 afs_set_cr_gid(afs_ucred_t *cred, gid_t gid) {
1449     cred->cr_gid = gid;
1450 }
1451 static_inline void
1452 afs_set_cr_ruid(afs_ucred_t *cred, uid_t uid) {
1453     cred->cr_ruid = uid;
1454 }
1455 static_inline void
1456 afs_set_cr_rgid(afs_ucred_t *cred, gid_t gid) {
1457     cred->cr_rgid = gid;
1458 }
1459 #endif
1460 #endif /* _AFS_H_ */