ref: cc6e4b6231bb28fe268feea3bfb50f7e0ee59166
dir: /load.c/
#include <u.h> #include <libc.h> #include <fcall.h> #include <avl.h> #include "dat.h" #include "fns.h" static int rangecmp(Avl *a, Avl *b) { return ((Arange*)a)->off - ((Arange*)b)->off; } int loadarena(Arena *a, vlong o) { Blk *b; if((a->free = avlcreate(rangecmp)) == nil) return -1; if((b = readblk(o, 0)) == nil) return -1; a->b = b; a->log.head.addr = GBIT64(b->data+0); a->log.head.hash = GBIT64(b->data+8); a->log.head.gen = -1; if(loadlog(a) == -1) return -1; if(compresslog(a) == -1) return -1; return 0; } void loadfs(char *dev) { int blksz, bufspc, hdrsz; int i, dirty; vlong sb; char *p, *e; Tree *t; Blk *b; Dir *d; fs->osnap = nil; if((fs->fd = open(dev, ORDWR)) == -1) sysfatal("open %s: %r", dev); if((d = dirfstat(fs->fd)) == nil) sysfatal("ream: %r"); sb = d->length - (d->length % Blksz) - Blksz; free(d); if((b = readblk(sb, 0)) == nil) sysfatal("read superblock: %r"); if(b->type != Tsuper) sysfatal("corrupt superblock: bad type"); if(memcmp(b->data, "gefs0001", 8) != 0) sysfatal("corrupt superblock: bad magic"); p = b->data + 8; dirty = GBIT32(p); p += 4; /* dirty */ blksz = GBIT32(p); p += 4; bufspc = GBIT32(p); p += 4; hdrsz = GBIT32(p); p += 4; fs->snap.ht = GBIT32(p); p += 4; fs->snap.bp.addr = GBIT64(p); p += 8; fs->snap.bp.hash = GBIT64(p); p += 8; fs->snap.bp.gen = GBIT64(p); p += 8; fs->narena = GBIT32(p); p += 4; fs->arenasz = GBIT64(p); p += 8; fs->nextqid = GBIT64(p); p += 8; fs->super = b; fs->nextgen = fs->snap.bp.gen + 1; for(i = 0; i < Ndead; i++){ fs->snap.prev[i] = -1; fs->snap.dead[i].head.addr = -1; fs->snap.dead[i].head.hash = -1; fs->snap.dead[i].head.gen = -1; } fprint(2, "load: %8s\n", p); fprint(2, "\tsnaptree:\t%B\n", fs->snap.bp); fprint(2, "\tarenas:\t%d\n", fs->narena); fprint(2, "\tarenasz:\t%lld\n", fs->arenasz); fprint(2, "\tnextqid:\t%lld\n", fs->nextqid); fprint(2, "\tnextgen:\t%lld\n", fs->nextgen); if((fs->arenas = calloc(fs->narena, sizeof(Arena))) == nil) sysfatal("malloc: %r"); for(i = 0; i < fs->narena; i++) if((loadarena(&fs->arenas[i], i*fs->arenasz)) == -1) sysfatal("loadfs: %r"); if(bufspc != Bufspc) sysfatal("fs uses different buffer size"); if(hdrsz != Hdrsz) sysfatal("fs uses different buffer size"); if(blksz != Blksz) sysfatal("fs uses different block size"); if(dirty){ fprint(2, "file system was not unmounted cleanly"); /* TODO: start gc pass */ } if((t = openlabel("main")) == nil) sysfatal("load users: no main label"); if((e = loadusers(2, t)) != nil) sysfatal("load users: %s\n", e); }