Blob


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