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