Blame


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