13e12c5d1SDavid du Colombier #include <u.h> 23e12c5d1SDavid du Colombier #include <libc.h> 33e12c5d1SDavid du Colombier #include "cformat.h" 43e12c5d1SDavid du Colombier #include "lru.h" 53e12c5d1SDavid du Colombier #include "bcache.h" 63e12c5d1SDavid du Colombier #include "disk.h" 73e12c5d1SDavid du Colombier #include "inode.h" 89a747e4fSDavid du Colombier #include "stats.h" 93e12c5d1SDavid du Colombier 103e12c5d1SDavid du Colombier /* 113e12c5d1SDavid du Colombier * read the inode blocks and make sure they 123e12c5d1SDavid du Colombier * haven't been trashed. 133e12c5d1SDavid du Colombier * 143e12c5d1SDavid du Colombier * make the in-core table of qid to inode mappings. 153e12c5d1SDavid du Colombier * N.B. this is just an array. we need a linear search to find 163e12c5d1SDavid du Colombier * a particular inode. this could be done faster. 173e12c5d1SDavid du Colombier * 183e12c5d1SDavid du Colombier * nab is the first inode block. 193e12c5d1SDavid du Colombier */ 203e12c5d1SDavid du Colombier int 213e12c5d1SDavid du Colombier iinit(Icache *ic, int f, int psize) 223e12c5d1SDavid du Colombier { 233e12c5d1SDavid du Colombier Ibuf *b; 243e12c5d1SDavid du Colombier Imap *m; 253e12c5d1SDavid du Colombier ulong ino; 263e12c5d1SDavid du Colombier Bbuf *bb; 273e12c5d1SDavid du Colombier Dinode *bi; 283e12c5d1SDavid du Colombier 293e12c5d1SDavid du Colombier /* 303e12c5d1SDavid du Colombier * get basic sizes and allocation info from disk 313e12c5d1SDavid du Colombier */ 323e12c5d1SDavid du Colombier if(dinit(ic, f, psize) < 0) 333e12c5d1SDavid du Colombier return -1; 343e12c5d1SDavid du Colombier 353e12c5d1SDavid du Colombier /* 363e12c5d1SDavid du Colombier * read first inode block to get number of inodes 373e12c5d1SDavid du Colombier */ 383e12c5d1SDavid du Colombier bb = bcread(ic, ic->nab); 393e12c5d1SDavid du Colombier if(bb == 0){ 403e12c5d1SDavid du Colombier fprint(2, "iinit: can't read disk\n"); 413e12c5d1SDavid du Colombier return -1; 423e12c5d1SDavid du Colombier } 433e12c5d1SDavid du Colombier bi = (Dinode*)bb->data; 443e12c5d1SDavid du Colombier if(bi->nino==0 || bi->nino>2048){ 453e12c5d1SDavid du Colombier fprint(2, "iinit: bad nino\n"); 463e12c5d1SDavid du Colombier return -1; 473e12c5d1SDavid du Colombier } 483e12c5d1SDavid du Colombier ic->nino = bi->nino; 493e12c5d1SDavid du Colombier 503e12c5d1SDavid du Colombier /* 513e12c5d1SDavid du Colombier * set up sizing constants 523e12c5d1SDavid du Colombier */ 533e12c5d1SDavid du Colombier ic->i2b = (ic->bsize - sizeof(Dihdr))/sizeof(Inode); 543e12c5d1SDavid du Colombier ic->nib = (ic->nino + ic->i2b - 1)/ic->i2b; 553e12c5d1SDavid du Colombier 563e12c5d1SDavid du Colombier /* 573e12c5d1SDavid du Colombier * allocate the in-core qid/inode map, build it's lru 583e12c5d1SDavid du Colombier */ 593e12c5d1SDavid du Colombier if(ic->map) 603e12c5d1SDavid du Colombier free(ic->map); 613e12c5d1SDavid du Colombier ic->map = malloc(sizeof(Imap)*ic->nino); 623e12c5d1SDavid du Colombier if(ic->map == 0){ 633e12c5d1SDavid du Colombier fprint(2, "iinit: can't alloc map\n"); 643e12c5d1SDavid du Colombier return -1; 653e12c5d1SDavid du Colombier } 663e12c5d1SDavid du Colombier lruinit(&ic->mlru); 673e12c5d1SDavid du Colombier for(m = ic->map; m < &ic->map[ic->nino]; m++){ 683e12c5d1SDavid du Colombier m->inuse = 0; 693e12c5d1SDavid du Colombier m->b = 0; 703e12c5d1SDavid du Colombier lruadd(&ic->mlru, m); 713e12c5d1SDavid du Colombier } 723e12c5d1SDavid du Colombier 733e12c5d1SDavid du Colombier /* 743e12c5d1SDavid du Colombier * mark all cache buffers as empty, put them on the lru list 753e12c5d1SDavid du Colombier */ 763e12c5d1SDavid du Colombier lruinit(&ic->blru); 773e12c5d1SDavid du Colombier for(b = ic->ib; b < &ic->ib[Nicache]; b++){ 783e12c5d1SDavid du Colombier b->inuse = 0; 793e12c5d1SDavid du Colombier lruadd(&ic->blru, b); 803e12c5d1SDavid du Colombier } 813e12c5d1SDavid du Colombier 823e12c5d1SDavid du Colombier /* 833e12c5d1SDavid du Colombier * Read all inodes and 843e12c5d1SDavid du Colombier * build the in-core qid/inode map 853e12c5d1SDavid du Colombier */ 863e12c5d1SDavid du Colombier for(ino = 0; ino < ic->nino; ino++){ 873e12c5d1SDavid du Colombier b = iread(ic, ino); 883e12c5d1SDavid du Colombier if(b == 0){ 893e12c5d1SDavid du Colombier fprint(2, "iinit: can't read inode %ld\n", ino); 903e12c5d1SDavid du Colombier return -1; 913e12c5d1SDavid du Colombier } 923e12c5d1SDavid du Colombier if(b->inode.inuse){ 933e12c5d1SDavid du Colombier m = &ic->map[ino]; 943e12c5d1SDavid du Colombier m->inuse = 1; 953e12c5d1SDavid du Colombier m->qid = b->inode.qid; 963e12c5d1SDavid du Colombier lruref(&ic->mlru, m); 973e12c5d1SDavid du Colombier } 983e12c5d1SDavid du Colombier } 993e12c5d1SDavid du Colombier return 0; 1003e12c5d1SDavid du Colombier } 1013e12c5d1SDavid du Colombier 1023e12c5d1SDavid du Colombier /* 1033e12c5d1SDavid du Colombier * format the inode blocks 1043e12c5d1SDavid du Colombier */ 1053e12c5d1SDavid du Colombier int 1063e12c5d1SDavid du Colombier iformat(Icache *ic, int f, ulong nino, char *name, int bsize, int psize) 1073e12c5d1SDavid du Colombier { 108*41fb754aSDavid du Colombier int nib; 109*41fb754aSDavid du Colombier ulong bno, i2b, i; 1103e12c5d1SDavid du Colombier Bbuf *bb; 1113e12c5d1SDavid du Colombier Dinode *bi; 1123e12c5d1SDavid du Colombier 1133e12c5d1SDavid du Colombier /* 1143e12c5d1SDavid du Colombier * first format disk allocation 1153e12c5d1SDavid du Colombier */ 1163e12c5d1SDavid du Colombier if(dformat(ic, f, name, bsize, psize) < 0) 1173e12c5d1SDavid du Colombier return -1; 1183e12c5d1SDavid du Colombier 119219b2ee8SDavid du Colombier fprint(2, "formatting inodes\n"); 1203e12c5d1SDavid du Colombier 1213e12c5d1SDavid du Colombier i2b = (bsize - sizeof(Dihdr))/sizeof(Inode); 1223e12c5d1SDavid du Colombier nib = (nino + i2b - 1)/i2b; 1233e12c5d1SDavid du Colombier 1243e12c5d1SDavid du Colombier for(bno = ic->nab; bno < ic->nab + nib; bno++){ 1253e12c5d1SDavid du Colombier if(dalloc(ic, 0) == Notabno){ 1263e12c5d1SDavid du Colombier fprint(2, "iformat: balloc failed\n"); 1273e12c5d1SDavid du Colombier return -1; 1283e12c5d1SDavid du Colombier } 1293e12c5d1SDavid du Colombier bb = bcalloc(ic, bno); 1303e12c5d1SDavid du Colombier if(bb == 0){ 1313e12c5d1SDavid du Colombier fprint(2, "iformat: bcalloc failed\n"); 1323e12c5d1SDavid du Colombier return -1; 1333e12c5d1SDavid du Colombier } 1343e12c5d1SDavid du Colombier bi = (Dinode*)bb->data; 1353e12c5d1SDavid du Colombier bi->magic = Imagic; 1363e12c5d1SDavid du Colombier bi->nino = nino; 1373e12c5d1SDavid du Colombier for(i = 0; i < i2b; i++) 1383e12c5d1SDavid du Colombier bi->inode[i].inuse = 0; 1393e12c5d1SDavid du Colombier bcmark(ic, bb); 1403e12c5d1SDavid du Colombier } 1413e12c5d1SDavid du Colombier 1423e12c5d1SDavid du Colombier bcsync(ic); 1433e12c5d1SDavid du Colombier 1443e12c5d1SDavid du Colombier return iinit(ic, f, psize); 1453e12c5d1SDavid du Colombier } 1463e12c5d1SDavid du Colombier 1473e12c5d1SDavid du Colombier /* 1483e12c5d1SDavid du Colombier * allocate a cache buffer, use least recently used 1493e12c5d1SDavid du Colombier */ 1503e12c5d1SDavid du Colombier Ibuf* 1513e12c5d1SDavid du Colombier ialloc(Icache *ic, ulong ino) 1523e12c5d1SDavid du Colombier { 1533e12c5d1SDavid du Colombier Imap *m; 1543e12c5d1SDavid du Colombier Ibuf *b; 1553e12c5d1SDavid du Colombier 1563e12c5d1SDavid du Colombier b = (Ibuf*)ic->blru.lnext; 1573e12c5d1SDavid du Colombier if(b->inuse) 1583e12c5d1SDavid du Colombier ic->map[b->ino].b = 0; 1593e12c5d1SDavid du Colombier b->ino = ino; 1603e12c5d1SDavid du Colombier b->inuse = 1; 1613e12c5d1SDavid du Colombier m = &ic->map[ino]; 1623e12c5d1SDavid du Colombier m->b = b; 1633e12c5d1SDavid du Colombier return b; 1643e12c5d1SDavid du Colombier } 1653e12c5d1SDavid du Colombier 1663e12c5d1SDavid du Colombier /* 1673e12c5d1SDavid du Colombier * free a cache buffer 1683e12c5d1SDavid du Colombier */ 1693e12c5d1SDavid du Colombier void 1703e12c5d1SDavid du Colombier ifree(Icache *ic, Ibuf *b) 1713e12c5d1SDavid du Colombier { 1723e12c5d1SDavid du Colombier b->inuse = 0; 1733e12c5d1SDavid du Colombier if(b->inuse) 1743e12c5d1SDavid du Colombier ic->map[b->ino].b = 0; 1753e12c5d1SDavid du Colombier lruderef(&ic->blru, b); 1763e12c5d1SDavid du Colombier } 1773e12c5d1SDavid du Colombier 1783e12c5d1SDavid du Colombier /* 1793e12c5d1SDavid du Colombier * get an inode into the cache. if no inode exists for this qid, create one 1803e12c5d1SDavid du Colombier * from an unused qid/inode map. 1813e12c5d1SDavid du Colombier */ 1823e12c5d1SDavid du Colombier Ibuf * 1833e12c5d1SDavid du Colombier iget(Icache *ic, Qid qid) 1843e12c5d1SDavid du Colombier { 1853e12c5d1SDavid du Colombier Imap *m, *me; 1863e12c5d1SDavid du Colombier Ibuf *b; 1873e12c5d1SDavid du Colombier 1883e12c5d1SDavid du Colombier /* 1893e12c5d1SDavid du Colombier * find map entry with same qid.path 1903e12c5d1SDavid du Colombier */ 191*41fb754aSDavid du Colombier for(m = ic->map, me = &ic->map[ic->nino]; m < me; m++) 1923e12c5d1SDavid du Colombier if(m->inuse && m->qid.path==qid.path){ 1933e12c5d1SDavid du Colombier if(m->qid.vers != qid.vers){ 1943e12c5d1SDavid du Colombier /* 1953e12c5d1SDavid du Colombier * our info is old, forget it 1963e12c5d1SDavid du Colombier */ 1979a747e4fSDavid du Colombier DPRINT(2, "updating old file %llud.%lud\n", 1983e12c5d1SDavid du Colombier qid.path, qid.vers); 1993e12c5d1SDavid du Colombier m->qid = qid; 2003e12c5d1SDavid du Colombier iupdate(ic, m - ic->map, qid); 2013e12c5d1SDavid du Colombier } 2023e12c5d1SDavid du Colombier break; 2033e12c5d1SDavid du Colombier } 2043e12c5d1SDavid du Colombier 2053e12c5d1SDavid du Colombier /* 2063e12c5d1SDavid du Colombier * if an already existing inode, just get it 2073e12c5d1SDavid du Colombier */ 2083e12c5d1SDavid du Colombier if(m != me) 2093e12c5d1SDavid du Colombier return iread(ic, m - ic->map); 2103e12c5d1SDavid du Colombier 2113e12c5d1SDavid du Colombier /* 2123e12c5d1SDavid du Colombier * create a new inode, throw out the least recently used inode 2133e12c5d1SDavid du Colombier * if necessary 2143e12c5d1SDavid du Colombier */ 2153e12c5d1SDavid du Colombier m = (Imap*)ic->mlru.lnext; 2163e12c5d1SDavid du Colombier if(m->inuse){ 217*41fb754aSDavid du Colombier DPRINT(2, "superceding file %llud.%ld by %llud.%ld\n", 218*41fb754aSDavid du Colombier m->qid.path, m->qid.vers, qid.path, qid.vers); 2193e12c5d1SDavid du Colombier if(iremove(ic, m - ic->map) < 0) 2203e12c5d1SDavid du Colombier return 0; 2213e12c5d1SDavid du Colombier } 2223e12c5d1SDavid du Colombier 223*41fb754aSDavid du Colombier if(statson) 2249a747e4fSDavid du Colombier cfsstat.ninsert++; 2253e12c5d1SDavid du Colombier /* 2263e12c5d1SDavid du Colombier * init inode and write to disk 2273e12c5d1SDavid du Colombier */ 228*41fb754aSDavid du Colombier DPRINT(2, "new file %llud.%ld ino %ld\n", 229*41fb754aSDavid du Colombier qid.path, qid.vers, m - ic->map); 2303e12c5d1SDavid du Colombier b = ialloc(ic, m - ic->map); 2313e12c5d1SDavid du Colombier b->inode.inuse = m->inuse = 1; 2323e12c5d1SDavid du Colombier b->inode.qid = qid; 2339a747e4fSDavid du Colombier b->inode.length = 0x7fffffffffffffffLL; 2343e12c5d1SDavid du Colombier m->qid = qid; 2353e12c5d1SDavid du Colombier b->inode.ptr.bno = Notabno; 2363e12c5d1SDavid du Colombier iwrite(ic, b); 2373e12c5d1SDavid du Colombier return b; 2383e12c5d1SDavid du Colombier } 2393e12c5d1SDavid du Colombier 2403e12c5d1SDavid du Colombier /* 2413e12c5d1SDavid du Colombier * read an inode into the cache 2423e12c5d1SDavid du Colombier * 2433e12c5d1SDavid du Colombier * ASSUMPTION: the inode is valid 2443e12c5d1SDavid du Colombier */ 2453e12c5d1SDavid du Colombier Ibuf* 2463e12c5d1SDavid du Colombier iread(Icache *ic, ulong ino) 2473e12c5d1SDavid du Colombier { 2483e12c5d1SDavid du Colombier Ibuf *b; 2493e12c5d1SDavid du Colombier Imap *m; 2503e12c5d1SDavid du Colombier ulong bno; 2513e12c5d1SDavid du Colombier Bbuf *bb; 2523e12c5d1SDavid du Colombier Dinode *bi; 2533e12c5d1SDavid du Colombier 2543e12c5d1SDavid du Colombier /* 2553e12c5d1SDavid du Colombier * first see if we already have it in a cache entry 2563e12c5d1SDavid du Colombier */ 2573e12c5d1SDavid du Colombier m = &ic->map[ino]; 2583e12c5d1SDavid du Colombier if(m->inuse && m->b){ 2593e12c5d1SDavid du Colombier b = m->b; 2603e12c5d1SDavid du Colombier goto out; 2613e12c5d1SDavid du Colombier } 2623e12c5d1SDavid du Colombier 2633e12c5d1SDavid du Colombier /* 2643e12c5d1SDavid du Colombier * read it 2653e12c5d1SDavid du Colombier */ 2663e12c5d1SDavid du Colombier b = ialloc(ic, ino); 2673e12c5d1SDavid du Colombier bno = ic->nab + ino/ic->i2b; 2683e12c5d1SDavid du Colombier bb = bcread(ic, bno); 2693e12c5d1SDavid du Colombier if(bb == 0){ 2703e12c5d1SDavid du Colombier ifree(ic, b); 2713e12c5d1SDavid du Colombier return 0; 2723e12c5d1SDavid du Colombier } 2733e12c5d1SDavid du Colombier bi = (Dinode*)bb->data; 2743e12c5d1SDavid du Colombier b->inode = bi->inode[ino % ic->i2b]; 2753e12c5d1SDavid du Colombier 2763e12c5d1SDavid du Colombier /* 2773e12c5d1SDavid du Colombier * consistency check 2783e12c5d1SDavid du Colombier */ 2793e12c5d1SDavid du Colombier if(bi->nino!=ic->nino || bi->magic!=Imagic){ 2803e12c5d1SDavid du Colombier fprint(2, "iread: inconsistent inode block\n"); 2813e12c5d1SDavid du Colombier ifree(ic, b); 2823e12c5d1SDavid du Colombier return 0; 2833e12c5d1SDavid du Colombier } 2843e12c5d1SDavid du Colombier out: 2853e12c5d1SDavid du Colombier b->inuse = 1; 2863e12c5d1SDavid du Colombier m->b = b; 2873e12c5d1SDavid du Colombier if(b->inode.inuse) 2883e12c5d1SDavid du Colombier lruref(&ic->mlru, m); 2893e12c5d1SDavid du Colombier lruref(&ic->blru, b); 2903e12c5d1SDavid du Colombier return b; 2913e12c5d1SDavid du Colombier } 2923e12c5d1SDavid du Colombier 2933e12c5d1SDavid du Colombier /* 2943e12c5d1SDavid du Colombier * write an inode back to disk 2953e12c5d1SDavid du Colombier */ 2963e12c5d1SDavid du Colombier int 2973e12c5d1SDavid du Colombier iwrite(Icache *ic, Ibuf *b) 2983e12c5d1SDavid du Colombier { 2993e12c5d1SDavid du Colombier ulong bno; 3003e12c5d1SDavid du Colombier Bbuf *bb; 3013e12c5d1SDavid du Colombier Dinode *bi; 3023e12c5d1SDavid du Colombier 3033e12c5d1SDavid du Colombier bno = ic->nab + b->ino/ic->i2b; 3043e12c5d1SDavid du Colombier bb = bcread(ic, bno); 3053e12c5d1SDavid du Colombier if(bb == 0) 3063e12c5d1SDavid du Colombier return 0; 3073e12c5d1SDavid du Colombier bi = (Dinode*)bb->data; 3083e12c5d1SDavid du Colombier bi->inode[b->ino % ic->i2b] = b->inode; 3093e12c5d1SDavid du Colombier bcmark(ic, bb); 3103e12c5d1SDavid du Colombier lruref(&ic->mlru, &ic->map[b->ino]); 3113e12c5d1SDavid du Colombier lruref(&ic->blru, b); 3123e12c5d1SDavid du Colombier return 0; 3133e12c5d1SDavid du Colombier } 3143e12c5d1SDavid du Colombier 3153e12c5d1SDavid du Colombier /* 3163e12c5d1SDavid du Colombier * Forget what we know about an inode without removing it 3173e12c5d1SDavid du Colombier * 3183e12c5d1SDavid du Colombier * N.B: ordering of iwrite and dfree is important 3193e12c5d1SDavid du Colombier */ 3203e12c5d1SDavid du Colombier int 3213e12c5d1SDavid du Colombier iupdate(Icache *ic, ulong ino, Qid qid) 3223e12c5d1SDavid du Colombier { 3233e12c5d1SDavid du Colombier Ibuf *b; 3243e12c5d1SDavid du Colombier Imap *m; 3253e12c5d1SDavid du Colombier Dptr d; 3263e12c5d1SDavid du Colombier 327*41fb754aSDavid du Colombier if(statson) 3289a747e4fSDavid du Colombier cfsstat.nupdate++; 3293e12c5d1SDavid du Colombier b = iread(ic, ino); 3303e12c5d1SDavid du Colombier if(b == 0) 3313e12c5d1SDavid du Colombier return -1; 3323e12c5d1SDavid du Colombier 3333e12c5d1SDavid du Colombier /* 3343e12c5d1SDavid du Colombier * update inode and map 3353e12c5d1SDavid du Colombier */ 3363e12c5d1SDavid du Colombier b->inode.qid = qid; 3379a747e4fSDavid du Colombier b->inode.length = 0x7fffffffffffffffLL; /* Set to maximum */ 3383e12c5d1SDavid du Colombier m = &ic->map[ino]; 3393e12c5d1SDavid du Colombier m->qid = qid; 3403e12c5d1SDavid du Colombier 3413e12c5d1SDavid du Colombier /* 3423e12c5d1SDavid du Colombier * the free is not done if the write fails! 3433e12c5d1SDavid du Colombier * this is important 3443e12c5d1SDavid du Colombier */ 3453e12c5d1SDavid du Colombier d = b->inode.ptr; 3463e12c5d1SDavid du Colombier b->inode.ptr.bno = Notabno; 3473e12c5d1SDavid du Colombier if(iwrite(ic, b) < 0) 3483e12c5d1SDavid du Colombier return -1; 3493e12c5d1SDavid du Colombier dfree(ic, &d); 3503e12c5d1SDavid du Colombier return 0; 3513e12c5d1SDavid du Colombier } 3523e12c5d1SDavid du Colombier 3533e12c5d1SDavid du Colombier /* 3543e12c5d1SDavid du Colombier * remove an inode 3553e12c5d1SDavid du Colombier * 3563e12c5d1SDavid du Colombier * N.B: ordering of iwrite and dfree is important 3573e12c5d1SDavid du Colombier */ 3583e12c5d1SDavid du Colombier int 3593e12c5d1SDavid du Colombier iremove(Icache *ic, ulong ino) 3603e12c5d1SDavid du Colombier { 3613e12c5d1SDavid du Colombier Ibuf *b; 3623e12c5d1SDavid du Colombier Imap *m; 3633e12c5d1SDavid du Colombier 364*41fb754aSDavid du Colombier if(statson) 3659a747e4fSDavid du Colombier cfsstat.ndelete++; 3663e12c5d1SDavid du Colombier m = &ic->map[ino]; 3673e12c5d1SDavid du Colombier 3683e12c5d1SDavid du Colombier /* 3693e12c5d1SDavid du Colombier * read in inode 3703e12c5d1SDavid du Colombier */ 3713e12c5d1SDavid du Colombier b = iread(ic, ino); 3723e12c5d1SDavid du Colombier if(b == 0) 3733e12c5d1SDavid du Colombier return -1; 3743e12c5d1SDavid du Colombier 3753e12c5d1SDavid du Colombier /* 3763e12c5d1SDavid du Colombier * mark it unused on disk 3773e12c5d1SDavid du Colombier */ 3783e12c5d1SDavid du Colombier b->inode.inuse = 0; 3793e12c5d1SDavid du Colombier if(iwrite(ic, b) < 0) 3803e12c5d1SDavid du Colombier return -1; 3813e12c5d1SDavid du Colombier 3823e12c5d1SDavid du Colombier /* 3833e12c5d1SDavid du Colombier * throw out it's data pages 3843e12c5d1SDavid du Colombier */ 3853e12c5d1SDavid du Colombier dfree(ic, &b->inode.ptr); 3863e12c5d1SDavid du Colombier 3873e12c5d1SDavid du Colombier /* 3883e12c5d1SDavid du Colombier * free the inode buffer 3893e12c5d1SDavid du Colombier */ 3903e12c5d1SDavid du Colombier ifree(ic, b); 3913e12c5d1SDavid du Colombier 3923e12c5d1SDavid du Colombier /* 3933e12c5d1SDavid du Colombier * make map entry least recently used 3943e12c5d1SDavid du Colombier */ 3953e12c5d1SDavid du Colombier lruderef(&ic->mlru, m); 3963e12c5d1SDavid du Colombier return 0; 3973e12c5d1SDavid du Colombier } 3983e12c5d1SDavid du Colombier 3993e12c5d1SDavid du Colombier /* 4003e12c5d1SDavid du Colombier * increment our version number 4013e12c5d1SDavid du Colombier */ 4023e12c5d1SDavid du Colombier void 4033e12c5d1SDavid du Colombier iinc(Icache *ic, Ibuf *b) 4043e12c5d1SDavid du Colombier { 4053e12c5d1SDavid du Colombier b->inode.qid.vers++; 4063e12c5d1SDavid du Colombier ic->map[b->ino].qid = b->inode.qid; 4073e12c5d1SDavid du Colombier iwrite(ic, b); 4083e12c5d1SDavid du Colombier } 409