ref: a81f100786ca7f0a1927c993f3f18a50b2480fb2
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;
return 0;
}
void
loadfs(char *dev)
{
Mount *mnt;
Arena *a;
Bptr bp;
char *e;
Tree *t;
int i, k;
if((mnt = mallocz(sizeof(*mnt), 1)) == nil)
sysfatal("malloc: %r");
if((mnt->name = strdup("dump")) == nil)
sysfatal("malloc: %r");
mnt->ref = 1;
mnt->root = nil;
mnt->gen = -1;
mnt->root = &fs->snap;
fs->snapmnt = mnt;
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(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, "\tsyncgen:\t%lld\n", fs->qgen);
fprint(2, "\tblocksize:\t%lld\n", Blksz);
fprint(2, "\tcachesz:\t%lld MiB\n", fs->cmax*Blksz/MiB);
if((t = opensnap("adm")) == nil)
sysfatal("load users: no main label");
if((e = loadusers(2, t)) != nil)
sysfatal("load users: %s\n", e);
closesnap(t);
}