Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_fixcpp/sys/src/cmd/disk/kfs/iobuf.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include	"all.h"
2
 
3
#define	DEBUG	0
4
 
5
long	niob;
6
long	nhiob;
7
Hiob	*hiob;
8
 
9
Iobuf*
10
getbuf(Device dev, long addr, int flag)
11
{
12
	Iobuf *p, *s;
13
	Hiob *hp;
14
	long h;
15
 
16
	if(DEBUG)
17
		print("getbuf %D(%ld) f=%x\n", dev, addr, flag);
18
	h = addr +
19
		dev.type*1009L +
20
		dev.ctrl*10007L +
21
		dev.unit*100003L +
22
		dev.part*1000003L;
23
	if(h < 0)
24
		h = ~h;
25
	h %= nhiob;
26
	hp = &hiob[h];
27
 
28
loop:
29
	lock(hp);
30
 
31
/*
32
 * look for it in the active list
33
 */
34
	s = hp->link;
35
	for(p=s;;) {
36
		if(p->addr == addr && !devcmp(p->dev, dev)) {
37
			if(p != s) {
38
				p->back->fore = p->fore;
39
				p->fore->back = p->back;
40
				p->fore = s;
41
				p->back = s->back;
42
				s->back = p;
43
				p->back->fore = p;
44
				hp->link = p;
45
			}
46
			unlock(hp);
47
			qlock(p);
48
			if(p->addr != addr || devcmp(p->dev, dev)) {
49
				qunlock(p);
50
				goto loop;
51
			}
52
			p->flags |= flag;
53
			cons.bhit.count++;
54
			p->iobuf = p->xiobuf;
55
			return p;
56
		}
57
		p = p->fore;
58
		if(p == s)
59
			break;
60
	}
61
	if(flag & Bprobe) {
62
		unlock(hp);
63
		return 0;
64
	}
65
 
66
/*
67
 * not found
68
 * take oldest unlocked entry in this queue
69
 */
70
xloop:
71
	p = s->back;
72
	if(!canqlock(p)) {
73
		if(p == hp->link) {
74
			unlock(hp);
75
			print("iobuf all locked\n");
76
			goto loop;
77
		}
78
		s = p;
79
		goto xloop;
80
	}
81
	/*
82
	 * its dangerous to flush the pseudo
83
	 * devices since they recursively call
84
	 * getbuf/putbuf. deadlock!
85
	 */
86
	if(p->flags & Bres) {
87
		qunlock(p);
88
		if(p == hp->link) {
89
			unlock(hp);
90
			print("iobuf all resed\n");
91
			goto loop;
92
		}
93
		s = p;
94
		goto xloop;
95
	}
96
	if(p->flags & Bmod) {
97
		unlock(hp);
98
		if(!devwrite(p->dev, p->addr, p->xiobuf))
99
			p->flags &= ~(Bimm|Bmod);
100
		qunlock(p);
101
		goto loop;
102
	}
103
	hp->link = p;
104
	p->addr = addr;
105
	p->dev = dev;
106
	p->flags = flag;
107
	unlock(hp);
108
	p->iobuf = p->xiobuf;
109
	if(flag & Bread) {
110
		if(devread(p->dev, p->addr, p->iobuf)) {
111
			p->flags = 0;
112
			p->dev = devnone;
113
			p->addr = -1;
114
			p->iobuf = (char*)-1;
115
			qunlock(p);
116
			return 0;
117
		}
118
		cons.bread.count++;
119
		return p;
120
	}
121
	cons.binit.count++;
122
	return p;
123
}
124
 
125
/*
126
 * syncblock tries to put out a block per hashline
127
 * returns 0 all done,
128
 * returns 1 if it missed something
129
 */
130
int
131
syncblock(void)
132
{
133
	Iobuf *p, *s, *q;
134
	Hiob *hp;
135
	long h;
136
	int flag;
137
 
138
	flag = 0;
139
	for(h=0; h<nhiob; h++) {
140
		q = 0;
141
		hp = &hiob[h];
142
		lock(hp);
143
		s = hp->link;
144
		for(p=s;;) {
145
			if(p->flags & Bmod) {
146
				if(q)
147
					flag = 1;	/* more than 1 mod/line */
148
				q = p;
149
			}
150
			p = p->fore;
151
			if(p == s)
152
				break;
153
		}
154
		unlock(hp);
155
		if(q) {
156
			if(!canqlock(q)) {
157
				flag = 1;		/* missed -- was locked */
158
				continue;
159
			}
160
			if(!(q->flags & Bmod)) {
161
				qunlock(q);
162
				continue;
163
			}
164
			if(!devwrite(q->dev, q->addr, q->xiobuf))
165
				q->flags &= ~(Bmod|Bimm);
166
			qunlock(q);
167
		}
168
	}
169
	return flag;
170
}
171
 
172
void
173
sync(char *reason)
174
{
175
	long i;
176
 
177
	print("sync: %s\n", reason);
178
	for(i=10*nhiob; i>0; i--)
179
		if(!syncblock())
180
			return;
181
	print("sync shorted\n");
182
}
183
 
184
void
185
putbuf(Iobuf *p)
186
{
187
	if(canqlock(p))
188
		print("buffer not locked %D(%ld)\n", p->dev, p->addr);
189
	if(p->flags & Bimm) {
190
		if(!(p->flags & Bmod))
191
			print("imm and no mod %D(%ld)\n", p->dev, p->addr);
192
		if(!devwrite(p->dev, p->addr, p->iobuf))
193
			p->flags &= ~(Bmod|Bimm);
194
	}
195
	p->iobuf = (char*)-1;
196
	qunlock(p);
197
}
198
 
199
int
200
checktag(Iobuf *p, int tag, long qpath)
201
{
202
	Tag *t;
203
 
204
	t = (Tag*)(p->iobuf+BUFSIZE);
205
	if(t->tag != tag) {
206
		if(1 || CHAT(0))
207
			print("	tag = %G; expected %G; addr = %lud\n",
208
				t->tag, tag, p->addr);
209
		return 2;
210
	}
211
	if(qpath != QPNONE) {
212
		qpath &= ~QPDIR;
213
		if(qpath != t->path) {
214
			if(qpath == (t->path&~QPDIR))	/* old bug */
215
				return 0;
216
			if(1 || CHAT(0))
217
				print("	tag/path = %lux; expected %G/%lux\n",
218
					t->path, tag, qpath);
219
			return 1;
220
		}
221
	}
222
	return 0;
223
}
224
 
225
void
226
settag(Iobuf *p, int tag, long qpath)
227
{
228
	Tag *t;
229
 
230
	t = (Tag*)(p->iobuf+BUFSIZE);
231
	t->tag = tag;
232
	if(qpath != QPNONE)
233
		t->path = qpath & ~QPDIR;
234
	p->flags |= Bmod;
235
}