xref: /plan9-contrib/sys/src/cmd/ramcfs/inode.c (revision 206fef1c8a79725587ecb1892b58204f8235c098)
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