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