1 #include "all.h" 2 3 Dentry* 4 getdir(Iobuf *p, int slot) 5 { 6 Dentry *d; 7 8 if(!p) 9 return 0; 10 d = (Dentry*)p->iobuf + slot%DIRPERBUF; 11 return d; 12 } 13 14 void 15 accessdir(Iobuf *p, Dentry *d, int f) 16 { 17 long t; 18 19 if(p && !isro(p->dev)) { 20 if(!(f & (FWRITE|FWSTAT)) && noatime) 21 return; 22 t = time(nil); 23 if(f & (FREAD|FWRITE|FWSTAT)){ 24 d->atime = t; 25 p->flags |= Bmod; 26 } 27 if(f & FWRITE) { 28 d->mtime = t; 29 d->qid.version++; 30 p->flags |= Bmod; 31 } 32 } 33 } 34 35 void 36 dbufread(Iobuf *p, Dentry *d, long a) 37 { 38 USED(p, d, a); 39 } 40 41 long 42 rel2abs(Iobuf *p, Dentry *d, long a, int tag, int putb) 43 { 44 long addr, qpath; 45 Device dev; 46 47 if(a < 0) { 48 print("dnodebuf: neg\n"); 49 return 0; 50 } 51 qpath = d->qid.path; 52 dev = p->dev; 53 if(a < NDBLOCK) { 54 addr = d->dblock[a]; 55 if(!addr && tag) { 56 addr = balloc(dev, tag, qpath); 57 d->dblock[a] = addr; 58 p->flags |= Bmod|Bimm; 59 } 60 if(putb) 61 putbuf(p); 62 return addr; 63 } 64 a -= NDBLOCK; 65 if(a < INDPERBUF) { 66 addr = d->iblock; 67 if(!addr && tag) { 68 addr = balloc(dev, Tind1, qpath); 69 d->iblock = addr; 70 p->flags |= Bmod|Bimm; 71 } 72 if(putb) 73 putbuf(p); 74 addr = indfetch(p, d, addr, a, Tind1, tag); 75 return addr; 76 } 77 a -= INDPERBUF; 78 if(a < INDPERBUF2) { 79 addr = d->diblock; 80 if(!addr && tag) { 81 addr = balloc(dev, Tind2, qpath); 82 d->diblock = addr; 83 p->flags |= Bmod|Bimm; 84 } 85 if(putb) 86 putbuf(p); 87 addr = indfetch(p, d, addr, a/INDPERBUF, Tind2, Tind1); 88 addr = indfetch(p, d, addr, a%INDPERBUF, Tind1, tag); 89 return addr; 90 } 91 if(putb) 92 putbuf(p); 93 print("dnodebuf: trip indirect\n"); 94 return 0; 95 } 96 97 Iobuf* 98 dnodebuf(Iobuf *p, Dentry *d, long a, int tag) 99 { 100 long addr; 101 102 addr = rel2abs(p, d, a, tag, 0); 103 if(addr) 104 return getbuf(p->dev, addr, Bread); 105 return 0; 106 } 107 108 /* 109 * same as dnodebuf but it calls putpuf(p) 110 * to reduce interference. 111 */ 112 Iobuf* 113 dnodebuf1(Iobuf *p, Dentry *d, long a, int tag) 114 { 115 long addr; 116 Device dev; 117 118 dev = p->dev; 119 addr = rel2abs(p, d, a, tag, 1); 120 if(addr) 121 return getbuf(dev, addr, Bread); 122 return 0; 123 124 } 125 126 long 127 indfetch(Iobuf *p, Dentry *d, long addr, long a, int itag, int tag) 128 { 129 Iobuf *bp; 130 131 if(!addr) 132 return 0; 133 bp = getbuf(p->dev, addr, Bread); 134 if(!bp || checktag(bp, itag, d->qid.path)) { 135 if(!bp) { 136 print("ind fetch bp = 0\n"); 137 return 0; 138 } 139 print("ind fetch tag\n"); 140 putbuf(bp); 141 return 0; 142 } 143 addr = ((long*)bp->iobuf)[a]; 144 if(!addr && tag) { 145 addr = balloc(p->dev, tag, d->qid.path); 146 if(addr) { 147 ((long*)bp->iobuf)[a] = addr; 148 bp->flags |= Bmod; 149 if(localfs || tag == Tdir) 150 bp->flags |= Bimm; 151 settag(bp, itag, d->qid.path); 152 } 153 } 154 putbuf(bp); 155 return addr; 156 } 157 158 void 159 dtrunc(Iobuf *p, Dentry *d) 160 { 161 int i; 162 163 bfree(p->dev, d->diblock, 2); 164 d->diblock = 0; 165 bfree(p->dev, d->iblock, 1); 166 d->iblock = 0; 167 for(i=NDBLOCK-1; i>=0; i--) { 168 bfree(p->dev, d->dblock[i], 0); 169 d->dblock[i] = 0; 170 } 171 d->size = 0; 172 p->flags |= Bmod|Bimm; 173 accessdir(p, d, FWRITE); 174 } 175