ref: 985b2457cda207c2c65edeb647aedbb6e92dac46
dir: /sys/src/cmd/disk/kfs/dentry.c/
#include "all.h" Dentry* getdir(Iobuf *p, int slot) { Dentry *d; if(!p) return 0; d = (Dentry*)p->iobuf + slot%DIRPERBUF; return d; } void accessdir(Iobuf *p, Dentry *d, int f) { long t; if(p && !isro(p->dev)) { if(!(f & (FWRITE|FWSTAT)) && noatime) return; t = time(nil); if(f & (FREAD|FWRITE|FWSTAT)){ d->atime = t; p->flags |= Bmod; } if(f & FWRITE) { d->mtime = t; d->qid.version++; p->flags |= Bmod; } } } void dbufread(Iobuf *p, Dentry *d, long a) { USED(p, d, a); } 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; } Iobuf* dnodebuf(Iobuf *p, Dentry *d, long a, int tag) { long addr; addr = rel2abs(p, d, a, tag, 0); if(addr) return getbuf(p->dev, addr, Bread); return 0; } /* * same as dnodebuf but it calls putpuf(p) * to reduce interference. */ Iobuf* dnodebuf1(Iobuf *p, Dentry *d, long a, int tag) { long addr; Device dev; dev = p->dev; addr = rel2abs(p, d, a, tag, 1); if(addr) return getbuf(dev, addr, Bread); return 0; } long indfetch(Iobuf *p, Dentry *d, long addr, long a, int itag, int tag) { Iobuf *bp; if(!addr) return 0; bp = getbuf(p->dev, addr, Bread); if(!bp || checktag(bp, itag, d->qid.path)) { if(!bp) { print("ind fetch bp = 0\n"); return 0; } print("ind fetch tag\n"); putbuf(bp); return 0; } addr = ((long*)bp->iobuf)[a]; if(!addr && tag) { addr = balloc(p->dev, tag, d->qid.path); if(addr) { ((long*)bp->iobuf)[a] = addr; bp->flags |= Bmod; if(localfs || tag == Tdir) bp->flags |= Bimm; settag(bp, itag, d->qid.path); } } putbuf(bp); return addr; } void dtrunc(Iobuf *p, Dentry *d) { int i; bfree(p->dev, d->diblock, 2); d->diblock = 0; bfree(p->dev, d->iblock, 1); d->iblock = 0; for(i=NDBLOCK-1; i>=0; i--) { bfree(p->dev, d->dblock[i], 0); d->dblock[i] = 0; } d->size = 0; p->flags |= Bmod|Bimm; accessdir(p, d, FWRITE); }