xref: /plan9/sys/src/cmd/fossil/dat.h (revision 282e677fa45fb578cdb8bc2c412ac084c367776e)
1 typedef struct Arch Arch;
2 typedef struct BList BList;
3 typedef struct Block Block;
4 typedef struct Cache Cache;
5 typedef struct Disk Disk;
6 typedef struct Entry Entry;
7 typedef struct Fsck Fsck;
8 typedef struct Header Header;
9 typedef struct Label Label;
10 typedef struct Periodic Periodic;
11 typedef struct Snap Snap;
12 typedef struct Source Source;
13 typedef struct Super Super;
14 typedef struct WalkPtr WalkPtr;
15 
16 /* tuneable parameters - probably should not be constants */
17 enum {
18 	BytesPerEntry = 100,	/* estimate of bytes per dir entries - determines number of index entries in the block */
19 	FullPercentage = 80,	/* don't allocate in block if more than this percentage full */
20 	FlushSize = 200,	/* number of blocks to flush */
21 	DirtyPercentage = 50,	/* maximum percentage of dirty blocks */
22 };
23 
24 enum {
25 	NilBlock	= (~0UL),
26 	MaxBlock	= (1UL<<31),
27 };
28 
29 enum {
30 	HeaderMagic = 0x3776ae89,
31 	HeaderVersion = 1,
32 	HeaderOffset = 128*1024,
33 	HeaderSize = 512,
34 	SuperMagic = 0x2340a3b1,
35 	SuperSize = 512,
36 	SuperVersion = 1,
37 	LabelSize = 14,
38 };
39 
40 /* well known tags */
41 enum {
42 	BadTag = 0,		/* this tag should not be used */
43 	RootTag = 1,		/* root of fs */
44 	EnumTag,		/* root of a dir listing */
45 	UserTag = 32,		/* all other tags should be >= UserTag */
46 };
47 
48 struct Super {
49 	u16int version;
50 	u32int epochLow;
51 	u32int epochHigh;
52 	u64int qid;			/* next qid */
53 	u32int active;			/* root of active file system */
54 	u32int next;			/* root of next snapshot to archive */
55 	u32int current;			/* root of snapshot currently archiving */
56 	uchar last[VtScoreSize];	/* last snapshot successfully archived */
57 	char name[128];			/* label */
58 };
59 
60 
61 struct Fs {
62 	Arch *arch;		/* immutable */
63 	Cache *cache;		/* immutable */
64 	int mode;		/* immutable */
65 	int blockSize;		/* immutable */
66 	VtSession *z;		/* immutable */
67 	Snap *snap;	/* immutable */
68 
69 	Periodic *metaFlush;	/* periodically flushes meta data cached in files */
70 
71 	/*
72 	 * epoch lock.
73 	 * Most operations on the fs require a read lock of elk, ensuring that
74 	 * the current high and low epochs do not change under foot.
75 	 * This lock is mostly acquired via a call to fileLock or fileRlock.
76 	 * Deletion and creation of snapshots occurs under a write lock of elk,
77 	 * ensuring no file operations are occurring concurrently.
78 	 */
79 	VtLock *elk;		/* epoch lock */
80 	u32int ehi;		/* epoch high */
81 	u32int elo;		/* epoch low */
82 
83 	int halted;		/* epoch lock is held to halt (console initiated) */
84 
85 	Source *source;		/* immutable: root of sources */
86 	File *file;		/* immutable: root of files */
87 };
88 
89 /*
90  * variant on VtEntry
91  * there are extra fields when stored locally
92  */
93 struct Entry {
94 	u32int gen;			/* generation number */
95 	ushort psize;			/* pointer block size */
96 	ushort dsize;			/* data block size */
97 	uchar depth;			/* unpacked from flags */
98 	uchar flags;
99 	uvlong size;
100 	uchar score[VtScoreSize];
101 	u32int tag;			/* tag for local blocks: zero if stored on Venti */
102 	u32int snap;			/* non zero -> entering snapshot of given epoch */
103 	uchar archive;			/* archive this snapshot: only valid for snap != 0 */
104 };
105 
106 struct Source {
107 	Fs *fs;		/* immutable */
108 	int mode;	/* immutable */
109 	u32int gen;	/* immutable */
110 	int dsize;	/* immutable */
111 	int dir;	/* immutable */
112 
113 	Source *parent;	/* immutable */
114 
115 	VtLock *lk;
116 	int ref;
117 	/*
118 	 * epoch for the source
119 	 * for ReadWrite sources, epoch is used to lazily notice
120 	 * sources that must be split from the snapshots.
121 	 * for ReadOnly sources, the epoch represents the minimum epoch
122 	 * along the chain from the root, and is used to lazily notice
123 	 * sources that have become invalid because they belong to an old
124 	 * snapshot.
125 	 */
126 	u32int epoch;
127 	Block *b;			/* block containing this source */
128 	uchar score[VtScoreSize];	/* score of block containing this source */
129 	u32int scoreEpoch;	/* epoch of block containing this source */
130 	int epb;			/* immutable: entries per block in parent */
131 	u32int tag;			/* immutable: tag of parent */
132 	u32int offset; 			/* immutable: entry offset in parent */
133 };
134 
135 
136 struct Header {
137 	ushort version;
138 	ushort blockSize;
139 	ulong super;	/* super blocks */
140 	ulong label;	/* start of labels */
141 	ulong data;	/* end of labels - start of data blocks */
142 	ulong end;	/* end of data blocks */
143 };
144 
145 /*
146  * contains a one block buffer
147  * to avoid problems of the block changing underfoot
148  * and to enable an interface that supports unget.
149  */
150 struct DirEntryEnum {
151 	File *file;
152 
153 	u32int boff; 	/* block offset */
154 
155 	int i, n;
156 	DirEntry *buf;
157 };
158 
159 /* Block states */
160 enum {
161 	BsFree = 0,		/* available for allocation */
162 	BsBad = 0xFF,		/* something is wrong with this block */
163 
164 	/* bit fields */
165 	BsAlloc = 1<<0,	/* block is in use */
166 	BsCopied = 1<<1,	/* block has been copied (usually in preparation for unlink) */
167 	BsVenti = 1<<2,	/* block has been stored on Venti */
168 	BsClosed = 1<<3,	/* block has been unlinked on disk from active file system */
169 	BsMask = BsAlloc|BsCopied|BsVenti|BsClosed,
170 };
171 
172 /*
173  * block types
174  * more regular than Venti block types
175  * bit 3 -> block or data block
176  * bits 2-0 -> level of block
177  */
178 enum {
179 	BtData,
180 	BtDir = 1<<3,
181 	BtLevelMask = 7,
182 	BtMax = 1<<4,
183 };
184 
185 /* io states */
186 enum {
187 	BioEmpty,	/* label & data are not valid */
188 	BioLabel,	/* label is good */
189 	BioClean,	/* data is on the disk */
190 	BioDirty,	/* data is not yet on the disk */
191 	BioReading,	/* in process of reading data */
192 	BioWriting,	/* in process of writing data */
193 	BioReadError,	/* error reading: assume disk always handles write errors */
194 	BioVentiError,	/* error reading from venti (probably disconnected) */
195 	BioMax
196 };
197 
198 struct Label {
199 	uchar type;
200 	uchar state;
201 	u32int tag;
202 	u32int epoch;
203 	u32int epochClose;
204 };
205 
206 struct Block {
207 	Cache *c;
208 	int ref;
209 	int nlock;
210 	ulong	pc;		/* pc that fetched this block from the cache */
211 
212 	VtLock *lk;
213 
214 	int 	part;
215 	u32int	addr;
216 	uchar	score[VtScoreSize];	/* score */
217 	Label l;
218 
219 	uchar	*dmap;
220 
221 	uchar 	*data;
222 
223 	/* the following is private; used by cache */
224 
225 	Block	*next;			/* doubly linked hash chains */
226 	Block	**prev;
227 	u32int	heap;			/* index in heap table */
228 	u32int	used;			/* last reference times */
229 
230 	u32int	vers;			/* version of dirty flag */
231 
232 	BList	*uhead;			/* blocks to unlink when this block is written */
233 	BList	*utail;
234 
235 	/* block ordering for cache -> disk */
236 	BList	*prior;			/* list of blocks before this one */
237 
238 	Block	*ionext;
239 	int	iostate;
240 	VtRendez *ioready;
241 };
242 
243 /* tree walker, for gc and archiver */
244 struct WalkPtr
245 {
246 	uchar *data;
247 	int isEntry;
248 	int n;
249 	int m;
250 	Entry e;
251 	uchar type;
252 	u32int tag;
253 };
254 
255 enum
256 {
257 	DoClose = 1<<0,
258 	DoClre = 1<<1,
259 	DoClri = 1<<2,
260 	DoClrp = 1<<3,
261 };
262 
263 struct Fsck
264 {
265 /* filled in by caller */
266 	int printblocks;
267 	int useventi;
268 	int flags;
269 	int printdirs;
270 	int printfiles;
271 	int walksnapshots;
272 	int walkfs;
273 	Fs *fs;
274 	int (*print)(char*, ...);
275 	void (*clre)(Fsck*, Block*, int);
276 	void (*clrp)(Fsck*, Block*, int);
277 	void (*close)(Fsck*, Block*, u32int);
278 	void (*clri)(Fsck*, char*, MetaBlock*, int, Block*);
279 
280 /* used internally */
281 	Cache *cache;
282 	uchar *amap;	/* all blocks seen so far */
283 	uchar *emap;	/* all blocks seen in this epoch */
284 	uchar *xmap;	/* all blocks in this epoch with parents in this epoch */
285 	uchar *errmap;	/* blocks with errors */
286 	uchar *smap;	/* walked sources */
287 	int nblocks;
288 	int bsize;
289 	int walkdepth;
290 	u32int hint;	/* where the next root probably is */
291 	int nseen;
292 	int quantum;
293 	int nclre;
294 	int nclrp;
295 	int nclose;
296 	int nclri;
297 };
298 
299 /* disk partitions */
300 enum {
301 	PartError,
302 	PartSuper,
303 	PartLabel,
304 	PartData,
305 	PartVenti,	/* fake partition */
306 };
307 
308 extern vtType[BtMax];
309