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