| typedef struct Config		Config; | 
 | typedef struct AMap		AMap; | 
 | typedef struct AMapN		AMapN; | 
 | typedef struct Arena		Arena; | 
 | typedef struct AState	AState; | 
 | typedef struct ArenaCIG	ArenaCIG; | 
 | typedef struct ArenaHead	ArenaHead; | 
 | typedef struct ArenaPart	ArenaPart; | 
 | typedef struct ArenaTail	ArenaTail; | 
 | typedef struct ATailStats	ATailStats; | 
 | typedef struct CIBlock		CIBlock; | 
 | typedef struct Clump		Clump; | 
 | typedef struct ClumpInfo	ClumpInfo; | 
 | typedef struct Graph Graph; | 
 | typedef struct IAddr		IAddr; | 
 | typedef struct IBucket		IBucket; | 
 | typedef struct IEStream		IEStream; | 
 | typedef struct IEntry		IEntry; | 
 | typedef struct IFile		IFile; | 
 | typedef struct ISect		ISect; | 
 | typedef struct Index		Index; | 
 | typedef struct Lump		Lump; | 
 | typedef struct DBlock		DBlock; | 
 | typedef struct Part		Part; | 
 | typedef struct Statbin Statbin; | 
 | typedef struct Statdesc	Statdesc; | 
 | typedef struct Stats		Stats; | 
 | typedef struct ZBlock		ZBlock; | 
 | typedef struct Round	Round; | 
 | typedef struct Bloom	Bloom; | 
 |  | 
 | #pragma incomplete IEStream | 
 |  | 
 | #define	TWID32	((u32int)~(u32int)0) | 
 | #define	TWID64	((u64int)~(u64int)0) | 
 | #define	TWID8	((u8int)~(u8int)0) | 
 |  | 
 | enum | 
 | { | 
 | 	/* | 
 | 	 * formerly fundamental constant, | 
 | 	 * now a server-imposed limitation. | 
 | 	 */ | 
 | 	VtMaxLumpSize	= 56*1024, | 
 |  | 
 | 	ABlockLog		= 9,		/* log2(512), the quantum for reading arenas */ | 
 | 	ANameSize		= 64, | 
 | 	MaxDiskBlock		= 64*1024,	/* max. allowed size for a disk block */ | 
 | 	MaxIoSize		= 64*1024,	/* max. allowed size for a disk io operation */ | 
 | 	PartBlank		= 256*1024,	/* untouched section at beginning of partition */ | 
 | 	HeadSize		= 512,		/* size of a header after PartBlank */ | 
 | 	MinArenaSize		= 1*1024*1024,	/* smallest reasonable arena size */ | 
 | 	IndexBase		= 1024*1024,	/* initial address to use in an index */ | 
 | 	MaxIo			= 64*1024,	/* max size of a single read or write operation */ | 
 | 	ICacheBits		= 16,		/* default bits for indexing icache */ | 
 | 	MaxAMap			= 31*1024,	/* max. allowed arenas in an address mapping; must be < 32*1024 */ | 
 | 	Unspecified		= TWID32, | 
 |  | 
 | 	/* | 
 | 	 * return codes from syncarena | 
 | 	 */ | 
 | 	SyncDataErr	= 1 << 0,		/* problem reading the clump data */ | 
 | 	SyncCIErr	= 1 << 1,		/* found erroneous clump directory entries */ | 
 | 	SyncCIZero	= 1 << 2,		/* found unwritten clump directory entries */ | 
 | 	SyncFixErr	= 1 << 3,		/* error writing fixed data */ | 
 | 	SyncHeader	= 1 << 4,		/* altered header fields */ | 
 |  | 
 | 	/* | 
 | 	 * error severity | 
 | 	 */ | 
 | 	EOk			= 0,		/* error expected in normal operation */ | 
 | 	EStrange,				/* strange error that should be logged */ | 
 | 	ECorrupt,				/* corrupted data found in arenas */ | 
 | 	EICorrupt,				/* corrupted data found in index */ | 
 | 	EAdmin,					/* should be brought to administrators' attention */ | 
 | 	ECrash,					/* really bad internal error */ | 
 | 	EBug,					/* a limitation which should be fixed */ | 
 | 	EInconsist,				/* inconsistencies between index and arena */ | 
 | 	EMax, | 
 |  | 
 | 	/* | 
 | 	 * internal disk formats for the venti archival storage system | 
 | 	 */ | 
 | 	/* | 
 | 	 * magic numbers on disk | 
 | 	 */ | 
 | 	_ClumpMagic		= 0xd15cb10cU,	/* clump header, deprecated */ | 
 | 	ClumpFreeMagic		= 0,		/* free clump; terminates active clump log */ | 
 |  | 
 | 	ArenaPartMagic		= 0xa9e4a5e7U,	/* arena partition header */ | 
 | 	ArenaMagic		= 0xf2a14eadU,	/* arena trailer */ | 
 | 	ArenaHeadMagic		= 0xd15c4eadU,	/* arena header */ | 
 | 	 | 
 | 	BloomMagic		= 0xb1004eadU,	/* bloom filter header */ | 
 | 	BloomMaxHash	= 32, | 
 |  | 
 | 	ISectMagic		= 0xd15c5ec7U,	/* index header */ | 
 |  | 
 | 	ArenaPartVersion	= 3, | 
 | 	ArenaVersion4		= 4, | 
 | 	ArenaVersion5		= 5, | 
 | 	BloomVersion		= 1, | 
 | 	IndexVersion		= 1, | 
 | 	ISectVersion1		= 1, | 
 | 	ISectVersion2		= 2, | 
 |  | 
 | 	/* | 
 | 	 * encodings of clumps on disk | 
 | 	 */ | 
 | 	ClumpEErr		= 0,		/* can't happen */ | 
 | 	ClumpENone,				/* plain */ | 
 | 	ClumpECompress,				/* compressed */ | 
 | 	ClumpEMax, | 
 |  | 
 | 	/* | 
 | 	 * sizes in bytes on disk | 
 | 	 */ | 
 | 	U8Size			= 1, | 
 | 	U16Size			= 2, | 
 | 	U32Size			= 4, | 
 | 	U64Size			= 8, | 
 |  | 
 | 	ArenaPartSize		= 4 * U32Size, | 
 | 	ArenaSize4		= 2 * U64Size + 6 * U32Size + ANameSize + U8Size, | 
 | 	ArenaSize5			= ArenaSize4 + U32Size, | 
 | 	ArenaSize5a		= ArenaSize5 + 2 * U8Size + 2 * U32Size + 2 * U64Size, | 
 | 	ArenaHeadSize4		= U64Size + 3 * U32Size + ANameSize, | 
 | 	ArenaHeadSize5		= ArenaHeadSize4 + U32Size, | 
 | 	BloomHeadSize	= 4 * U32Size, | 
 | 	ISectSize1		= 7 * U32Size + 2 * ANameSize, | 
 | 	ISectSize2		= ISectSize1 + U32Size, | 
 | 	ClumpInfoSize		= U8Size + 2 * U16Size + VtScoreSize, | 
 | 	ClumpSize		= ClumpInfoSize + U8Size + 3 * U32Size, | 
 | 	MaxBloomSize		= 1<<(32-3),	/* 2^32 bits */ | 
 | 	MaxBloomHash	= 32,		/* bits per score */ | 
 | 	/* | 
 | 	 * BUG - The various block copies that manipulate entry buckets | 
 | 	 * would be faster if we bumped IBucketSize up to 8 and IEntrySize up to 40, | 
 | 	 * so that everything is word-aligned.  Buildindex is actually cpu-bound | 
 | 	 * by the (byte at a time) copying in qsort. | 
 | 	 */ | 
 | 	IBucketSize		= U32Size + U16Size, | 
 | 	IEntrySize		= U64Size + U32Size + 2*U16Size + 2*U8Size + VtScoreSize, | 
 | 	IEntryTypeOff		= VtScoreSize + U32Size + U16Size + U64Size + U16Size, | 
 | 	IEntryAddrOff		= VtScoreSize + U32Size + U16Size, | 
 |  | 
 | 	MaxClumpBlocks		=  (VtMaxLumpSize + ClumpSize + (1 << ABlockLog) - 1) >> ABlockLog, | 
 | 	 | 
 | 	IcacheFrac		= 1000000,	/* denominator */ | 
 |  | 
 | 	SleepForever		= 1000000000,	/* magic value for sleep time */ | 
 | 	/* | 
 | 	 * dirty flags - order controls disk write order | 
 | 	 */ | 
 | 	DirtyArena		= 1, | 
 | 	DirtyArenaCib, | 
 | 	DirtyArenaTrailer, | 
 | 	DirtyMax, | 
 | 	 | 
 | 	ArenaCIGSize = 10*1024,	// about 0.5 MB worth of IEntry. | 
 |  | 
 | 	VentiZZZZZZZZ | 
 | }; | 
 |  | 
 | extern char TraceDisk[]; | 
 | extern char TraceLump[]; | 
 | extern char TraceBlock[]; | 
 | extern char TraceProc[]; | 
 | extern char TraceWork[]; | 
 | extern char TraceQuiet[]; | 
 | extern char TraceRpc[]; | 
 |  | 
 | /* | 
 |  * results of parsing and initializing a config file | 
 |  */ | 
 | struct Config | 
 | { | 
 | 	char		*index;			/* name of the index to initialize */ | 
 | 	int		naparts;		/* arena partitions initialized */ | 
 | 	ArenaPart	**aparts; | 
 | 	int		nsects;			/* index sections initialized */ | 
 | 	ISect		**sects; | 
 | 	Bloom	*bloom;		/* bloom filter */ | 
 | 	u32int	bcmem; | 
 | 	u32int	mem; | 
 | 	u32int	icmem; | 
 | 	int		queuewrites; | 
 | 	char*	haddr; | 
 | 	char*	vaddr; | 
 | 	char*	webroot; | 
 | }; | 
 |  | 
 | /* | 
 |  * a Part is the low level interface to files or disks. | 
 |  * there are two main types of partitions | 
 |  *	arena paritions, which some number of arenas, each in a sub-partition. | 
 |  *	index partition, which only have one subpartition. | 
 |  */ | 
 | struct Part | 
 | { | 
 | 	int		fd;			/* rock for accessing the disk */ | 
 | 	int		mode; | 
 | 	u64int		offset; | 
 | 	u64int		size;			/* size of the partiton */ | 
 | 	u32int		blocksize;		/* block size for reads and writes */ | 
 | 	u32int		fsblocksize;	/* minimum file system block size */ | 
 | 	char		*name; | 
 | 	char		*filename; | 
 | 	Channel		*writechan;		/* chan[dcache.nblock](DBlock*) */ | 
 | }; | 
 |  | 
 | /* | 
 |  * a cached block from the partition | 
 |  * yuck -- most of this is internal structure for the cache | 
 |  * all other routines should only use data | 
 |  */ | 
 | struct DBlock | 
 | { | 
 | 	u8int	*data; | 
 |  | 
 | 	Part	*part;			/* partition in which cached */ | 
 | 	u64int	addr;			/* base address on the partition */ | 
 | 	u32int	size;			/* amount of data available, not amount allocated; should go away */ | 
 | 	u32int	mode; | 
 | 	u32int	dirty; | 
 | 	u32int	dirtying; | 
 | 	DBlock	*next;			/* doubly linked hash chains */ | 
 | 	DBlock	*prev; | 
 | 	u32int	heap;			/* index in heap table */ | 
 | 	u32int	used;			/* last reference times */ | 
 | 	u32int	used2; | 
 | 	u32int	ref;			/* reference count */ | 
 | 	RWLock	lock;			/* for access to data only */ | 
 | 	Channel	*writedonechan;	 | 
 | 	void*	chanbuf[1];		/* buffer for the chan! */ | 
 | }; | 
 |  | 
 | /* | 
 |  * a cached block from the partition | 
 |  * yuck -- most of this is internal structure for the cache | 
 |  * all other routines should only use data | 
 |  * double yuck -- this is mostly the same as a DBlock | 
 |  */ | 
 | struct Lump | 
 | { | 
 | 	Packet	*data; | 
 |  | 
 | 	Part	*part;			/* partition in which cached */ | 
 | 	u8int	score[VtScoreSize];	/* score of packet */ | 
 | 	u8int	type;			/* type of packet */ | 
 | 	u32int	size;			/* amount of data allocated to hold packet */ | 
 | 	Lump	*next;			/* doubly linked hash chains */ | 
 | 	Lump	*prev; | 
 | 	u32int	heap;			/* index in heap table */ | 
 | 	u32int	used;			/* last reference times */ | 
 | 	u32int	used2; | 
 | 	u32int	ref;			/* reference count */ | 
 | 	QLock	lock;			/* for access to data only */ | 
 | }; | 
 |  | 
 | /* | 
 |  * mapping between names and address ranges | 
 |  */ | 
 | struct AMap | 
 | { | 
 | 	u64int		start; | 
 | 	u64int		stop; | 
 | 	char		name[ANameSize]; | 
 | }; | 
 |  | 
 | /* | 
 |  * an AMap along with a length | 
 |  */ | 
 | struct AMapN | 
 | { | 
 | 	int		n; | 
 | 	AMap		*map; | 
 | }; | 
 |  | 
 | /* | 
 |  * an ArenaPart is a partition made up of Arenas | 
 |  * it exists because most os's don't support many partitions, | 
 |  * and we want to have many different Arenas | 
 |  */ | 
 | struct ArenaPart | 
 | { | 
 | 	Part		*part; | 
 | 	u64int		size;			/* size of underlying partition, rounded down to blocks */ | 
 | 	Arena		**arenas; | 
 | 	u32int		tabbase;		/* base address of arena table on disk */ | 
 | 	u32int		tabsize;		/* max. bytes in arena table */ | 
 |  | 
 | 	/* | 
 | 	 * fields stored on disk | 
 | 	 */ | 
 | 	u32int		version; | 
 | 	u32int		blocksize;		/* "optimal" block size for reads and writes */ | 
 | 	u32int		arenabase;		/* base address of first arena */ | 
 |  | 
 | 	/* | 
 | 	 * stored in the arena mapping table on disk | 
 | 	 */ | 
 | 	AMap		*map; | 
 | 	int		narenas; | 
 | }; | 
 |  | 
 | /* | 
 |  * info about one block in the clump info cache | 
 |  */ | 
 | struct CIBlock | 
 | { | 
 | 	u32int		block;			/* blocks in the directory */ | 
 | 	int		offset;			/* offsets of one clump in the data */ | 
 | 	DBlock		*data; | 
 | }; | 
 |  | 
 | /* | 
 |  * Statistics kept in the tail.  | 
 |  */ | 
 | struct ATailStats | 
 | { | 
 | 	u32int		clumps;		/* number of clumps */ | 
 | 	u32int		cclumps;		/* number of compressed clumps */ | 
 | 	u64int		used; | 
 | 	u64int		uncsize; | 
 | 	u8int		sealed; | 
 | }; | 
 |  | 
 | /* | 
 |  * Arena state - represents a point in the data log | 
 |  */ | 
 | struct AState | 
 | { | 
 | 	Arena		*arena; | 
 | 	u64int		aa;			/* index address */ | 
 | 	ATailStats		stats; | 
 | }; | 
 |  | 
 | /* | 
 |  * an Arena is a log of Clumps, preceeded by an ArenaHeader, | 
 |  * and followed by a Arena, each in one disk block. | 
 |  * struct on disk is not always up to date, but should be self-consistent. | 
 |  * to sync after reboot, follow clumps starting at used until ClumpFreeMagic if found. | 
 |  * <struct name="Arena" type="Arena *"> | 
 |  *	<field name="name" val="s->name" type="AName"/> | 
 |  *	<field name="version" val="s->version" type="U32int"/> | 
 |  *	<field name="partition" val="s->part->name" type="AName"/> | 
 |  *	<field name="blocksize" val="s->blocksize" type="U32int"/> | 
 |  *	<field name="start" val="s->base" type="U64int"/> | 
 |  *	<field name="stop" val="s->base+2*s->blocksize" type="U64int"/> | 
 |  *	<field name="created" val="s->ctime" type="U32int"/> | 
 |  *	<field name="modified" val="s->wtime" type="U32int"/> | 
 |  *	<field name="sealed" val="s->sealed" type="Sealed"/> | 
 |  *	<field name="score" val="s->score" type="Score"/> | 
 |  *	<field name="clumps" val="s->clumps" type="U32int"/> | 
 |  *	<field name="compressedclumps" val="s->cclumps" type="U32int"/> | 
 |  *	<field name="data" val="s->uncsize" type="U64int"/> | 
 |  *	<field name="compresseddata" val="s->used - s->clumps * ClumpSize" type="U64int"/> | 
 |  *	<field name="storage" val="s->used + s->clumps * ClumpInfoSize" type="U64int"/> | 
 |  * </struct> | 
 |  */ | 
 | struct Arena | 
 | { | 
 | 	QLock		lock;			/* lock for arena fields, writing to disk */ | 
 | 	Part		*part;			/* partition in which arena lives */ | 
 | 	int		blocksize;		/* size of block to read or write */ | 
 | 	u64int		base;			/* base address on disk */ | 
 | 	u64int		size;			/* total space in the arena */ | 
 | 	u8int		score[VtScoreSize];	/* score of the entire sealed & summed arena */ | 
 |  | 
 | 	int		clumpmax;		/* ClumpInfos per block */ | 
 | 	AState		mem; | 
 | 	int		inqueue; | 
 |  | 
 | 	/* | 
 | 	 * fields stored on disk | 
 | 	 */ | 
 | 	u32int		version; | 
 | 	char		name[ANameSize];	/* text label */ | 
 | 	ATailStats		memstats; | 
 | 	ATailStats		diskstats; | 
 | 	u32int		ctime;			/* first time a block was written */ | 
 | 	u32int		wtime;			/* last time a block was written */ | 
 | 	u32int		clumpmagic; | 
 | 	 | 
 | 	ArenaCIG	*cig; | 
 | 	int	ncig; | 
 | }; | 
 |  | 
 | struct ArenaCIG | 
 | { | 
 | 	u64int	offset;  // from arena base | 
 | }; | 
 |  | 
 | /* | 
 |  * redundant storage of some fields at the beginning of each arena | 
 |  */ | 
 | struct ArenaHead | 
 | { | 
 | 	u32int		version; | 
 | 	char		name[ANameSize]; | 
 | 	u32int		blocksize; | 
 | 	u64int		size; | 
 | 	u32int		clumpmagic; | 
 | }; | 
 |  | 
 | /* | 
 |  * most interesting meta information for a clump. | 
 |  * stored in each clump's header and in the Arena's directory, | 
 |  * stored in reverse order just prior to the arena trailer | 
 |  */ | 
 | struct ClumpInfo | 
 | { | 
 | 	u8int		type; | 
 | 	u16int		size;			/* size of disk data, not including header */ | 
 | 	u16int		uncsize;		/* size of uncompressed data */ | 
 | 	u8int		score[VtScoreSize];	/* score of the uncompressed data only */ | 
 | }; | 
 |  | 
 | /* | 
 |  * header for an immutable clump of data | 
 |  */ | 
 | struct Clump | 
 | { | 
 | 	ClumpInfo	info; | 
 | 	u8int		encoding; | 
 | 	u32int		creator;		/* initial client which wrote the block */ | 
 | 	u32int		time;			/* creation at gmt seconds since 1/1/1970 */ | 
 | }; | 
 |  | 
 | /* | 
 |  * index of all clumps according to their score | 
 |  * this is just a wrapper to tie together the index sections | 
 |  * <struct name="Index" type="Index *"> | 
 |  *	<field name="name" val="s->name" type="AName"/> | 
 |  *	<field name="version" val="s->version" type="U32int"/> | 
 |  *	<field name="blocksize" val="s->blocksize" type="U32int"/> | 
 |  *	<field name="tabsize" val="s->tabsize" type="U32int"/> | 
 |  *	<field name="buckets" val="s->buckets" type="U32int"/> | 
 |  *	<field name="buckdiv" val="s->div" type="U32int"/> | 
 |  *	<field name="bitblocks" val="s->div" type="U32int"/> | 
 |  *	<field name="maxdepth" val="s->div" type="U32int"/> | 
 |  *	<field name="bitkeylog" val="s->div" type="U32int"/> | 
 |  *	<field name="bitkeymask" val="s->div" type="U32int"/> | 
 |  *	<array name="sect" val="&s->smap[i]" elems="s->nsects" type="Amap"/> | 
 |  *	<array name="amap" val="&s->amap[i]" elems="s->narenas" type="Amap"/> | 
 |  *	<array name="arena" val="s->arenas[i]" elems="s->narenas" type="Arena"/> | 
 |  * </struct> | 
 |  * <struct name="Amap" type="AMap *"> | 
 |  *	<field name="name" val="s->name" type="AName"/> | 
 |  *	<field name="start" val="s->start" type="U64int"/> | 
 |  *	<field name="stop" val="s->stop" type="U64int"/> | 
 |  * </struct> | 
 |  */ | 
 | struct Index | 
 | { | 
 | 	u32int		div;			/* divisor for mapping score to bucket */ | 
 | 	u32int		buckets;		/* last bucket used in disk hash table */ | 
 | 	u32int		blocksize; | 
 | 	u32int		tabsize;		/* max. bytes in index config */ | 
 |  | 
 | 	int		mapalloc;		/* first arena to check when adding a lump */ | 
 | 	Arena		**arenas;		/* arenas in the mapping */ | 
 | 	ISect		**sects;		/* sections which hold the buckets */ | 
 | 	Bloom		*bloom;	/* bloom filter */ | 
 |  | 
 | 	/* | 
 | 	 * fields stored in config file  | 
 | 	 */ | 
 | 	u32int		version; | 
 | 	char		name[ANameSize];	/* text label */ | 
 | 	int		nsects; | 
 | 	AMap		*smap;			/* mapping of buckets to index sections */ | 
 | 	int		narenas; | 
 | 	AMap		*amap;			/* mapping from index addesses to arenas */ | 
 | 	 | 
 | 	QLock	writing; | 
 | }; | 
 |  | 
 | /* | 
 |  * one part of the bucket storage for an index. | 
 |  * the index blocks are sequentially allocated | 
 |  * across all of the sections. | 
 |  */ | 
 | struct ISect | 
 | { | 
 | 	Part		*part; | 
 | 	int		blocklog;		/* log2(blocksize) */ | 
 | 	int		buckmax;		/* max. entries in a index bucket */ | 
 | 	u32int		tabbase;		/* base address of index config table on disk */ | 
 | 	u32int		tabsize;		/* max. bytes in index config */ | 
 | 	Channel	*writechan; | 
 | 	Channel	*writedonechan; | 
 | 	void		*ig;		/* used by buildindex only */ | 
 | 	int		ng; | 
 |  | 
 | 	/* | 
 | 	 * fields stored on disk | 
 | 	 */ | 
 | 	u32int		version; | 
 | 	u32int		bucketmagic; | 
 | 	char		name[ANameSize];	/* text label */ | 
 | 	char		index[ANameSize];	/* index owning the section */ | 
 | 	u32int		blocksize;		/* size of hash buckets in index */ | 
 | 	u32int		blockbase;		/* address of start of on disk index table */ | 
 | 	u32int		blocks;			/* total blocks on disk; some may be unused */ | 
 | 	u32int		start;			/* first bucket in this section */ | 
 | 	u32int		stop;			/* limit of buckets in this section */ | 
 | }; | 
 |  | 
 | /* | 
 |  * externally interesting part of an IEntry | 
 |  */ | 
 | struct IAddr | 
 | { | 
 | 	u64int		addr; | 
 | 	u16int		size;			/* uncompressed size */ | 
 | 	u8int		type;			/* type of block */ | 
 | 	u8int		blocks;			/* arena io quanta for Clump + data */ | 
 | }; | 
 |  | 
 | /* | 
 |  * entries in the index | 
 |  * kept in IBuckets in the disk index table, | 
 |  * cached in the memory ICache. | 
 |  */ | 
 | struct IEntry | 
 | { | 
 | 	/* on disk data - 32 bytes*/ | 
 | 	u8int	score[VtScoreSize]; | 
 | 	IAddr	ia; | 
 | 	 | 
 | 	IEntry	*nexthash; | 
 | 	IEntry	*nextdirty; | 
 | 	IEntry	*next; | 
 | 	IEntry	*prev; | 
 | 	u8int	state; | 
 | }; | 
 | enum { | 
 | 	IEClean = 0, | 
 | 	IEDirty = 1, | 
 | 	IESummary = 2, | 
 | }; | 
 |  | 
 | /* | 
 |  * buckets in the on disk index table | 
 |  */ | 
 | struct IBucket | 
 | { | 
 | 	u16int		n;			/* number of active indices */ | 
 | 	u32int		buck;		/* used by buildindex/checkindex only */ | 
 | 	u8int		*data; | 
 | }; | 
 |  | 
 | /* | 
 |  * temporary buffers used by individual threads | 
 |  */ | 
 | struct ZBlock | 
 | { | 
 | 	u32int		len; | 
 | 	u32int		_size; | 
 | 	u8int		*data; | 
 | 	u8int		*free; | 
 | }; | 
 |  | 
 | /* | 
 |  * simple input buffer for a '\0' terminated text file | 
 |  */ | 
 | struct IFile | 
 | { | 
 | 	char		*name;				/* name of the file */ | 
 | 	ZBlock		*b;				/* entire contents of file */ | 
 | 	u32int		pos;				/* current position in the file */ | 
 | }; | 
 |  | 
 | struct Statdesc | 
 | { | 
 | 	char *name; | 
 | 	ulong max; | 
 | }; | 
 |  | 
 | /* keep in sync with stats.c:/statdesc and httpd.c:/graphname*/ | 
 | enum | 
 | { | 
 | 	StatRpcTotal, | 
 | 	StatRpcRead, | 
 | 	StatRpcReadOk, | 
 | 	StatRpcReadFail, | 
 | 	StatRpcReadBytes, | 
 | 	StatRpcReadTime, | 
 | 	StatRpcReadCached, | 
 | 	StatRpcReadCachedTime, | 
 | 	StatRpcReadUncached, | 
 | 	StatRpcReadUncachedTime, | 
 | 	StatRpcWrite, | 
 | 	StatRpcWriteNew, | 
 | 	StatRpcWriteOld, | 
 | 	StatRpcWriteFail, | 
 | 	StatRpcWriteBytes, | 
 | 	StatRpcWriteTime, | 
 | 	StatRpcWriteNewTime, | 
 | 	StatRpcWriteOldTime, | 
 |  | 
 | 	StatLcacheHit, | 
 | 	StatLcacheMiss, | 
 | 	StatLcacheRead, | 
 | 	StatLcacheWrite, | 
 | 	StatLcacheSize, | 
 | 	StatLcacheStall, | 
 | 	StatLcacheReadTime, | 
 |  | 
 | 	StatDcacheHit, | 
 | 	StatDcacheMiss, | 
 | 	StatDcacheLookup, | 
 | 	StatDcacheRead, | 
 | 	StatDcacheWrite, | 
 | 	StatDcacheDirty, | 
 | 	StatDcacheSize, | 
 | 	StatDcacheFlush, | 
 | 	StatDcacheStall, | 
 | 	StatDcacheLookupTime, | 
 |  | 
 | 	StatDblockStall, | 
 | 	StatLumpStall, | 
 |  | 
 | 	StatIcacheHit, | 
 | 	StatIcacheMiss, | 
 | 	StatIcacheRead, | 
 | 	StatIcacheWrite, | 
 | 	StatIcacheFill, | 
 | 	StatIcachePrefetch, | 
 | 	StatIcacheDirty, | 
 | 	StatIcacheSize, | 
 | 	StatIcacheFlush, | 
 | 	StatIcacheStall, | 
 | 	StatIcacheReadTime, | 
 | 	StatIcacheLookup, | 
 | 	StatScacheHit, | 
 | 	StatScachePrefetch, | 
 |  | 
 | 	StatBloomHit, | 
 | 	StatBloomMiss, | 
 | 	StatBloomFalseMiss, | 
 | 	StatBloomLookup, | 
 | 	StatBloomOnes, | 
 | 	StatBloomBits, | 
 |  | 
 | 	StatApartRead, | 
 | 	StatApartReadBytes, | 
 | 	StatApartWrite, | 
 | 	StatApartWriteBytes, | 
 |  | 
 | 	StatIsectRead, | 
 | 	StatIsectReadBytes, | 
 | 	StatIsectWrite, | 
 | 	StatIsectWriteBytes, | 
 |  | 
 | 	StatSumRead, | 
 | 	StatSumReadBytes, | 
 | 	 | 
 | 	StatCigLoad, | 
 | 	StatCigLoadTime, | 
 |  | 
 | 	NStat | 
 | }; | 
 |  | 
 | extern Statdesc statdesc[NStat]; | 
 |  | 
 | /* | 
 |  * statistics about the operation of the server | 
 |  * mainly for performance monitoring and profiling. | 
 |  */ | 
 | struct Stats | 
 | { | 
 | 	ulong		now; | 
 | 	ulong		n[NStat]; | 
 | }; | 
 |  | 
 | struct Statbin | 
 | { | 
 | 	uint nsamp; | 
 | 	uint min; | 
 | 	uint max; | 
 | 	uint avg; | 
 | }; | 
 |  | 
 | struct Graph | 
 | { | 
 | 	long (*fn)(Stats*, Stats*, void*); | 
 | 	void *arg; | 
 | 	long t0; | 
 | 	long t1; | 
 | 	long min; | 
 | 	long max; | 
 | 	long wid; | 
 | 	long ht; | 
 | 	int fill; | 
 | }; | 
 |  | 
 | /* | 
 |  * for kicking background processes that run one round after another after another | 
 |  */ | 
 | struct Round | 
 | { | 
 | 	QLock	lock; | 
 | 	Rendez	start; | 
 | 	Rendez	finish; | 
 | 	Rendez	delaywait; | 
 | 	int		delaytime; | 
 | 	int		delaykick; | 
 | 	char*	name; | 
 | 	int		last; | 
 | 	int		current; | 
 | 	int		next; | 
 | 	int		doanother; | 
 | }; | 
 |  | 
 | /* | 
 |  * Bloom filter of stored block hashes | 
 |  */ | 
 | struct Bloom | 
 | { | 
 | 	RWLock lk;		/* protects nhash, nbits, tab, mb */ | 
 | 	QLock mod;		/* one marker at a time, protects nb */ | 
 | 	int nhash; | 
 | 	ulong size;		/* bytes in tab */ | 
 | 	ulong bitmask;		/* to produce bit index */ | 
 | 	u8int *data; | 
 | 	Part *part; | 
 | 	Channel *writechan; | 
 | 	Channel *writedonechan; | 
 | }; | 
 |  | 
 | extern	Index		*mainindex; | 
 | extern	u32int		maxblocksize;		/* max. block size used by any partition */ | 
 | extern	int		paranoid;		/* should verify hashes on disk read */ | 
 | extern	int		queuewrites;		/* put all lump writes on a queue and finish later */ | 
 | extern	int		readonly;		/* only allowed to read the disk data */ | 
 | extern	Stats		stats; | 
 | extern	u8int		zeroscore[VtScoreSize]; | 
 | extern	int		compressblocks; | 
 | extern	int		writestodevnull;	/* dangerous - for performance debugging */ | 
 | extern	int		bootstrap;		/* writes but does not index - cannot read */ | 
 | extern	int		collectstats; | 
 | extern	QLock	memdrawlock; | 
 | extern	int		icachesleeptime; | 
 | extern	int		minicachesleeptime; | 
 | extern	int		arenasumsleeptime; | 
 | extern	int		manualscheduling; | 
 | extern	int		l0quantum; | 
 | extern	int		l1quantum; | 
 | extern	int		ignorebloom; | 
 | extern	int		icacheprefetch; | 
 | extern	int		syncwrites; | 
 | extern	int		debugarena; /* print in arena error msgs; -1==unknown */ | 
 |  | 
 | extern	Stats	*stathist; | 
 | extern	int	nstathist; | 
 | extern	ulong	stattime; | 
 |  | 
 | #ifndef PLAN9PORT | 
 | #pragma varargck type "V" uchar* | 
 | #define ODIRECT 0 | 
 | #endif | 
 |  |