1*206fef1cSDavid du Colombier #include <u.h>
2*206fef1cSDavid du Colombier #include <libc.h>
3*206fef1cSDavid du Colombier #include "cformat.h"
4*206fef1cSDavid du Colombier #include "lru.h"
5*206fef1cSDavid du Colombier #include "bcache.h"
6*206fef1cSDavid du Colombier #include "disk.h"
7*206fef1cSDavid du Colombier #include "inode.h"
8*206fef1cSDavid du Colombier #include "stats.h"
9*206fef1cSDavid du Colombier
10*206fef1cSDavid du Colombier extern int readonly;
11*206fef1cSDavid du Colombier
12*206fef1cSDavid du Colombier /*
13*206fef1cSDavid du Colombier * read the inode blocks and make sure they
14*206fef1cSDavid du Colombier * haven't been trashed.
15*206fef1cSDavid du Colombier *
16*206fef1cSDavid du Colombier * make the in-core table of qid to inode mappings.
17*206fef1cSDavid du Colombier * N.B. this is just an array. we need a linear search to find
18*206fef1cSDavid du Colombier * a particular inode. this could be done faster.
19*206fef1cSDavid du Colombier *
20*206fef1cSDavid du Colombier * nab is the first inode block.
21*206fef1cSDavid du Colombier */
22*206fef1cSDavid du Colombier int
iinit(Icache * ic,char * mc,int psize,char * name)23*206fef1cSDavid du Colombier iinit(Icache *ic, char *mc, int psize, char* name)
24*206fef1cSDavid du Colombier {
25*206fef1cSDavid du Colombier Ibuf *b;
26*206fef1cSDavid du Colombier Imap *m;
27*206fef1cSDavid du Colombier ulong ino;
28*206fef1cSDavid du Colombier Bbuf *bb;
29*206fef1cSDavid du Colombier Dinode *bi;
30*206fef1cSDavid du Colombier
31*206fef1cSDavid du Colombier /*
32*206fef1cSDavid du Colombier * get basic sizes and allocation info from disk
33*206fef1cSDavid du Colombier */
34*206fef1cSDavid du Colombier if(dinit(ic, mc, psize, name) < 0)
35*206fef1cSDavid du Colombier return -1;
36*206fef1cSDavid du Colombier
37*206fef1cSDavid du Colombier /*
38*206fef1cSDavid du Colombier * read first inode block to get number of inodes
39*206fef1cSDavid du Colombier */
40*206fef1cSDavid du Colombier bb = bcread(ic, ic->nab);
41*206fef1cSDavid du Colombier if(bb == 0){
42*206fef1cSDavid du Colombier fprint(2, "iinit: can't read disk\n");
43*206fef1cSDavid du Colombier return -1;
44*206fef1cSDavid du Colombier }
45*206fef1cSDavid du Colombier bi = (Dinode*)bb->data;
46*206fef1cSDavid du Colombier if(bi->nino==0 || bi->nino>2048){
47*206fef1cSDavid du Colombier fprint(2, "iinit: bad nino\n");
48*206fef1cSDavid du Colombier return -1;
49*206fef1cSDavid du Colombier }
50*206fef1cSDavid du Colombier ic->nino = bi->nino;
51*206fef1cSDavid du Colombier
52*206fef1cSDavid du Colombier /*
53*206fef1cSDavid du Colombier * set up sizing constants
54*206fef1cSDavid du Colombier */
55*206fef1cSDavid du Colombier ic->i2b = (ic->bsize - sizeof(Dihdr))/sizeof(Inode);
56*206fef1cSDavid du Colombier ic->nib = (ic->nino + ic->i2b - 1)/ic->i2b;
57*206fef1cSDavid du Colombier
58*206fef1cSDavid du Colombier /*
59*206fef1cSDavid du Colombier * allocate the in-core qid/inode map, build it's lru
60*206fef1cSDavid du Colombier */
61*206fef1cSDavid du Colombier if(ic->map)
62*206fef1cSDavid du Colombier free(ic->map);
63*206fef1cSDavid du Colombier ic->map = malloc(sizeof(Imap)*ic->nino);
64*206fef1cSDavid du Colombier if(ic->map == 0){
65*206fef1cSDavid du Colombier fprint(2, "iinit: can't alloc map\n");
66*206fef1cSDavid du Colombier return -1;
67*206fef1cSDavid du Colombier }
68*206fef1cSDavid du Colombier lruinit(&ic->mlru);
69*206fef1cSDavid du Colombier for(m = ic->map; m < &ic->map[ic->nino]; m++){
70*206fef1cSDavid du Colombier m->inuse = 0;
71*206fef1cSDavid du Colombier m->b = 0;
72*206fef1cSDavid du Colombier lruadd(&ic->mlru, m);
73*206fef1cSDavid du Colombier }
74*206fef1cSDavid du Colombier
75*206fef1cSDavid du Colombier /*
76*206fef1cSDavid du Colombier * mark all cache buffers as empty, put them on the lru list
77*206fef1cSDavid du Colombier */
78*206fef1cSDavid du Colombier lruinit(&ic->blru);
79*206fef1cSDavid du Colombier for(b = ic->ib; b < &ic->ib[Nicache]; b++){
80*206fef1cSDavid du Colombier b->inuse = 0;
81*206fef1cSDavid du Colombier lruadd(&ic->blru, b);
82*206fef1cSDavid du Colombier }
83*206fef1cSDavid du Colombier
84*206fef1cSDavid du Colombier /*
85*206fef1cSDavid du Colombier * Read all inodes and
86*206fef1cSDavid du Colombier * build the in-core qid/inode map
87*206fef1cSDavid du Colombier */
88*206fef1cSDavid du Colombier for(ino = 0; ino < ic->nino; ino++){
89*206fef1cSDavid du Colombier b = iread(ic, ino);
90*206fef1cSDavid du Colombier if(b == 0){
91*206fef1cSDavid du Colombier fprint(2, "iinit: can't read inode %ld\n", ino);
92*206fef1cSDavid du Colombier return -1;
93*206fef1cSDavid du Colombier }
94*206fef1cSDavid du Colombier if(b->inode.inuse){
95*206fef1cSDavid du Colombier m = &ic->map[ino];
96*206fef1cSDavid du Colombier m->inuse = 1;
97*206fef1cSDavid du Colombier m->qid = b->inode.qid;
98*206fef1cSDavid du Colombier lruref(&ic->mlru, m);
99*206fef1cSDavid du Colombier }
100*206fef1cSDavid du Colombier }
101*206fef1cSDavid du Colombier return 0;
102*206fef1cSDavid du Colombier }
103*206fef1cSDavid du Colombier
104*206fef1cSDavid du Colombier /*
105*206fef1cSDavid du Colombier * format the inode blocks
106*206fef1cSDavid du Colombier */
107*206fef1cSDavid du Colombier int
iformat(Icache * ic,char * mc,ulong nino,char * name,int bsize,int psize)108*206fef1cSDavid du Colombier iformat(Icache *ic, char *mc, ulong nino, char *name, int bsize, int psize)
109*206fef1cSDavid du Colombier {
110*206fef1cSDavid du Colombier int nib;
111*206fef1cSDavid du Colombier ulong bno, i2b, i;
112*206fef1cSDavid du Colombier Bbuf *bb;
113*206fef1cSDavid du Colombier Dinode *bi;
114*206fef1cSDavid du Colombier
115*206fef1cSDavid du Colombier /*
116*206fef1cSDavid du Colombier * first format disk allocation
117*206fef1cSDavid du Colombier */
118*206fef1cSDavid du Colombier if(dformat(ic, mc, name, bsize, psize) < 0)
119*206fef1cSDavid du Colombier return -1;
120*206fef1cSDavid du Colombier
121*206fef1cSDavid du Colombier fprint(2, "formatting inodes in memory\n");
122*206fef1cSDavid du Colombier
123*206fef1cSDavid du Colombier i2b = (bsize - sizeof(Dihdr))/sizeof(Inode);
124*206fef1cSDavid du Colombier nib = (nino + i2b - 1)/i2b;
125*206fef1cSDavid du Colombier
126*206fef1cSDavid du Colombier for(bno = ic->nab; bno < ic->nab + nib; bno++){
127*206fef1cSDavid du Colombier if(dalloc(ic, 0) == Notabno){
128*206fef1cSDavid du Colombier fprint(2, "iformat: balloc failed\n");
129*206fef1cSDavid du Colombier return -1;
130*206fef1cSDavid du Colombier }
131*206fef1cSDavid du Colombier bb = bcalloc(ic, bno);
132*206fef1cSDavid du Colombier if(bb == 0){
133*206fef1cSDavid du Colombier fprint(2, "iformat: bcalloc failed\n");
134*206fef1cSDavid du Colombier return -1;
135*206fef1cSDavid du Colombier }
136*206fef1cSDavid du Colombier bi = (Dinode*)bb->data;
137*206fef1cSDavid du Colombier bi->magic = Imagic;
138*206fef1cSDavid du Colombier bi->nino = nino;
139*206fef1cSDavid du Colombier for(i = 0; i < i2b; i++)
140*206fef1cSDavid du Colombier bi->inode[i].inuse = 0;
141*206fef1cSDavid du Colombier bcmark(ic, bb);
142*206fef1cSDavid du Colombier }
143*206fef1cSDavid du Colombier
144*206fef1cSDavid du Colombier bcsync(ic);
145*206fef1cSDavid du Colombier
146*206fef1cSDavid du Colombier return iinit(ic, mc, psize, name);
147*206fef1cSDavid du Colombier }
148*206fef1cSDavid du Colombier
149*206fef1cSDavid du Colombier /*
150*206fef1cSDavid du Colombier * allocate a cache buffer, use least recently used
151*206fef1cSDavid du Colombier */
152*206fef1cSDavid du Colombier Ibuf*
ialloc(Icache * ic,ulong ino)153*206fef1cSDavid du Colombier ialloc(Icache *ic, ulong ino)
154*206fef1cSDavid du Colombier {
155*206fef1cSDavid du Colombier Imap *m;
156*206fef1cSDavid du Colombier Ibuf *b;
157*206fef1cSDavid du Colombier
158*206fef1cSDavid du Colombier b = (Ibuf*)ic->blru.lnext;
159*206fef1cSDavid du Colombier if(b->inuse)
160*206fef1cSDavid du Colombier ic->map[b->ino].b = 0;
161*206fef1cSDavid du Colombier b->ino = ino;
162*206fef1cSDavid du Colombier b->inuse = 1;
163*206fef1cSDavid du Colombier m = &ic->map[ino];
164*206fef1cSDavid du Colombier m->b = b;
165*206fef1cSDavid du Colombier return b;
166*206fef1cSDavid du Colombier }
167*206fef1cSDavid du Colombier
168*206fef1cSDavid du Colombier /*
169*206fef1cSDavid du Colombier * free a cache buffer
170*206fef1cSDavid du Colombier */
171*206fef1cSDavid du Colombier void
ifree(Icache * ic,Ibuf * b)172*206fef1cSDavid du Colombier ifree(Icache *ic, Ibuf *b)
173*206fef1cSDavid du Colombier {
174*206fef1cSDavid du Colombier b->inuse = 0;
175*206fef1cSDavid du Colombier if(b->inuse)
176*206fef1cSDavid du Colombier ic->map[b->ino].b = 0;
177*206fef1cSDavid du Colombier lruderef(&ic->blru, b);
178*206fef1cSDavid du Colombier }
179*206fef1cSDavid du Colombier
180*206fef1cSDavid du Colombier /*
181*206fef1cSDavid du Colombier * get an inode into the cache. if no inode exists for this qid, create one
182*206fef1cSDavid du Colombier * from an unused qid/inode map.
183*206fef1cSDavid du Colombier */
184*206fef1cSDavid du Colombier Ibuf *
iget(Icache * ic,Qid qid)185*206fef1cSDavid du Colombier iget(Icache *ic, Qid qid)
186*206fef1cSDavid du Colombier {
187*206fef1cSDavid du Colombier Imap *m, *me;
188*206fef1cSDavid du Colombier Ibuf *b;
189*206fef1cSDavid du Colombier
190*206fef1cSDavid du Colombier /*
191*206fef1cSDavid du Colombier * find map entry with same qid.path
192*206fef1cSDavid du Colombier */
193*206fef1cSDavid du Colombier for(m = ic->map, me = &ic->map[ic->nino]; m < me; m++)
194*206fef1cSDavid du Colombier if(m->inuse && m->qid.path==qid.path){
195*206fef1cSDavid du Colombier if((m->qid.vers != qid.vers || qid.vers == 0)
196*206fef1cSDavid du Colombier && !readonly){
197*206fef1cSDavid du Colombier /*
198*206fef1cSDavid du Colombier * our info is old or this is likely
199*206fef1cSDavid du Colombier * a synthetic file, so forget it
200*206fef1cSDavid du Colombier */
201*206fef1cSDavid du Colombier DPRINT(2, "updating old file %llud.%lud\n",
202*206fef1cSDavid du Colombier qid.path, qid.vers);
203*206fef1cSDavid du Colombier m->qid = qid;
204*206fef1cSDavid du Colombier iupdate(ic, m - ic->map, qid);
205*206fef1cSDavid du Colombier }
206*206fef1cSDavid du Colombier break;
207*206fef1cSDavid du Colombier }
208*206fef1cSDavid du Colombier
209*206fef1cSDavid du Colombier /*
210*206fef1cSDavid du Colombier * if an already existing inode, just get it
211*206fef1cSDavid du Colombier */
212*206fef1cSDavid du Colombier if(m != me)
213*206fef1cSDavid du Colombier return iread(ic, m - ic->map);
214*206fef1cSDavid du Colombier
215*206fef1cSDavid du Colombier /*
216*206fef1cSDavid du Colombier * create a new inode, throw out the least recently used inode
217*206fef1cSDavid du Colombier * if necessary
218*206fef1cSDavid du Colombier */
219*206fef1cSDavid du Colombier m = (Imap*)ic->mlru.lnext;
220*206fef1cSDavid du Colombier if(m->inuse){
221*206fef1cSDavid du Colombier DPRINT(2, "superceding file %llud.%ld by %llud.%ld\n",
222*206fef1cSDavid du Colombier m->qid.path, m->qid.vers, qid.path, qid.vers);
223*206fef1cSDavid du Colombier if(iremove(ic, m - ic->map) < 0)
224*206fef1cSDavid du Colombier return 0;
225*206fef1cSDavid du Colombier }
226*206fef1cSDavid du Colombier
227*206fef1cSDavid du Colombier if(statson)
228*206fef1cSDavid du Colombier cfsstat.ninsert++;
229*206fef1cSDavid du Colombier /*
230*206fef1cSDavid du Colombier * init inode and write to disk
231*206fef1cSDavid du Colombier */
232*206fef1cSDavid du Colombier DPRINT(2, "new file %llud.%ld ino %ld\n",
233*206fef1cSDavid du Colombier qid.path, qid.vers, m - ic->map);
234*206fef1cSDavid du Colombier b = ialloc(ic, m - ic->map);
235*206fef1cSDavid du Colombier b->inode.inuse = m->inuse = 1;
236*206fef1cSDavid du Colombier b->inode.qid = qid;
237*206fef1cSDavid du Colombier b->inode.length = 0x7fffffffffffffffLL;
238*206fef1cSDavid du Colombier m->qid = qid;
239*206fef1cSDavid du Colombier b->inode.ptr.bno = Notabno;
240*206fef1cSDavid du Colombier iwrite(ic, b);
241*206fef1cSDavid du Colombier return b;
242*206fef1cSDavid du Colombier }
243*206fef1cSDavid du Colombier
244*206fef1cSDavid du Colombier /*
245*206fef1cSDavid du Colombier * read an inode into the cache
246*206fef1cSDavid du Colombier *
247*206fef1cSDavid du Colombier * ASSUMPTION: the inode is valid
248*206fef1cSDavid du Colombier */
249*206fef1cSDavid du Colombier Ibuf*
iread(Icache * ic,ulong ino)250*206fef1cSDavid du Colombier iread(Icache *ic, ulong ino)
251*206fef1cSDavid du Colombier {
252*206fef1cSDavid du Colombier Ibuf *b;
253*206fef1cSDavid du Colombier Imap *m;
254*206fef1cSDavid du Colombier ulong bno;
255*206fef1cSDavid du Colombier Bbuf *bb;
256*206fef1cSDavid du Colombier Dinode *bi;
257*206fef1cSDavid du Colombier
258*206fef1cSDavid du Colombier /*
259*206fef1cSDavid du Colombier * first see if we already have it in a cache entry
260*206fef1cSDavid du Colombier */
261*206fef1cSDavid du Colombier m = &ic->map[ino];
262*206fef1cSDavid du Colombier if(m->inuse && m->b){
263*206fef1cSDavid du Colombier b = m->b;
264*206fef1cSDavid du Colombier goto out;
265*206fef1cSDavid du Colombier }
266*206fef1cSDavid du Colombier
267*206fef1cSDavid du Colombier /*
268*206fef1cSDavid du Colombier * read it
269*206fef1cSDavid du Colombier */
270*206fef1cSDavid du Colombier b = ialloc(ic, ino);
271*206fef1cSDavid du Colombier bno = ic->nab + ino/ic->i2b;
272*206fef1cSDavid du Colombier bb = bcread(ic, bno);
273*206fef1cSDavid du Colombier if(bb == 0){
274*206fef1cSDavid du Colombier ifree(ic, b);
275*206fef1cSDavid du Colombier return 0;
276*206fef1cSDavid du Colombier }
277*206fef1cSDavid du Colombier bi = (Dinode*)bb->data;
278*206fef1cSDavid du Colombier b->inode = bi->inode[ino % ic->i2b];
279*206fef1cSDavid du Colombier
280*206fef1cSDavid du Colombier /*
281*206fef1cSDavid du Colombier * consistency check
282*206fef1cSDavid du Colombier */
283*206fef1cSDavid du Colombier if(bi->nino!=ic->nino || bi->magic!=Imagic){
284*206fef1cSDavid du Colombier fprint(2, "iread: inconsistent inode block\n");
285*206fef1cSDavid du Colombier ifree(ic, b);
286*206fef1cSDavid du Colombier return 0;
287*206fef1cSDavid du Colombier }
288*206fef1cSDavid du Colombier out:
289*206fef1cSDavid du Colombier b->inuse = 1;
290*206fef1cSDavid du Colombier m->b = b;
291*206fef1cSDavid du Colombier if(b->inode.inuse)
292*206fef1cSDavid du Colombier lruref(&ic->mlru, m);
293*206fef1cSDavid du Colombier lruref(&ic->blru, b);
294*206fef1cSDavid du Colombier return b;
295*206fef1cSDavid du Colombier }
296*206fef1cSDavid du Colombier
297*206fef1cSDavid du Colombier /*
298*206fef1cSDavid du Colombier * write an inode back to disk
299*206fef1cSDavid du Colombier */
300*206fef1cSDavid du Colombier int
iwrite(Icache * ic,Ibuf * b)301*206fef1cSDavid du Colombier iwrite(Icache *ic, Ibuf *b)
302*206fef1cSDavid du Colombier {
303*206fef1cSDavid du Colombier ulong bno;
304*206fef1cSDavid du Colombier Bbuf *bb;
305*206fef1cSDavid du Colombier Dinode *bi;
306*206fef1cSDavid du Colombier
307*206fef1cSDavid du Colombier bno = ic->nab + b->ino/ic->i2b;
308*206fef1cSDavid du Colombier bb = bcread(ic, bno);
309*206fef1cSDavid du Colombier if(bb == 0)
310*206fef1cSDavid du Colombier return 0;
311*206fef1cSDavid du Colombier bi = (Dinode*)bb->data;
312*206fef1cSDavid du Colombier bi->inode[b->ino % ic->i2b] = b->inode;
313*206fef1cSDavid du Colombier bcmark(ic, bb);
314*206fef1cSDavid du Colombier lruref(&ic->mlru, &ic->map[b->ino]);
315*206fef1cSDavid du Colombier lruref(&ic->blru, b);
316*206fef1cSDavid du Colombier return 0;
317*206fef1cSDavid du Colombier }
318*206fef1cSDavid du Colombier
319*206fef1cSDavid du Colombier /*
320*206fef1cSDavid du Colombier * Forget what we know about an inode without removing it
321*206fef1cSDavid du Colombier *
322*206fef1cSDavid du Colombier * N.B: ordering of iwrite and dfree is important
323*206fef1cSDavid du Colombier */
324*206fef1cSDavid du Colombier int
iupdate(Icache * ic,ulong ino,Qid qid)325*206fef1cSDavid du Colombier iupdate(Icache *ic, ulong ino, Qid qid)
326*206fef1cSDavid du Colombier {
327*206fef1cSDavid du Colombier Ibuf *b;
328*206fef1cSDavid du Colombier Imap *m;
329*206fef1cSDavid du Colombier Dptr d;
330*206fef1cSDavid du Colombier
331*206fef1cSDavid du Colombier if(statson)
332*206fef1cSDavid du Colombier cfsstat.nupdate++;
333*206fef1cSDavid du Colombier b = iread(ic, ino);
334*206fef1cSDavid du Colombier if(b == 0)
335*206fef1cSDavid du Colombier return -1;
336*206fef1cSDavid du Colombier
337*206fef1cSDavid du Colombier /*
338*206fef1cSDavid du Colombier * update inode and map
339*206fef1cSDavid du Colombier */
340*206fef1cSDavid du Colombier b->inode.qid = qid;
341*206fef1cSDavid du Colombier b->inode.length = 0x7fffffffffffffffLL; /* Set to maximum */
342*206fef1cSDavid du Colombier m = &ic->map[ino];
343*206fef1cSDavid du Colombier m->qid = qid;
344*206fef1cSDavid du Colombier
345*206fef1cSDavid du Colombier /*
346*206fef1cSDavid du Colombier * the free is not done if the write fails!
347*206fef1cSDavid du Colombier * this is important
348*206fef1cSDavid du Colombier */
349*206fef1cSDavid du Colombier d = b->inode.ptr;
350*206fef1cSDavid du Colombier b->inode.ptr.bno = Notabno;
351*206fef1cSDavid du Colombier if(iwrite(ic, b) < 0)
352*206fef1cSDavid du Colombier return -1;
353*206fef1cSDavid du Colombier dfree(ic, &d);
354*206fef1cSDavid du Colombier return 0;
355*206fef1cSDavid du Colombier }
356*206fef1cSDavid du Colombier
357*206fef1cSDavid du Colombier /*
358*206fef1cSDavid du Colombier * remove an inode
359*206fef1cSDavid du Colombier *
360*206fef1cSDavid du Colombier * N.B: ordering of iwrite and dfree is important
361*206fef1cSDavid du Colombier */
362*206fef1cSDavid du Colombier int
iremove(Icache * ic,ulong ino)363*206fef1cSDavid du Colombier iremove(Icache *ic, ulong ino)
364*206fef1cSDavid du Colombier {
365*206fef1cSDavid du Colombier Ibuf *b;
366*206fef1cSDavid du Colombier Imap *m;
367*206fef1cSDavid du Colombier
368*206fef1cSDavid du Colombier if(statson)
369*206fef1cSDavid du Colombier cfsstat.ndelete++;
370*206fef1cSDavid du Colombier m = &ic->map[ino];
371*206fef1cSDavid du Colombier
372*206fef1cSDavid du Colombier /*
373*206fef1cSDavid du Colombier * read in inode
374*206fef1cSDavid du Colombier */
375*206fef1cSDavid du Colombier b = iread(ic, ino);
376*206fef1cSDavid du Colombier if(b == 0)
377*206fef1cSDavid du Colombier return -1;
378*206fef1cSDavid du Colombier
379*206fef1cSDavid du Colombier /*
380*206fef1cSDavid du Colombier * mark it unused on disk
381*206fef1cSDavid du Colombier */
382*206fef1cSDavid du Colombier b->inode.inuse = 0;
383*206fef1cSDavid du Colombier if(iwrite(ic, b) < 0)
384*206fef1cSDavid du Colombier return -1;
385*206fef1cSDavid du Colombier
386*206fef1cSDavid du Colombier /*
387*206fef1cSDavid du Colombier * throw out it's data pages
388*206fef1cSDavid du Colombier */
389*206fef1cSDavid du Colombier dfree(ic, &b->inode.ptr);
390*206fef1cSDavid du Colombier
391*206fef1cSDavid du Colombier /*
392*206fef1cSDavid du Colombier * free the inode buffer
393*206fef1cSDavid du Colombier */
394*206fef1cSDavid du Colombier ifree(ic, b);
395*206fef1cSDavid du Colombier
396*206fef1cSDavid du Colombier /*
397*206fef1cSDavid du Colombier * make map entry least recently used
398*206fef1cSDavid du Colombier */
399*206fef1cSDavid du Colombier lruderef(&ic->mlru, m);
400*206fef1cSDavid du Colombier return 0;
401*206fef1cSDavid du Colombier }
402*206fef1cSDavid du Colombier
403*206fef1cSDavid du Colombier /*
404*206fef1cSDavid du Colombier * increment our version number
405*206fef1cSDavid du Colombier */
406*206fef1cSDavid du Colombier void
iinc(Icache * ic,Ibuf * b)407*206fef1cSDavid du Colombier iinc(Icache *ic, Ibuf *b)
408*206fef1cSDavid du Colombier {
409*206fef1cSDavid du Colombier b->inode.qid.vers++;
410*206fef1cSDavid du Colombier ic->map[b->ino].qid = b->inode.qid;
411*206fef1cSDavid du Colombier iwrite(ic, b);
412*206fef1cSDavid du Colombier }
413