Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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];