ref: 5c21eca829380c28769f79beabb7cc51f1787f97
dir: /tag.c/
#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; }