123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- #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);
- }
|