static int32_t rel2abs(Fs *fs, Dentry *d, int32_t a) { int32_t addr; if(a < NDBLOCK) return d->dblock[a]; a -= NDBLOCK; if(a < fs->kfs.INDPERBUF){ if(d->iblock == 0) return 0; addr = indfetch(fs, d->iblock, a, Tind1, d->qid.path); if(addr == 0) print("rel2abs indfetch 0 %s %ld\n", d->name, a); return addr; } a -= fs->kfs.INDPERBUF; if(a < fs->kfs.INDPERBUF2){ if(d->diblock == 0) return 0; addr = indfetch(fs, d->diblock, a/fs->kfs.INDPERBUF, Tind2, d->qid.path); if(addr == 0){ print("rel2abs indfetch 0 %s %ld\n", d->name, a/fs->kfs.INDPERBUF); return 0; } addr = indfetch(fs, addr, a%fs->kfs.INDPERBUF, Tind1, d->qid.path); return addr; } print("rel2abs trip ind %s %ld\n", d->name, a); return -1; }
long rel2abs(Iobuf *p, Dentry *d, long a, int tag, int putb) { long addr, qpath; Device dev; if(a < 0) { print("dnodebuf: neg\n"); return 0; } qpath = d->qid.path; dev = p->dev; if(a < NDBLOCK) { addr = d->dblock[a]; if(!addr && tag) { addr = balloc(dev, tag, qpath); d->dblock[a] = addr; p->flags |= Bmod|Bimm; } if(putb) putbuf(p); return addr; } a -= NDBLOCK; if(a < INDPERBUF) { addr = d->iblock; if(!addr && tag) { addr = balloc(dev, Tind1, qpath); d->iblock = addr; p->flags |= Bmod|Bimm; } if(putb) putbuf(p); addr = indfetch(p, d, addr, a, Tind1, tag); return addr; } a -= INDPERBUF; if(a < INDPERBUF2) { addr = d->diblock; if(!addr && tag) { addr = balloc(dev, Tind2, qpath); d->diblock = addr; p->flags |= Bmod|Bimm; } if(putb) putbuf(p); addr = indfetch(p, d, addr, a/INDPERBUF, Tind2, Tind1); addr = indfetch(p, d, addr, a%INDPERBUF, Tind1, tag); return addr; } if(putb) putbuf(p); print("dnodebuf: trip indirect\n"); return 0; }
Off rel2abs(Iobuf *p, Dentry *d, Off a, int tag, int putb, int uid) { int i; Off addr, qpath, indaddrs = 1, div; Device *dev; if(a < 0) { print("rel2abs: neg offset\n"); if(putb) putbuf(p); return 0; } dev = p->dev; qpath = d->qid.path; /* is `a' a direct block? */ if(a < NDBLOCK) { addr = d->dblock[a]; if(!addr && tag) { addr = bufalloc(dev, tag, qpath, uid); d->dblock[a] = addr; p->flags |= Bmod|Bimm; } if(putb) putbuf(p); return addr; } a -= NDBLOCK; /* * loop through indirect block depths. */ for (i = 0; i < NIBLOCK; i++) { indaddrs *= INDPERBUF; /* is a's disk addr in this indir block or one of its kids? */ if (a < indaddrs) { addr = d->iblocks[i]; if(!addr && tag) { addr = bufalloc(dev, Tind1+i, qpath, uid); d->iblocks[i] = addr; p->flags |= Bmod|Bimm; } if(putb) putbuf(p); div = indaddrs; for (; i >= 0; i--) { div /= INDPERBUF; if (div <= 0) panic("rel2abs: non-positive divisor"); addr = indfetch(dev, qpath, addr, (a/div)%INDPERBUF, Tind1+i, (i == 0? tag: Tind1+i-1), uid); } return addr; } a -= indaddrs; } if(putb) putbuf(p); /* quintuple-indirect blocks not implemented. */ print("rel2abs: no %d-deep indirect\n", NIBLOCK+1); return 0; }