dat.h 7.7 KB

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