11 * read the inode blocks and make sure they
12 * haven't been trashed.
14 * make the in-core table of qid to inode mappings.
15 * N.B. this is just an array. we need a linear search to find
16 * a particular inode. this could be done faster.
18 * nab is the first inode block.
21 iinit(Icache *ic, int f, int psize, char* name)
30 * get basic sizes and allocation info from disk
32 if(dinit(ic, f, psize, name) < 0)
36 * read first inode block to get number of inodes
38 bb = bcread(ic, ic->nab);
40 fprint(2, "iinit: can't read disk\n");
43 bi = (Dinode*)bb->data;
44 if(bi->nino==0 || bi->nino>2048){
45 fprint(2, "iinit: bad nino\n");
51 * set up sizing constants
53 ic->i2b = (ic->bsize - sizeof(Dihdr))/sizeof(Inode);
54 ic->nib = (ic->nino + ic->i2b - 1)/ic->i2b;
57 * allocate the in-core qid/inode map, build it's lru
61 ic->map = malloc(sizeof(Imap)*ic->nino);
63 fprint(2, "iinit: can't alloc map\n");
67 for(m = ic->map; m < &ic->map[ic->nino]; m++){
74 * mark all cache buffers as empty, put them on the lru list
77 for(b = ic->ib; b < &ic->ib[Nicache]; b++){
84 * build the in-core qid/inode map
86 for(ino = 0; ino < ic->nino; ino++){
89 fprint(2, "iinit: can't read inode %ld\n", ino);
95 m->qid = b->inode.qid;
103 * format the inode blocks
106 iformat(Icache *ic, int f, ulong nino, char *name, int bsize, int psize)
114 * first format disk allocation
116 if(dformat(ic, f, name, bsize, psize) < 0)
119 fprint(2, "formatting inodes\n");
121 i2b = (bsize - sizeof(Dihdr))/sizeof(Inode);
122 nib = (nino + i2b - 1)/i2b;
124 for(bno = ic->nab; bno < ic->nab + nib; bno++){
125 if(dalloc(ic, 0) == Notabno){
126 fprint(2, "iformat: balloc failed\n");
129 bb = bcalloc(ic, bno);
131 fprint(2, "iformat: bcalloc failed\n");
134 bi = (Dinode*)bb->data;
137 for(i = 0; i < i2b; i++)
138 bi->inode[i].inuse = 0;
144 return iinit(ic, f, psize, name);
148 * allocate a cache buffer, use least recently used
151 ialloc(Icache *ic, ulong ino)
156 b = (Ibuf*)ic->blru.lnext;
158 ic->map[b->ino].b = 0;
167 * free a cache buffer
170 ifree(Icache *ic, Ibuf *b)
174 ic->map[b->ino].b = 0;
175 lruderef(&ic->blru, b);
179 * get an inode into the cache. if no inode exists for this qid, create one
180 * from an unused qid/inode map.
183 iget(Icache *ic, Qid qid)
189 * find map entry with same qid.path
191 for(m = ic->map, me = &ic->map[ic->nino]; m < me; m++)
192 if(m->inuse && m->qid.path==qid.path){
193 if(m->qid.vers != qid.vers){
195 * our info is old, forget it
197 DPRINT(2, "updating old file %llud.%lud\n",
200 iupdate(ic, m - ic->map, qid);
206 * if an already existing inode, just get it
209 return iread(ic, m - ic->map);
212 * create a new inode, throw out the least recently used inode
215 m = (Imap*)ic->mlru.lnext;
217 DPRINT(2, "superceding file %llud.%ld by %llud.%ld\n",
218 m->qid.path, m->qid.vers, qid.path, qid.vers);
219 if(iremove(ic, m - ic->map) < 0)
226 * init inode and write to disk
228 DPRINT(2, "new file %llud.%ld ino %zd\n",
229 qid.path, qid.vers, m - ic->map);
230 b = ialloc(ic, m - ic->map);
231 b->inode.inuse = m->inuse = 1;
233 b->inode.length = 0x7fffffffffffffffLL;
235 b->inode.ptr.bno = Notabno;
241 * read an inode into the cache
243 * ASSUMPTION: the inode is valid
246 iread(Icache *ic, ulong ino)
255 * first see if we already have it in a cache entry
258 if(m->inuse && m->b){
267 bno = ic->nab + ino/ic->i2b;
268 bb = bcread(ic, bno);
273 bi = (Dinode*)bb->data;
274 b->inode = bi->inode[ino % ic->i2b];
279 if(bi->nino!=ic->nino || bi->magic!=Imagic){
280 fprint(2, "iread: inconsistent inode block\n");
288 lruref(&ic->mlru, m);
289 lruref(&ic->blru, b);
294 * write an inode back to disk
297 iwrite(Icache *ic, Ibuf *b)
303 bno = ic->nab + b->ino/ic->i2b;
304 bb = bcread(ic, bno);
307 bi = (Dinode*)bb->data;
308 bi->inode[b->ino % ic->i2b] = b->inode;
310 lruref(&ic->mlru, &ic->map[b->ino]);
311 lruref(&ic->blru, b);
316 * Forget what we know about an inode without removing it
318 * N.B: ordering of iwrite and dfree is important
321 iupdate(Icache *ic, ulong ino, Qid qid)
334 * update inode and map
337 b->inode.length = 0x7fffffffffffffffLL; /* Set to maximum */
342 * the free is not done if the write fails!
346 b->inode.ptr.bno = Notabno;
347 if(iwrite(ic, b) < 0)
356 * N.B: ordering of iwrite and dfree is important
359 iremove(Icache *ic, ulong ino)
376 * mark it unused on disk
379 if(iwrite(ic, b) < 0)
383 * throw out it's data pages
385 dfree(ic, &b->inode.ptr);
388 * free the inode buffer
393 * make map entry least recently used
395 lruderef(&ic->mlru, m);
400 * increment our version number
403 iinc(Icache *ic, Ibuf *b)
406 ic->map[b->ino].qid = b->inode.qid;