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