Exemplo n.º 1
0
static uvlong
gbit64(void *a)
{
	uchar *i;

	i = a;
	return (uvlong)gbit32(i+4)<<32 | gbit32(i);
}
Exemplo n.º 2
0
Arquivo: storage.c Projeto: bazil/tra
static void
freedata(XDBlock *d)
{
	int i;
	u32int paddr;
	uchar *ba, *pa;
	XDBlock *f;

//print("free %ud size %ud\n", d->db.addr, d->m);
//print("slots before:\n"); for(i=LogMindat; i<=d->s->lgpagesz; i++) print("%d %ud\n", 1<<i, d->s->free[i] ? d->s->free[i]->addr : 0);
	i = dblog2(d->m);
	assert(LogMindat <= i && i <= d->s->lgpagesz);
	d->db.n = ~(u32int)0;
	branddata(d);
//print("free %p\n", d->pa);
//print("%.2ux %.2ux %.2ux %.2ux %.2ux %.2ux %.2ux %.2ux\n",
//	d->pa[0], d->pa[1], d->pa[2], d->pa[3],
//	d->pa[4], d->pa[5], d->pa[6], d->pa[7]);

	for(; i < d->s->lgpagesz; i++){
		/* try to merge with buddy */
		paddr = d->db.addr&~(2*d->m-1);
		if(paddr == d->db.addr){
			pa = d->pa;
			ba = pa+d->m;
		}else{
			pa = d->pa - d->m;
			ba = pa;
		}
		if(gbit32(ba+4) != ~(u32int)0 || gbit32(ba) != d->m)
			break;
		if(unfreedata(d->s, paddr+(ba-pa), i) < 0)
			break;
DBG print("merged %ud and %lud in slot %d\n", d->db.addr, paddr+(ba-pa), i);
		d->db.addr = paddr;
assert(pa == d->p->a+paddr-d->p->addr);
		d->pa = pa;
		d->db.a = d->pa+HdrSize;
		d->m *= 2;
	}

	branddata(d);
	f = d->s->free[i];
	pbit32((uchar*)d->db.a+4, 0);
	if(f){
		pbit32(d->db.a, f->db.addr);
		pbit32((uchar*)f->db.a+4, d->db.addr);
		((Dpage*)f->p)->flags |= DDirty;
	}else
		pbit32(d->db.a, 0);
DBG print("added %ud to slot %d next %ud (%ud)\n", d->db.addr, i, f ? f->db.addr: 0, gbit32(d->db.a));
	d->next = f;
	d->s->free[i] = d;
//print("slots after:\n"); for(i=LogMindat; i<=d->s->lgpagesz; i++) print("%d %ud\n", 1<<i, d->s->free[i] ? d->s->free[i]->addr : 0);
}
Exemplo n.º 3
0
Arquivo: storage.c Projeto: bazil/tra
/* * * * * * utility * * * * * */
static int
Bgbit32(Biobuf *b, u32int *p)
{
	uchar tmp[4];

	if(Bread(b, tmp, 4) != 4)
		return -1;
	*p = gbit32(tmp);
	return 0;
}
Exemplo n.º 4
0
Arquivo: storage.c Projeto: bazil/tra
/* * * * * * logging * * * * * */
static int
applylog(XDStore *ds)
{
	int np;
	uchar *a, *buf;
	u32int addr;
	Biobuf *b;
	Dpage *p;

	buf = malloc(ds->ds.pagesize);
	if(buf == nil)
		return -1;
	b = malloc(sizeof(Biobuf));
	if(b == nil)
		goto Error;
	if(seek(ds->logfd, 0, 0) != 0){
	Error:
		free(buf);
		free(b);
		return -1;
	}
	Binit(b, ds->logfd, OREAD);
	if(Bgbit32(b, &addr) < 0)
		goto Error;
	if(addr != gbit32((uchar*)"log\n")){
		werrstr("malformed log");
		goto Error;
	}
	np = 0;
	for(;;){
		if(Bgbit32(b, &addr) < 0)
			goto Error;
		if(addr == ~(u32int)0)
			break;
DBG print("apply log page %ud\n", addr);
		p = findpage(ds, addr);
		if(p)
			a = p->a;
		else
			a = buf;
		if(Bread(b, a, ds->ds.pagesize) != ds->ds.pagesize)
			goto Error;
		if(pwrite(ds->fd, a, ds->ds.pagesize, addr) != ds->ds.pagesize)
{
abort();
			goto Error;
}
		np++;
	}
	fprint(2, "applied changes to %d pages\n", np);
	free(b);
	free(buf);
	return 0 && fsync(ds->fd);
}
Exemplo n.º 5
0
Arquivo: storage.c Projeto: bazil/tra
static XDBlock*
loaddata(XDStore *s, u32int addr)
{
	XDBlock *d;
	Dpage *p;

	p = loadpage(s, addr&~(s->ds.pagesize-1));
	if(p == nil)
		return nil;
	d = mkdata(s, p, p->a+(addr&(s->ds.pagesize-1)), 0);
	if(d == nil){
		p->nref--;
		return nil;
	}
//print("load %ud p->addr %ud off %ud pa %p ",
//	addr, p->addr, (addr&(s->ds.pagesize-1)), p->a);
//print("%.2ux %.2ux %.2ux %.2ux %.2ux %.2ux %.2ux %.2ux\n",
//	d->pa[0], d->pa[1], d->pa[2], d->pa[3],
//	d->pa[4], d->pa[5], d->pa[6], d->pa[7]);
	d->m = gbit32(d->pa);
	d->db.n = gbit32(d->pa+4);
	return d;
}
Exemplo n.º 6
0
Arquivo: storage.c Projeto: bazil/tra
static XDBlock*
popfree(XDStore *s, int slot)
{
	u32int na;
	XDBlock *d, *nd;

	d = s->free[slot];
	if(d == nil){
		werrstr("empty slot %d", slot);
		return nil;
	}
	if(d->db.n != ~(u32int)0){
		fprint(2, "slot %d allocated page on the free list (oops)\n", slot);
		abort();
	}

	if(d->p == nil){
		d->p = loadpage(s, d->db.addr&~(s->ds.pagesize-1));
		if(d->p == nil){
			werrstr("loadpage %ud: %r", d->db.addr&~(s->ds.pagesize-1));
			return nil;
		}
		d->pa = d->p->a + (d->db.addr&(s->ds.pagesize-1));
		d->db.a = d->pa+HdrSize;
	}
	if(d->next){
DBG print("used slot %d got %ud next %ud\n", slot, d->db.addr, d->next->db.addr);
		s->free[slot] = d->next;
		return d;
	}
	na = gbit32(d->db.a);
	if(na == 0){
DBG print("used slot %d got %ud next 0\n", slot, d->db.addr);
		s->free[slot] = nil;
		return d;
	}
	nd = loaddata(s, na);
	if(nd == nil){	/* if we return d we'll leak the rest of the free chain */
DBG print("used slot %d got %ud next %ud bad: %r\n", slot, d->db.addr, na);
		werrstr("loaddata %ud: %r", na);
		return nil;
	}
	pbit32((uchar*)nd->db.a+4, 0);
	((Dpage*)nd->p)->flags |= DDirty;
	s->free[slot] = nd;
DBG print("used slot %d got %ud next %ud (loaded)\n", slot, d->db.addr, nd->db.addr);
	return d;
}
Exemplo n.º 7
0
static int
identify(Ctlr *c, ushort *id)
{
	int i;
	uchar oserial[21];
	uvlong osectors, s;

	osectors = c->sectors;
	memmove(oserial, c->serial, sizeof c->serial);

	c->feat &= ~(Dllba|Dpower|Dsmart|Dnop);
	i = gbit16(id+83) | gbit16(id+86);
	if(i & (1<<10)){
		c->feat |= Dllba;
		s = gbit64(id+100);
	}else
		s = gbit32(id+60);

	i = gbit16(id+83);
	if((i>>14) == 1) {
		if(i & (1<<3))
			c->feat |= Dpower;
		i = gbit16(id+82);
		if(i & 1)
			c->feat |= Dsmart;
		if(i & (1<<14))
			c->feat |= Dnop;
	}

	aoeidmove(c->serial, id+10, 20);
	aoeidmove(c->firmware, id+23, 8);
	aoeidmove(c->model, id+27, 40);

	if((osectors == 0 || osectors != s) &&
	    memcmp(oserial, c->serial, sizeof oserial) != 0){
		c->sectors = s;
		c->mediachange = 1;
		c->vers++;
	}
	return 0;
}
Exemplo n.º 8
0
Arquivo: storage.c Projeto: bazil/tra
	if(nd == nil){	/* if we return d we'll leak the rest of the free chain */
DBG print("used slot %d got %ud next %ud bad: %r\n", slot, d->db.addr, na);
		werrstr("loaddata %ud: %r", na);
		return nil;
	}
	pbit32((uchar*)nd->db.a+4, 0);
	((Dpage*)nd->p)->flags |= DDirty;
	s->free[slot] = nd;
DBG print("used slot %d got %ud next %ud (loaded)\n", slot, d->db.addr, nd->db.addr);
	return d;
}

static void
unloaddata(XDBlock *d)
{
DBG if(d->db.addr == 28288) print("\t%ud -> %ud, %ud\n", d->db.addr, gbit32(d->db.a), gbit32((uchar*)d->db.a+4));
	if(d->db.flags&DDirty)
		d->p->flags |= DDirty;
	d->p->nref--;
	d->p = (Dpage*)0xBBBBBBBB;
//print("unloaddata %p\n", d->pa);
//print("%.2ux %.2ux %.2ux %.2ux %.2ux %.2ux %.2ux %.2ux\n",
//	d->pa[0], d->pa[1], d->pa[2], d->pa[3],
//	d->pa[4], d->pa[5], d->pa[6], d->pa[7]);
	free(d);
}

static int
unfreedata(XDStore *s, u32int addr, int slot)
{
	u32int naddr, paddr;