code: mafs

ref: a566629485f872d51d4d5661d8b4aa32bd45f3e2
dir: /tag.c/

View raw version
#include <u.h>
#include <libc.h>
#include "dat.h"
#include "fns.h"

static u64
addu64ov(u64 a, u64 b)
{
	u64 r = a + b;

	if (r < a || r < b)
		return 0;
	return r;
}

static u64
mulu64ov(u64 a, u64 b)
{
	u64 r = a * b;

	if (a != 0 && r/a != b || r < a || r < b)
		return 0;
	return r;
}

/* could use muluvlongov() here but it does not add any value for us
	raise base to n-th power; n >= 0
 */
u64
power(u64 base, int n)
{
	int i;
	u64 v;

	v = 1;
	for(i = 1; i <= n; i++)
		v = v*base;
	return v;
}

/* Each u64 address in this indirect block links to n Tdata/Tdentry blocks */
u64
nperindunit(u16 tag)
{
	if(tag < Tind0 || tag > Tmaxind+1)
		return 0;

	if(tag == Tind0)
		return 1;
	return Nspanidperblock*power(Blocksize/sizeof(u64), tag-Tind1);
}

/* Each u64 address in the indirect block links to n Tdata/Tdentry blocks */
u64
nperiblock(u16 tag)
{
	return nperindunit(tag+1);
}

/* get the Tindn tag of the block that a reli belongs to */
u8
rel2tind(u64 reli)
{
	u64 maxfortag, tag, i;

	if(reli < Ndspanid){
		panic("should not be here");
	}
	reli -= Ndspanid;

	for(tag = Tind0, i = reli; tag <= Tmaxind; tag++){
		maxfortag = nperiblock(tag);
		if(i < maxfortag)
			break;
		i -= maxfortag;
	}
	return tag;
}