1368c31abSDavid du Colombier typedef struct Config Config; 2368c31abSDavid du Colombier typedef struct AMap AMap; 3368c31abSDavid du Colombier typedef struct AMapN AMapN; 4368c31abSDavid du Colombier typedef struct Arena Arena; 5368c31abSDavid du Colombier typedef struct AState AState; 6f9e1cf08SDavid du Colombier typedef struct ArenaCIG ArenaCIG; 7368c31abSDavid du Colombier typedef struct ArenaHead ArenaHead; 8368c31abSDavid du Colombier typedef struct ArenaPart ArenaPart; 9368c31abSDavid du Colombier typedef struct ArenaTail ArenaTail; 10368c31abSDavid du Colombier typedef struct ATailStats ATailStats; 11368c31abSDavid du Colombier typedef struct CIBlock CIBlock; 12368c31abSDavid du Colombier typedef struct Clump Clump; 13368c31abSDavid du Colombier typedef struct ClumpInfo ClumpInfo; 14368c31abSDavid du Colombier typedef struct Graph Graph; 15368c31abSDavid du Colombier typedef struct IAddr IAddr; 16368c31abSDavid du Colombier typedef struct IBucket IBucket; 17368c31abSDavid du Colombier typedef struct IEStream IEStream; 18368c31abSDavid du Colombier typedef struct IEntry IEntry; 19368c31abSDavid du Colombier typedef struct IFile IFile; 20368c31abSDavid du Colombier typedef struct ISect ISect; 21368c31abSDavid du Colombier typedef struct Index Index; 22368c31abSDavid du Colombier typedef struct Lump Lump; 23368c31abSDavid du Colombier typedef struct DBlock DBlock; 24368c31abSDavid du Colombier typedef struct Part Part; 25368c31abSDavid du Colombier typedef struct Statbin Statbin; 26368c31abSDavid du Colombier typedef struct Statdesc Statdesc; 27368c31abSDavid du Colombier typedef struct Stats Stats; 28368c31abSDavid du Colombier typedef struct ZBlock ZBlock; 29368c31abSDavid du Colombier typedef struct Round Round; 30368c31abSDavid du Colombier typedef struct Bloom Bloom; 31368c31abSDavid du Colombier 32f9e1cf08SDavid du Colombier #pragma incomplete IEStream 33f9e1cf08SDavid du Colombier 34368c31abSDavid du Colombier #define TWID32 ((u32int)~(u32int)0) 35368c31abSDavid du Colombier #define TWID64 ((u64int)~(u64int)0) 36368c31abSDavid du Colombier #define TWID8 ((u8int)~(u8int)0) 37368c31abSDavid du Colombier 38368c31abSDavid du Colombier enum 39368c31abSDavid du Colombier { 40368c31abSDavid du Colombier ABlockLog = 9, /* log2(512), the quantum for reading arenas */ 41368c31abSDavid du Colombier ANameSize = 64, 42368c31abSDavid du Colombier MaxDiskBlock = 64*1024, /* max. allowed size for a disk block */ 43368c31abSDavid du Colombier MaxIoSize = 64*1024, /* max. allowed size for a disk io operation */ 44368c31abSDavid du Colombier PartBlank = 256*1024, /* untouched section at beginning of partition */ 45368c31abSDavid du Colombier HeadSize = 512, /* size of a header after PartBlank */ 46368c31abSDavid du Colombier MinArenaSize = 1*1024*1024, /* smallest reasonable arena size */ 47368c31abSDavid du Colombier IndexBase = 1024*1024, /* initial address to use in an index */ 48368c31abSDavid du Colombier MaxIo = 64*1024, /* max size of a single read or write operation */ 49368c31abSDavid du Colombier ICacheBits = 16, /* default bits for indexing icache */ 5068860d28SDavid du Colombier MaxAMap = 31*1024, /* max. allowed arenas in an address mapping; must be < 32*1024 */ 51*1206f3fcSDavid du Colombier Unspecified = TWID32, 52368c31abSDavid du Colombier 53368c31abSDavid du Colombier /* 54368c31abSDavid du Colombier * return codes from syncarena 55368c31abSDavid du Colombier */ 56368c31abSDavid du Colombier SyncDataErr = 1 << 0, /* problem reading the clump data */ 57368c31abSDavid du Colombier SyncCIErr = 1 << 1, /* found erroneous clump directory entries */ 58368c31abSDavid du Colombier SyncCIZero = 1 << 2, /* found unwritten clump directory entries */ 59368c31abSDavid du Colombier SyncFixErr = 1 << 3, /* error writing fixed data */ 60368c31abSDavid du Colombier SyncHeader = 1 << 4, /* altered header fields */ 61368c31abSDavid du Colombier 62368c31abSDavid du Colombier /* 63368c31abSDavid du Colombier * error severity 64368c31abSDavid du Colombier */ 65368c31abSDavid du Colombier EOk = 0, /* error expected in normal operation */ 66368c31abSDavid du Colombier EStrange, /* strange error that should be logged */ 67368c31abSDavid du Colombier ECorrupt, /* corrupted data found in arenas */ 68368c31abSDavid du Colombier EICorrupt, /* corrupted data found in index */ 69368c31abSDavid du Colombier EAdmin, /* should be brought to administrators' attention */ 70368c31abSDavid du Colombier ECrash, /* really bad internal error */ 71368c31abSDavid du Colombier EBug, /* a limitation which should be fixed */ 72368c31abSDavid du Colombier EInconsist, /* inconsistencies between index and arena */ 73368c31abSDavid du Colombier EMax, 74368c31abSDavid du Colombier 75368c31abSDavid du Colombier /* 76368c31abSDavid du Colombier * internal disk formats for the venti archival storage system 77368c31abSDavid du Colombier */ 78368c31abSDavid du Colombier /* 79368c31abSDavid du Colombier * magic numbers on disk 80368c31abSDavid du Colombier */ 81368c31abSDavid du Colombier _ClumpMagic = 0xd15cb10cU, /* clump header, deprecated */ 82368c31abSDavid du Colombier ClumpFreeMagic = 0, /* free clump; terminates active clump log */ 83368c31abSDavid du Colombier 84368c31abSDavid du Colombier ArenaPartMagic = 0xa9e4a5e7U, /* arena partition header */ 85368c31abSDavid du Colombier ArenaMagic = 0xf2a14eadU, /* arena trailer */ 86368c31abSDavid du Colombier ArenaHeadMagic = 0xd15c4eadU, /* arena header */ 87368c31abSDavid du Colombier 88368c31abSDavid du Colombier BloomMagic = 0xb1004eadU, /* bloom filter header */ 89368c31abSDavid du Colombier BloomMaxHash = 32, 90368c31abSDavid du Colombier 91368c31abSDavid du Colombier ISectMagic = 0xd15c5ec7U, /* index header */ 92368c31abSDavid du Colombier 93368c31abSDavid du Colombier ArenaPartVersion = 3, 94368c31abSDavid du Colombier ArenaVersion4 = 4, 95368c31abSDavid du Colombier ArenaVersion5 = 5, 96368c31abSDavid du Colombier BloomVersion = 1, 97368c31abSDavid du Colombier IndexVersion = 1, 98368c31abSDavid du Colombier ISectVersion1 = 1, 99368c31abSDavid du Colombier ISectVersion2 = 2, 100368c31abSDavid du Colombier 101368c31abSDavid du Colombier /* 102368c31abSDavid du Colombier * encodings of clumps on disk 103368c31abSDavid du Colombier */ 104368c31abSDavid du Colombier ClumpEErr = 0, /* can't happen */ 105368c31abSDavid du Colombier ClumpENone, /* plain */ 106368c31abSDavid du Colombier ClumpECompress, /* compressed */ 107368c31abSDavid du Colombier ClumpEMax, 108368c31abSDavid du Colombier 109368c31abSDavid du Colombier /* 110368c31abSDavid du Colombier * sizes in bytes on disk 111368c31abSDavid du Colombier */ 112368c31abSDavid du Colombier U8Size = 1, 113368c31abSDavid du Colombier U16Size = 2, 114368c31abSDavid du Colombier U32Size = 4, 115368c31abSDavid du Colombier U64Size = 8, 116368c31abSDavid du Colombier 117368c31abSDavid du Colombier ArenaPartSize = 4 * U32Size, 118368c31abSDavid du Colombier ArenaSize4 = 2 * U64Size + 6 * U32Size + ANameSize + U8Size, 119368c31abSDavid du Colombier ArenaSize5 = ArenaSize4 + U32Size, 120368c31abSDavid du Colombier ArenaSize5a = ArenaSize5 + 2 * U8Size + 2 * U32Size + 2 * U64Size, 121368c31abSDavid du Colombier ArenaHeadSize4 = U64Size + 3 * U32Size + ANameSize, 122368c31abSDavid du Colombier ArenaHeadSize5 = ArenaHeadSize4 + U32Size, 123368c31abSDavid du Colombier BloomHeadSize = 4 * U32Size, 124368c31abSDavid du Colombier ISectSize1 = 7 * U32Size + 2 * ANameSize, 125368c31abSDavid du Colombier ISectSize2 = ISectSize1 + U32Size, 126368c31abSDavid du Colombier ClumpInfoSize = U8Size + 2 * U16Size + VtScoreSize, 127368c31abSDavid du Colombier ClumpSize = ClumpInfoSize + U8Size + 3 * U32Size, 128368c31abSDavid du Colombier MaxBloomSize = 1<<(32-3), /* 2^32 bits */ 129368c31abSDavid du Colombier MaxBloomHash = 32, /* bits per score */ 130368c31abSDavid du Colombier /* 131368c31abSDavid du Colombier * BUG - The various block copies that manipulate entry buckets 132368c31abSDavid du Colombier * would be faster if we bumped IBucketSize up to 8 and IEntrySize up to 40, 133368c31abSDavid du Colombier * so that everything is word-aligned. Buildindex is actually cpu-bound 134368c31abSDavid du Colombier * by the (byte at a time) copying in qsort. 135368c31abSDavid du Colombier */ 136368c31abSDavid du Colombier IBucketSize = U32Size + U16Size, 137368c31abSDavid du Colombier IEntrySize = U64Size + U32Size + 2*U16Size + 2*U8Size + VtScoreSize, 138368c31abSDavid du Colombier IEntryTypeOff = VtScoreSize + U32Size + U16Size + U64Size + U16Size, 139368c31abSDavid du Colombier IEntryAddrOff = VtScoreSize + U32Size + U16Size, 140368c31abSDavid du Colombier 141368c31abSDavid du Colombier MaxClumpBlocks = (VtMaxLumpSize + ClumpSize + (1 << ABlockLog) - 1) >> ABlockLog, 142368c31abSDavid du Colombier 143368c31abSDavid du Colombier IcacheFrac = 1000000, /* denominator */ 144368c31abSDavid du Colombier 145368c31abSDavid du Colombier SleepForever = 1000000000, /* magic value for sleep time */ 146368c31abSDavid du Colombier /* 147368c31abSDavid du Colombier * dirty flags - order controls disk write order 148368c31abSDavid du Colombier */ 149368c31abSDavid du Colombier DirtyArena = 1, 150368c31abSDavid du Colombier DirtyArenaCib, 151368c31abSDavid du Colombier DirtyArenaTrailer, 152368c31abSDavid du Colombier DirtyMax, 153368c31abSDavid du Colombier 154f9e1cf08SDavid du Colombier ArenaCIGSize = 10*1024, // about 0.5 MB worth of IEntry. 155f9e1cf08SDavid du Colombier 156368c31abSDavid du Colombier VentiZZZZZZZZ 157368c31abSDavid du Colombier }; 158368c31abSDavid du Colombier 159368c31abSDavid du Colombier extern char TraceDisk[]; 160368c31abSDavid du Colombier extern char TraceLump[]; 161368c31abSDavid du Colombier extern char TraceBlock[]; 162368c31abSDavid du Colombier extern char TraceProc[]; 163368c31abSDavid du Colombier extern char TraceWork[]; 164368c31abSDavid du Colombier extern char TraceQuiet[]; 165368c31abSDavid du Colombier extern char TraceRpc[]; 166368c31abSDavid du Colombier 167368c31abSDavid du Colombier /* 168368c31abSDavid du Colombier * results of parsing and initializing a config file 169368c31abSDavid du Colombier */ 170368c31abSDavid du Colombier struct Config 171368c31abSDavid du Colombier { 172368c31abSDavid du Colombier char *index; /* name of the index to initialize */ 173368c31abSDavid du Colombier int naparts; /* arena partitions initialized */ 174368c31abSDavid du Colombier ArenaPart **aparts; 175368c31abSDavid du Colombier int nsects; /* index sections initialized */ 176368c31abSDavid du Colombier ISect **sects; 177368c31abSDavid du Colombier Bloom *bloom; /* bloom filter */ 178368c31abSDavid du Colombier u32int bcmem; 179368c31abSDavid du Colombier u32int mem; 180368c31abSDavid du Colombier u32int icmem; 181368c31abSDavid du Colombier int queuewrites; 182368c31abSDavid du Colombier char* haddr; 183368c31abSDavid du Colombier char* vaddr; 184368c31abSDavid du Colombier char* webroot; 185368c31abSDavid du Colombier }; 186368c31abSDavid du Colombier 187368c31abSDavid du Colombier /* 188368c31abSDavid du Colombier * a Part is the low level interface to files or disks. 189368c31abSDavid du Colombier * there are two main types of partitions 190368c31abSDavid du Colombier * arena paritions, which some number of arenas, each in a sub-partition. 191368c31abSDavid du Colombier * index partition, which only have one subpartition. 192368c31abSDavid du Colombier */ 193368c31abSDavid du Colombier struct Part 194368c31abSDavid du Colombier { 195368c31abSDavid du Colombier int fd; /* rock for accessing the disk */ 196368c31abSDavid du Colombier int mode; 197368c31abSDavid du Colombier u64int offset; 198368c31abSDavid du Colombier u64int size; /* size of the partiton */ 199368c31abSDavid du Colombier u32int blocksize; /* block size for reads and writes */ 200368c31abSDavid du Colombier u32int fsblocksize; /* minimum file system block size */ 201368c31abSDavid du Colombier char *name; 202368c31abSDavid du Colombier char *filename; 203368c31abSDavid du Colombier Channel *writechan; /* chan[dcache.nblock](DBlock*) */ 204368c31abSDavid du Colombier }; 205368c31abSDavid du Colombier 206368c31abSDavid du Colombier /* 207368c31abSDavid du Colombier * a cached block from the partition 208368c31abSDavid du Colombier * yuck -- most of this is internal structure for the cache 209368c31abSDavid du Colombier * all other routines should only use data 210368c31abSDavid du Colombier */ 211368c31abSDavid du Colombier struct DBlock 212368c31abSDavid du Colombier { 213368c31abSDavid du Colombier u8int *data; 214368c31abSDavid du Colombier 215368c31abSDavid du Colombier Part *part; /* partition in which cached */ 216368c31abSDavid du Colombier u64int addr; /* base address on the partition */ 217368c31abSDavid du Colombier u32int size; /* amount of data available, not amount allocated; should go away */ 218368c31abSDavid du Colombier u32int mode; 219368c31abSDavid du Colombier u32int dirty; 220368c31abSDavid du Colombier u32int dirtying; 221368c31abSDavid du Colombier DBlock *next; /* doubly linked hash chains */ 222368c31abSDavid du Colombier DBlock *prev; 223368c31abSDavid du Colombier u32int heap; /* index in heap table */ 224368c31abSDavid du Colombier u32int used; /* last reference times */ 225368c31abSDavid du Colombier u32int used2; 226368c31abSDavid du Colombier u32int ref; /* reference count */ 227368c31abSDavid du Colombier RWLock lock; /* for access to data only */ 228368c31abSDavid du Colombier Channel *writedonechan; 229368c31abSDavid du Colombier void* chanbuf[1]; /* buffer for the chan! */ 230368c31abSDavid du Colombier }; 231368c31abSDavid du Colombier 232368c31abSDavid du Colombier /* 233368c31abSDavid du Colombier * a cached block from the partition 234368c31abSDavid du Colombier * yuck -- most of this is internal structure for the cache 235368c31abSDavid du Colombier * all other routines should only use data 236368c31abSDavid du Colombier * double yuck -- this is mostly the same as a DBlock 237368c31abSDavid du Colombier */ 238368c31abSDavid du Colombier struct Lump 239368c31abSDavid du Colombier { 240368c31abSDavid du Colombier Packet *data; 241368c31abSDavid du Colombier 242368c31abSDavid du Colombier Part *part; /* partition in which cached */ 243368c31abSDavid du Colombier u8int score[VtScoreSize]; /* score of packet */ 244368c31abSDavid du Colombier u8int type; /* type of packet */ 245368c31abSDavid du Colombier u32int size; /* amount of data allocated to hold packet */ 246368c31abSDavid du Colombier Lump *next; /* doubly linked hash chains */ 247368c31abSDavid du Colombier Lump *prev; 248368c31abSDavid du Colombier u32int heap; /* index in heap table */ 249368c31abSDavid du Colombier u32int used; /* last reference times */ 250368c31abSDavid du Colombier u32int used2; 251368c31abSDavid du Colombier u32int ref; /* reference count */ 252368c31abSDavid du Colombier QLock lock; /* for access to data only */ 253368c31abSDavid du Colombier }; 254368c31abSDavid du Colombier 255368c31abSDavid du Colombier /* 256368c31abSDavid du Colombier * mapping between names and address ranges 257368c31abSDavid du Colombier */ 258368c31abSDavid du Colombier struct AMap 259368c31abSDavid du Colombier { 260368c31abSDavid du Colombier u64int start; 261368c31abSDavid du Colombier u64int stop; 262368c31abSDavid du Colombier char name[ANameSize]; 263368c31abSDavid du Colombier }; 264368c31abSDavid du Colombier 265368c31abSDavid du Colombier /* 266368c31abSDavid du Colombier * an AMap along with a length 267368c31abSDavid du Colombier */ 268368c31abSDavid du Colombier struct AMapN 269368c31abSDavid du Colombier { 270368c31abSDavid du Colombier int n; 271368c31abSDavid du Colombier AMap *map; 272368c31abSDavid du Colombier }; 273368c31abSDavid du Colombier 274368c31abSDavid du Colombier /* 275368c31abSDavid du Colombier * an ArenaPart is a partition made up of Arenas 276368c31abSDavid du Colombier * it exists because most os's don't support many partitions, 277368c31abSDavid du Colombier * and we want to have many different Arenas 278368c31abSDavid du Colombier */ 279368c31abSDavid du Colombier struct ArenaPart 280368c31abSDavid du Colombier { 281368c31abSDavid du Colombier Part *part; 282368c31abSDavid du Colombier u64int size; /* size of underlying partition, rounded down to blocks */ 283368c31abSDavid du Colombier Arena **arenas; 284368c31abSDavid du Colombier u32int tabbase; /* base address of arena table on disk */ 285368c31abSDavid du Colombier u32int tabsize; /* max. bytes in arena table */ 286368c31abSDavid du Colombier 287368c31abSDavid du Colombier /* 288368c31abSDavid du Colombier * fields stored on disk 289368c31abSDavid du Colombier */ 290368c31abSDavid du Colombier u32int version; 291368c31abSDavid du Colombier u32int blocksize; /* "optimal" block size for reads and writes */ 292368c31abSDavid du Colombier u32int arenabase; /* base address of first arena */ 293368c31abSDavid du Colombier 294368c31abSDavid du Colombier /* 295368c31abSDavid du Colombier * stored in the arena mapping table on disk 296368c31abSDavid du Colombier */ 297368c31abSDavid du Colombier AMap *map; 298368c31abSDavid du Colombier int narenas; 299368c31abSDavid du Colombier }; 300368c31abSDavid du Colombier 301368c31abSDavid du Colombier /* 302368c31abSDavid du Colombier * info about one block in the clump info cache 303368c31abSDavid du Colombier */ 304368c31abSDavid du Colombier struct CIBlock 305368c31abSDavid du Colombier { 306368c31abSDavid du Colombier u32int block; /* blocks in the directory */ 307368c31abSDavid du Colombier int offset; /* offsets of one clump in the data */ 308368c31abSDavid du Colombier DBlock *data; 309368c31abSDavid du Colombier }; 310368c31abSDavid du Colombier 311368c31abSDavid du Colombier /* 312368c31abSDavid du Colombier * Statistics kept in the tail. 313368c31abSDavid du Colombier */ 314368c31abSDavid du Colombier struct ATailStats 315368c31abSDavid du Colombier { 316368c31abSDavid du Colombier u32int clumps; /* number of clumps */ 317368c31abSDavid du Colombier u32int cclumps; /* number of compressed clumps */ 318368c31abSDavid du Colombier u64int used; 319368c31abSDavid du Colombier u64int uncsize; 320368c31abSDavid du Colombier u8int sealed; 321368c31abSDavid du Colombier }; 322368c31abSDavid du Colombier 323368c31abSDavid du Colombier /* 324368c31abSDavid du Colombier * Arena state - represents a point in the data log 325368c31abSDavid du Colombier */ 326368c31abSDavid du Colombier struct AState 327368c31abSDavid du Colombier { 328368c31abSDavid du Colombier Arena *arena; 329368c31abSDavid du Colombier u64int aa; /* index address */ 330368c31abSDavid du Colombier ATailStats stats; 331368c31abSDavid du Colombier }; 332368c31abSDavid du Colombier 333368c31abSDavid du Colombier /* 334368c31abSDavid du Colombier * an Arena is a log of Clumps, preceeded by an ArenaHeader, 335368c31abSDavid du Colombier * and followed by a Arena, each in one disk block. 336368c31abSDavid du Colombier * struct on disk is not always up to date, but should be self-consistent. 337368c31abSDavid du Colombier * to sync after reboot, follow clumps starting at used until ClumpFreeMagic if found. 338368c31abSDavid du Colombier * <struct name="Arena" type="Arena *"> 339368c31abSDavid du Colombier * <field name="name" val="s->name" type="AName"/> 340368c31abSDavid du Colombier * <field name="version" val="s->version" type="U32int"/> 341368c31abSDavid du Colombier * <field name="partition" val="s->part->name" type="AName"/> 342368c31abSDavid du Colombier * <field name="blocksize" val="s->blocksize" type="U32int"/> 343368c31abSDavid du Colombier * <field name="start" val="s->base" type="U64int"/> 344368c31abSDavid du Colombier * <field name="stop" val="s->base+2*s->blocksize" type="U64int"/> 345368c31abSDavid du Colombier * <field name="created" val="s->ctime" type="U32int"/> 346368c31abSDavid du Colombier * <field name="modified" val="s->wtime" type="U32int"/> 347368c31abSDavid du Colombier * <field name="sealed" val="s->sealed" type="Sealed"/> 348368c31abSDavid du Colombier * <field name="score" val="s->score" type="Score"/> 349368c31abSDavid du Colombier * <field name="clumps" val="s->clumps" type="U32int"/> 350368c31abSDavid du Colombier * <field name="compressedclumps" val="s->cclumps" type="U32int"/> 351368c31abSDavid du Colombier * <field name="data" val="s->uncsize" type="U64int"/> 352368c31abSDavid du Colombier * <field name="compresseddata" val="s->used - s->clumps * ClumpSize" type="U64int"/> 353368c31abSDavid du Colombier * <field name="storage" val="s->used + s->clumps * ClumpInfoSize" type="U64int"/> 354368c31abSDavid du Colombier * </struct> 355368c31abSDavid du Colombier */ 356368c31abSDavid du Colombier struct Arena 357368c31abSDavid du Colombier { 358368c31abSDavid du Colombier QLock lock; /* lock for arena fields, writing to disk */ 359368c31abSDavid du Colombier Part *part; /* partition in which arena lives */ 360368c31abSDavid du Colombier int blocksize; /* size of block to read or write */ 361368c31abSDavid du Colombier u64int base; /* base address on disk */ 362368c31abSDavid du Colombier u64int size; /* total space in the arena */ 363368c31abSDavid du Colombier u8int score[VtScoreSize]; /* score of the entire sealed & summed arena */ 364368c31abSDavid du Colombier 365368c31abSDavid du Colombier int clumpmax; /* ClumpInfos per block */ 366368c31abSDavid du Colombier AState mem; 367368c31abSDavid du Colombier int inqueue; 368368c31abSDavid du Colombier 369368c31abSDavid du Colombier /* 370368c31abSDavid du Colombier * fields stored on disk 371368c31abSDavid du Colombier */ 372368c31abSDavid du Colombier u32int version; 373368c31abSDavid du Colombier char name[ANameSize]; /* text label */ 374368c31abSDavid du Colombier ATailStats memstats; 375368c31abSDavid du Colombier ATailStats diskstats; 376368c31abSDavid du Colombier u32int ctime; /* first time a block was written */ 377368c31abSDavid du Colombier u32int wtime; /* last time a block was written */ 378368c31abSDavid du Colombier u32int clumpmagic; 379f9e1cf08SDavid du Colombier 380f9e1cf08SDavid du Colombier ArenaCIG *cig; 381f9e1cf08SDavid du Colombier int ncig; 382f9e1cf08SDavid du Colombier }; 383f9e1cf08SDavid du Colombier 384f9e1cf08SDavid du Colombier struct ArenaCIG 385f9e1cf08SDavid du Colombier { 386f9e1cf08SDavid du Colombier u64int offset; // from arena base 387368c31abSDavid du Colombier }; 388368c31abSDavid du Colombier 389368c31abSDavid du Colombier /* 390368c31abSDavid du Colombier * redundant storage of some fields at the beginning of each arena 391368c31abSDavid du Colombier */ 392368c31abSDavid du Colombier struct ArenaHead 393368c31abSDavid du Colombier { 394368c31abSDavid du Colombier u32int version; 395368c31abSDavid du Colombier char name[ANameSize]; 396368c31abSDavid du Colombier u32int blocksize; 397368c31abSDavid du Colombier u64int size; 398368c31abSDavid du Colombier u32int clumpmagic; 399368c31abSDavid du Colombier }; 400368c31abSDavid du Colombier 401368c31abSDavid du Colombier /* 402368c31abSDavid du Colombier * most interesting meta information for a clump. 403368c31abSDavid du Colombier * stored in each clump's header and in the Arena's directory, 404368c31abSDavid du Colombier * stored in reverse order just prior to the arena trailer 405368c31abSDavid du Colombier */ 406368c31abSDavid du Colombier struct ClumpInfo 407368c31abSDavid du Colombier { 408368c31abSDavid du Colombier u8int type; 409368c31abSDavid du Colombier u16int size; /* size of disk data, not including header */ 410368c31abSDavid du Colombier u16int uncsize; /* size of uncompressed data */ 411368c31abSDavid du Colombier u8int score[VtScoreSize]; /* score of the uncompressed data only */ 412368c31abSDavid du Colombier }; 413368c31abSDavid du Colombier 414368c31abSDavid du Colombier /* 415368c31abSDavid du Colombier * header for an immutable clump of data 416368c31abSDavid du Colombier */ 417368c31abSDavid du Colombier struct Clump 418368c31abSDavid du Colombier { 419368c31abSDavid du Colombier ClumpInfo info; 420368c31abSDavid du Colombier u8int encoding; 421368c31abSDavid du Colombier u32int creator; /* initial client which wrote the block */ 422368c31abSDavid du Colombier u32int time; /* creation at gmt seconds since 1/1/1970 */ 423368c31abSDavid du Colombier }; 424368c31abSDavid du Colombier 425368c31abSDavid du Colombier /* 426368c31abSDavid du Colombier * index of all clumps according to their score 427368c31abSDavid du Colombier * this is just a wrapper to tie together the index sections 428368c31abSDavid du Colombier * <struct name="Index" type="Index *"> 429368c31abSDavid du Colombier * <field name="name" val="s->name" type="AName"/> 430368c31abSDavid du Colombier * <field name="version" val="s->version" type="U32int"/> 431368c31abSDavid du Colombier * <field name="blocksize" val="s->blocksize" type="U32int"/> 432368c31abSDavid du Colombier * <field name="tabsize" val="s->tabsize" type="U32int"/> 433368c31abSDavid du Colombier * <field name="buckets" val="s->buckets" type="U32int"/> 434368c31abSDavid du Colombier * <field name="buckdiv" val="s->div" type="U32int"/> 435368c31abSDavid du Colombier * <field name="bitblocks" val="s->div" type="U32int"/> 436368c31abSDavid du Colombier * <field name="maxdepth" val="s->div" type="U32int"/> 437368c31abSDavid du Colombier * <field name="bitkeylog" val="s->div" type="U32int"/> 438368c31abSDavid du Colombier * <field name="bitkeymask" val="s->div" type="U32int"/> 439368c31abSDavid du Colombier * <array name="sect" val="&s->smap[i]" elems="s->nsects" type="Amap"/> 440368c31abSDavid du Colombier * <array name="amap" val="&s->amap[i]" elems="s->narenas" type="Amap"/> 441368c31abSDavid du Colombier * <array name="arena" val="s->arenas[i]" elems="s->narenas" type="Arena"/> 442368c31abSDavid du Colombier * </struct> 443368c31abSDavid du Colombier * <struct name="Amap" type="AMap *"> 444368c31abSDavid du Colombier * <field name="name" val="s->name" type="AName"/> 445368c31abSDavid du Colombier * <field name="start" val="s->start" type="U64int"/> 446368c31abSDavid du Colombier * <field name="stop" val="s->stop" type="U64int"/> 447368c31abSDavid du Colombier * </struct> 448368c31abSDavid du Colombier */ 449368c31abSDavid du Colombier struct Index 450368c31abSDavid du Colombier { 451368c31abSDavid du Colombier u32int div; /* divisor for mapping score to bucket */ 452368c31abSDavid du Colombier u32int buckets; /* last bucket used in disk hash table */ 453368c31abSDavid du Colombier u32int blocksize; 454368c31abSDavid du Colombier u32int tabsize; /* max. bytes in index config */ 455368c31abSDavid du Colombier 456368c31abSDavid du Colombier int mapalloc; /* first arena to check when adding a lump */ 457368c31abSDavid du Colombier Arena **arenas; /* arenas in the mapping */ 458368c31abSDavid du Colombier ISect **sects; /* sections which hold the buckets */ 459368c31abSDavid du Colombier Bloom *bloom; /* bloom filter */ 460368c31abSDavid du Colombier 461368c31abSDavid du Colombier /* 462368c31abSDavid du Colombier * fields stored in config file 463368c31abSDavid du Colombier */ 464368c31abSDavid du Colombier u32int version; 465368c31abSDavid du Colombier char name[ANameSize]; /* text label */ 466368c31abSDavid du Colombier int nsects; 467368c31abSDavid du Colombier AMap *smap; /* mapping of buckets to index sections */ 468368c31abSDavid du Colombier int narenas; 469368c31abSDavid du Colombier AMap *amap; /* mapping from index addesses to arenas */ 470f9e1cf08SDavid du Colombier 471f9e1cf08SDavid du Colombier QLock writing; 472368c31abSDavid du Colombier }; 473368c31abSDavid du Colombier 474368c31abSDavid du Colombier /* 475368c31abSDavid du Colombier * one part of the bucket storage for an index. 476368c31abSDavid du Colombier * the index blocks are sequentially allocated 477368c31abSDavid du Colombier * across all of the sections. 478368c31abSDavid du Colombier */ 479368c31abSDavid du Colombier struct ISect 480368c31abSDavid du Colombier { 481368c31abSDavid du Colombier Part *part; 482368c31abSDavid du Colombier int blocklog; /* log2(blocksize) */ 483368c31abSDavid du Colombier int buckmax; /* max. entries in a index bucket */ 484368c31abSDavid du Colombier u32int tabbase; /* base address of index config table on disk */ 485368c31abSDavid du Colombier u32int tabsize; /* max. bytes in index config */ 486368c31abSDavid du Colombier Channel *writechan; 487368c31abSDavid du Colombier Channel *writedonechan; 488368c31abSDavid du Colombier void *ig; /* used by buildindex only */ 489368c31abSDavid du Colombier int ng; 490368c31abSDavid du Colombier 491368c31abSDavid du Colombier /* 492368c31abSDavid du Colombier * fields stored on disk 493368c31abSDavid du Colombier */ 494368c31abSDavid du Colombier u32int version; 495368c31abSDavid du Colombier u32int bucketmagic; 496368c31abSDavid du Colombier char name[ANameSize]; /* text label */ 497368c31abSDavid du Colombier char index[ANameSize]; /* index owning the section */ 498368c31abSDavid du Colombier u32int blocksize; /* size of hash buckets in index */ 499368c31abSDavid du Colombier u32int blockbase; /* address of start of on disk index table */ 500368c31abSDavid du Colombier u32int blocks; /* total blocks on disk; some may be unused */ 501368c31abSDavid du Colombier u32int start; /* first bucket in this section */ 502368c31abSDavid du Colombier u32int stop; /* limit of buckets in this section */ 503368c31abSDavid du Colombier }; 504368c31abSDavid du Colombier 505368c31abSDavid du Colombier /* 506368c31abSDavid du Colombier * externally interesting part of an IEntry 507368c31abSDavid du Colombier */ 508368c31abSDavid du Colombier struct IAddr 509368c31abSDavid du Colombier { 510368c31abSDavid du Colombier u64int addr; 511368c31abSDavid du Colombier u16int size; /* uncompressed size */ 512368c31abSDavid du Colombier u8int type; /* type of block */ 513368c31abSDavid du Colombier u8int blocks; /* arena io quanta for Clump + data */ 514368c31abSDavid du Colombier }; 515368c31abSDavid du Colombier 516368c31abSDavid du Colombier /* 517368c31abSDavid du Colombier * entries in the index 518368c31abSDavid du Colombier * kept in IBuckets in the disk index table, 519368c31abSDavid du Colombier * cached in the memory ICache. 520368c31abSDavid du Colombier */ 521368c31abSDavid du Colombier struct IEntry 522368c31abSDavid du Colombier { 523f9e1cf08SDavid du Colombier /* on disk data - 32 bytes*/ 524368c31abSDavid du Colombier u8int score[VtScoreSize]; 525368c31abSDavid du Colombier IAddr ia; 526f9e1cf08SDavid du Colombier 527f9e1cf08SDavid du Colombier IEntry *nexthash; 528f9e1cf08SDavid du Colombier IEntry *nextdirty; 529f9e1cf08SDavid du Colombier IEntry *next; 530f9e1cf08SDavid du Colombier IEntry *prev; 531f9e1cf08SDavid du Colombier u8int state; 532f9e1cf08SDavid du Colombier }; 533f9e1cf08SDavid du Colombier enum { 534f9e1cf08SDavid du Colombier IEClean = 0, 535f9e1cf08SDavid du Colombier IEDirty = 1, 536f9e1cf08SDavid du Colombier IESummary = 2, 537368c31abSDavid du Colombier }; 538368c31abSDavid du Colombier 539368c31abSDavid du Colombier /* 540368c31abSDavid du Colombier * buckets in the on disk index table 541368c31abSDavid du Colombier */ 542368c31abSDavid du Colombier struct IBucket 543368c31abSDavid du Colombier { 544368c31abSDavid du Colombier u16int n; /* number of active indices */ 545368c31abSDavid du Colombier u32int buck; /* used by buildindex/checkindex only */ 546368c31abSDavid du Colombier u8int *data; 547368c31abSDavid du Colombier }; 548368c31abSDavid du Colombier 549368c31abSDavid du Colombier /* 550368c31abSDavid du Colombier * temporary buffers used by individual threads 551368c31abSDavid du Colombier */ 552368c31abSDavid du Colombier struct ZBlock 553368c31abSDavid du Colombier { 554368c31abSDavid du Colombier u32int len; 555368c31abSDavid du Colombier u32int _size; 556368c31abSDavid du Colombier u8int *data; 557368c31abSDavid du Colombier u8int *free; 558368c31abSDavid du Colombier }; 559368c31abSDavid du Colombier 560368c31abSDavid du Colombier /* 561368c31abSDavid du Colombier * simple input buffer for a '\0' terminated text file 562368c31abSDavid du Colombier */ 563368c31abSDavid du Colombier struct IFile 564368c31abSDavid du Colombier { 565368c31abSDavid du Colombier char *name; /* name of the file */ 566368c31abSDavid du Colombier ZBlock *b; /* entire contents of file */ 567368c31abSDavid du Colombier u32int pos; /* current position in the file */ 568368c31abSDavid du Colombier }; 569368c31abSDavid du Colombier 570368c31abSDavid du Colombier struct Statdesc 571368c31abSDavid du Colombier { 572368c31abSDavid du Colombier char *name; 573368c31abSDavid du Colombier ulong max; 574368c31abSDavid du Colombier }; 575368c31abSDavid du Colombier 576368c31abSDavid du Colombier /* keep in sync with stats.c:/statdesc and httpd.c:/graphname*/ 577368c31abSDavid du Colombier enum 578368c31abSDavid du Colombier { 579368c31abSDavid du Colombier StatRpcTotal, 580368c31abSDavid du Colombier StatRpcRead, 581368c31abSDavid du Colombier StatRpcReadOk, 582368c31abSDavid du Colombier StatRpcReadFail, 583368c31abSDavid du Colombier StatRpcReadBytes, 584368c31abSDavid du Colombier StatRpcReadTime, 585368c31abSDavid du Colombier StatRpcReadCached, 586368c31abSDavid du Colombier StatRpcReadCachedTime, 587368c31abSDavid du Colombier StatRpcReadUncached, 588368c31abSDavid du Colombier StatRpcReadUncachedTime, 589368c31abSDavid du Colombier StatRpcWrite, 590368c31abSDavid du Colombier StatRpcWriteNew, 591368c31abSDavid du Colombier StatRpcWriteOld, 592368c31abSDavid du Colombier StatRpcWriteFail, 593368c31abSDavid du Colombier StatRpcWriteBytes, 594368c31abSDavid du Colombier StatRpcWriteTime, 595368c31abSDavid du Colombier StatRpcWriteNewTime, 596368c31abSDavid du Colombier StatRpcWriteOldTime, 597368c31abSDavid du Colombier 598368c31abSDavid du Colombier StatLcacheHit, 599368c31abSDavid du Colombier StatLcacheMiss, 600368c31abSDavid du Colombier StatLcacheRead, 601368c31abSDavid du Colombier StatLcacheWrite, 602368c31abSDavid du Colombier StatLcacheSize, 603368c31abSDavid du Colombier StatLcacheStall, 604368c31abSDavid du Colombier StatLcacheReadTime, 605368c31abSDavid du Colombier 606368c31abSDavid du Colombier StatDcacheHit, 607368c31abSDavid du Colombier StatDcacheMiss, 608368c31abSDavid du Colombier StatDcacheLookup, 609368c31abSDavid du Colombier StatDcacheRead, 610368c31abSDavid du Colombier StatDcacheWrite, 611368c31abSDavid du Colombier StatDcacheDirty, 612368c31abSDavid du Colombier StatDcacheSize, 613368c31abSDavid du Colombier StatDcacheFlush, 614368c31abSDavid du Colombier StatDcacheStall, 615368c31abSDavid du Colombier StatDcacheLookupTime, 616368c31abSDavid du Colombier 617368c31abSDavid du Colombier StatDblockStall, 618368c31abSDavid du Colombier StatLumpStall, 619368c31abSDavid du Colombier 620368c31abSDavid du Colombier StatIcacheHit, 621368c31abSDavid du Colombier StatIcacheMiss, 622368c31abSDavid du Colombier StatIcacheRead, 623368c31abSDavid du Colombier StatIcacheWrite, 624368c31abSDavid du Colombier StatIcacheFill, 625368c31abSDavid du Colombier StatIcachePrefetch, 626368c31abSDavid du Colombier StatIcacheDirty, 627368c31abSDavid du Colombier StatIcacheSize, 628368c31abSDavid du Colombier StatIcacheFlush, 629368c31abSDavid du Colombier StatIcacheStall, 630368c31abSDavid du Colombier StatIcacheReadTime, 631f9e1cf08SDavid du Colombier StatIcacheLookup, 632f9e1cf08SDavid du Colombier StatScacheHit, 633f9e1cf08SDavid du Colombier StatScachePrefetch, 634368c31abSDavid du Colombier 635368c31abSDavid du Colombier StatBloomHit, 636368c31abSDavid du Colombier StatBloomMiss, 637368c31abSDavid du Colombier StatBloomFalseMiss, 638368c31abSDavid du Colombier StatBloomLookup, 639368c31abSDavid du Colombier StatBloomOnes, 640368c31abSDavid du Colombier StatBloomBits, 641368c31abSDavid du Colombier 642368c31abSDavid du Colombier StatApartRead, 643368c31abSDavid du Colombier StatApartReadBytes, 644368c31abSDavid du Colombier StatApartWrite, 645368c31abSDavid du Colombier StatApartWriteBytes, 646368c31abSDavid du Colombier 647368c31abSDavid du Colombier StatIsectRead, 648368c31abSDavid du Colombier StatIsectReadBytes, 649368c31abSDavid du Colombier StatIsectWrite, 650368c31abSDavid du Colombier StatIsectWriteBytes, 651368c31abSDavid du Colombier 652368c31abSDavid du Colombier StatSumRead, 653368c31abSDavid du Colombier StatSumReadBytes, 654368c31abSDavid du Colombier 655f9e1cf08SDavid du Colombier StatCigLoad, 656f9e1cf08SDavid du Colombier StatCigLoadTime, 657f9e1cf08SDavid du Colombier 658368c31abSDavid du Colombier NStat 659368c31abSDavid du Colombier }; 660368c31abSDavid du Colombier 661368c31abSDavid du Colombier extern Statdesc statdesc[NStat]; 662368c31abSDavid du Colombier 663368c31abSDavid du Colombier /* 664368c31abSDavid du Colombier * statistics about the operation of the server 665368c31abSDavid du Colombier * mainly for performance monitoring and profiling. 666368c31abSDavid du Colombier */ 667368c31abSDavid du Colombier struct Stats 668368c31abSDavid du Colombier { 669368c31abSDavid du Colombier ulong now; 670368c31abSDavid du Colombier ulong n[NStat]; 671368c31abSDavid du Colombier }; 672368c31abSDavid du Colombier 673368c31abSDavid du Colombier struct Statbin 674368c31abSDavid du Colombier { 675368c31abSDavid du Colombier uint nsamp; 676368c31abSDavid du Colombier uint min; 677368c31abSDavid du Colombier uint max; 678368c31abSDavid du Colombier uint avg; 679368c31abSDavid du Colombier }; 680368c31abSDavid du Colombier 681368c31abSDavid du Colombier struct Graph 682368c31abSDavid du Colombier { 683368c31abSDavid du Colombier long (*fn)(Stats*, Stats*, void*); 684368c31abSDavid du Colombier void *arg; 685368c31abSDavid du Colombier long t0; 686368c31abSDavid du Colombier long t1; 687368c31abSDavid du Colombier long min; 688368c31abSDavid du Colombier long max; 689368c31abSDavid du Colombier long wid; 690368c31abSDavid du Colombier long ht; 691368c31abSDavid du Colombier int fill; 692368c31abSDavid du Colombier }; 693368c31abSDavid du Colombier 694368c31abSDavid du Colombier /* 695368c31abSDavid du Colombier * for kicking background processes that run one round after another after another 696368c31abSDavid du Colombier */ 697368c31abSDavid du Colombier struct Round 698368c31abSDavid du Colombier { 699368c31abSDavid du Colombier QLock lock; 700368c31abSDavid du Colombier Rendez start; 701368c31abSDavid du Colombier Rendez finish; 702368c31abSDavid du Colombier Rendez delaywait; 703368c31abSDavid du Colombier int delaytime; 704368c31abSDavid du Colombier int delaykick; 705368c31abSDavid du Colombier char* name; 706368c31abSDavid du Colombier int last; 707368c31abSDavid du Colombier int current; 708368c31abSDavid du Colombier int next; 709368c31abSDavid du Colombier int doanother; 710368c31abSDavid du Colombier }; 711368c31abSDavid du Colombier 712368c31abSDavid du Colombier /* 713368c31abSDavid du Colombier * Bloom filter of stored block hashes 714368c31abSDavid du Colombier */ 715368c31abSDavid du Colombier struct Bloom 716368c31abSDavid du Colombier { 717368c31abSDavid du Colombier RWLock lk; /* protects nhash, nbits, tab, mb */ 718368c31abSDavid du Colombier QLock mod; /* one marker at a time, protects nb */ 719368c31abSDavid du Colombier int nhash; 720368c31abSDavid du Colombier ulong size; /* bytes in tab */ 721368c31abSDavid du Colombier ulong bitmask; /* to produce bit index */ 722368c31abSDavid du Colombier u8int *data; 723368c31abSDavid du Colombier Part *part; 724368c31abSDavid du Colombier Channel *writechan; 725368c31abSDavid du Colombier Channel *writedonechan; 726368c31abSDavid du Colombier }; 727368c31abSDavid du Colombier 728368c31abSDavid du Colombier extern Index *mainindex; 729368c31abSDavid du Colombier extern u32int maxblocksize; /* max. block size used by any partition */ 730368c31abSDavid du Colombier extern int paranoid; /* should verify hashes on disk read */ 731368c31abSDavid du Colombier extern int queuewrites; /* put all lump writes on a queue and finish later */ 732368c31abSDavid du Colombier extern int readonly; /* only allowed to read the disk data */ 733368c31abSDavid du Colombier extern Stats stats; 734368c31abSDavid du Colombier extern u8int zeroscore[VtScoreSize]; 735368c31abSDavid du Colombier extern int compressblocks; 736368c31abSDavid du Colombier extern int writestodevnull; /* dangerous - for performance debugging */ 737368c31abSDavid du Colombier extern int collectstats; 738368c31abSDavid du Colombier extern QLock memdrawlock; 739368c31abSDavid du Colombier extern int icachesleeptime; 740368c31abSDavid du Colombier extern int minicachesleeptime; 741368c31abSDavid du Colombier extern int arenasumsleeptime; 742368c31abSDavid du Colombier extern int manualscheduling; 743368c31abSDavid du Colombier extern int l0quantum; 744368c31abSDavid du Colombier extern int l1quantum; 745368c31abSDavid du Colombier extern int ignorebloom; 746368c31abSDavid du Colombier extern int icacheprefetch; 747368c31abSDavid du Colombier extern int syncwrites; 748b8a11165SDavid du Colombier extern int debugarena; /* print in arena error msgs; -1==unknown */ 749368c31abSDavid du Colombier 750368c31abSDavid du Colombier extern Stats *stathist; 751368c31abSDavid du Colombier extern int nstathist; 752368c31abSDavid du Colombier extern ulong stattime; 753368c31abSDavid du Colombier 754368c31abSDavid du Colombier #ifndef PLAN9PORT 755368c31abSDavid du Colombier #pragma varargck type "V" uchar* 756368c31abSDavid du Colombier #define ODIRECT 0 757368c31abSDavid du Colombier #endif 758f9e1cf08SDavid du Colombier 759