ref: 5df01f8986e0256e7c5c0e657195892b3ca9daab
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) { if(((Arange*)a)->off < ((Arange*)b)->off) return -1; if(((Arange*)a)->off > ((Arange*)b)->off) return 1; return 0; } int loadarena(Arena *a, Bptr hdbp, vlong asz) { Blk *hd, *tl, *b; Bptr bp; /* try to load block pointers with consistency check */ bp = hdbp; hd = getblk(bp, 0); bp.addr += asz; tl = getblk(bp, 0); /* if neither head nor tail is consistent, we're hosed */ b = (hd != nil) ? hd : tl; if(b == nil) return -1; /* otherwise, we could have crashed mid-pass, just load the blocks */ bp = hdbp; if(hd == nil && (hd = getblk(bp, GBnochk)) == nil) return -1; bp.addr += asz; if(tl == nil && (tl = getblk(bp, GBnochk)) == nil) return -1; if(unpackarena(a, b->data, Arenasz) == nil) return -1; if((a->free = avlcreate(rangecmp)) == nil) return -1; a->hd = hd; a->tl = tl; a->used = a->size; return 0; } void loadfs(char *dev) { Mount *dump; Arena *a; Bptr bp; char *e; Tree *t; int i, k; if((dump = mallocz(sizeof(*dump), 1)) == nil) sysfatal("malloc: %r"); if((dump->name = strdup("dump")) == nil) sysfatal("malloc: %r"); dump->ref = 1; dump->gen = -1; dump->root = &fs->snap; fs->snapmnt = dump; fs->gotinfo = 0; fs->narena = 1; if((fs->fd = open(dev, ORDWR)) == -1) sysfatal("open %s: %r", dev); bp = (Bptr){0, -1, -1}; if((fs->sb0 = getblk(bp, GBnochk)) == nil) sysfatal("superblock: %r\n"); bp = (Bptr){512*MiB, -1, -1}; if((fs->sb1 = getblk(bp, GBnochk)) == nil) sysfatal("superblock: %r\n"); if(unpacksb(fs, fs->sb0->buf, Blksz) == nil) sysfatal("superblock: %r"); if((fs->arenas = calloc(fs->narena, sizeof(Arena))) == nil) sysfatal("malloc: %r"); for(i = 0; i < fs->narena; i++){ a = &fs->arenas[i]; memset(a, 0, sizeof(Arena)); if((loadarena(a, fs->arenabp[i], fs->arenasz)) == -1) sysfatal("loadfs: %r"); a->reserve = a->size / 1024; if(a->reserve < 32*MiB) a->reserve = 32*MiB; if(!fs->gotinfo){ if((fs->arenas = realloc(fs->arenas, fs->narena*sizeof(Arena))) == nil) sysfatal("malloc: %r"); for(k = 1; k < fs->narena; k++) memset(&fs->arenas[k], 0, sizeof(Arena)); fs->gotinfo = 1; } } for(i = 0; i < fs->narena; i++){ a = &fs->arenas[i]; if(loadlog(a, a->loghd) == -1) sysfatal("load log %B: %r", a->loghd); } fprint(2, "load %s:\n", dev); fprint(2, "\tsnaptree:\t%B\n", fs->snap.bp); fprint(2, "\tnarenas:\t%d\n", fs->narena); fprint(2, "\tarenasz:\t%lld MiB\n", fs->arenasz/MiB); fprint(2, "\tnextqid:\t%lld\n", fs->nextqid); fprint(2, "\tnextgen:\t%lld\n", fs->nextgen); fprint(2, "\tblocksize:\t%lld\n", Blksz); fprint(2, "\tcachesz:\t%lld MiB\n", fs->cmax*Blksz/MiB); if((t = opensnap("adm", nil)) == nil) sysfatal("load users: no adm label"); if((e = loadusers(2, t)) != nil) sysfatal("load users: %s\n", e); closesnap(t); }