]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/cwfs/iobuf.c
cwfs: remove old some assert() debugging
[plan9front.git] / sys / src / cmd / cwfs / iobuf.c
1 #include        "all.h"
2 #include        "io.h"
3
4 extern  uint nhiob;
5 extern  Hiob *hiob;
6
7 Iobuf*
8 getbuf(Device *d, Off addr, int flag)
9 {
10         Iobuf *p, *s;
11         Hiob *hp;
12         Off h;
13
14         if(chatty > 1)
15                 fprint(2, "getbuf %Z(%lld) f=%x\n", d, (Wideoff)addr, flag);
16         h = addr + (Off)(uintptr)d*1009;
17         if(h < 0)
18                 h = ~h;
19         h %= nhiob;
20         hp = &hiob[h];
21
22 loop:
23         lock(hp);
24
25 /*
26  * look for it in the active list
27  */
28         s = hp->link;
29         for(p=s;;) {
30                 if(p->addr == addr && p->dev == d) {
31                         if(p != s) {
32                                 p->back->fore = p->fore;
33                                 p->fore->back = p->back;
34                                 p->fore = s;
35                                 p->back = s->back;
36                                 s->back = p;
37                                 p->back->fore = p;
38                                 hp->link = p;
39                         }
40                         unlock(hp);
41                         qlock(p);
42                         if(p->addr != addr || p->dev != d || iobufmap(p) == 0) {
43                                 qunlock(p);
44                                 goto loop;
45                         }
46                         p->flags |= flag;
47                         return p;
48                 }
49                 p = p->fore;
50                 if(p == s)
51                         break;
52         }
53         if(flag & Bprobe) {
54                 unlock(hp);
55                 return 0;
56         }
57
58 /*
59  * not found
60  * take oldest unlocked entry in this queue
61  */
62 xloop:
63         p = s->back;
64         if(!canqlock(p)) {
65                 if(p == hp->link) {
66                         unlock(hp);
67                         fprint(2, "iobuf all locked\n");
68                         goto loop;
69                 }
70                 s = p;
71                 goto xloop;
72         }
73
74         /*
75          * its dangerous to flush the pseudo
76          * devices since they recursively call
77          * getbuf/putbuf. deadlock!
78          */
79         if(p->flags & Bres) {
80                 qunlock(p);
81                 if(p == hp->link) {
82                         unlock(hp);
83                         fprint(2, "iobuf all reserved\n");
84                         goto loop;
85                 }
86                 s = p;
87                 goto xloop;
88         }
89         if(p->flags & Bmod) {
90                 unlock(hp);
91                 if(iobufmap(p)) {
92                         if(!devwrite(p->dev, p->addr, p->iobuf))
93                                 p->flags &= ~(Bimm|Bmod);
94                         iobufunmap(p);
95                 }
96                 qunlock(p);
97                 goto loop;
98         }
99         hp->link = p;
100         p->addr = addr;
101         p->dev = d;
102         p->flags = flag;
103         unlock(hp);
104         if(iobufmap(p))
105                 if(flag & Brd) {
106                         if(!devread(p->dev, p->addr, p->iobuf))
107                                 return p;
108                         iobufunmap(p);
109                 } else
110                         return p;
111         else
112                 fprint(2, "iobuf cant map buffer %Z(%lld)\n", p->dev, (Wideoff)p->addr);
113         p->flags = 0;
114         p->dev = devnone;
115         p->addr = -1;
116         qunlock(p);
117         return 0;
118 }
119
120 /*
121  * syncblock tries to put out a block per hashline
122  * returns 0 all done,
123  * returns 1 if it missed something
124  */
125 int
126 syncblock(void)
127 {
128         Iobuf *p, *s, *q;
129         Hiob *hp;
130         long h;
131         int flag;
132
133         flag = 0;
134         for(h=0; h<nhiob; h++) {
135                 q = 0;
136                 hp = &hiob[h];
137                 lock(hp);
138                 s = hp->link;
139                 for(p=s;;) {
140                         if(p->flags & Bmod) {
141                                 if(q)
142                                         flag = 1;       /* more than 1 mod/line */
143                                 q = p;
144                         }
145                         p = p->fore;
146                         if(p == s)
147                                 break;
148                 }
149                 unlock(hp);
150                 if(q) {
151                         if(!canqlock(q)) {
152                                 flag = 1;               /* missed -- was locked */
153                                 continue;
154                         }
155                         if(!(q->flags & Bmod)) {
156                                 qunlock(q);
157                                 continue;
158                         }
159                         if(iobufmap(q)) {
160                                 if(!devwrite(q->dev, q->addr, q->iobuf))
161                                         q->flags &= ~(Bmod|Bimm);
162                                 iobufunmap(q);
163                         } else
164                                 flag = 1;
165                         qunlock(q);
166                 }
167         }
168         return flag;
169 }
170
171 void
172 sync(char *reason)
173 {
174         long i;
175
176         if(chatty)
177                 fprint(2, "sync: %s\n", reason);
178         for(i=10*nhiob; i>0; i--)
179                 if(!syncblock())
180                         return;
181 }
182
183 void
184 putbuf(Iobuf *p)
185 {
186
187         if(canqlock(p))
188                 fprint(2, "buffer not locked %Z(%lld)\n", p->dev, (Wideoff)p->addr);
189         if(p->flags & Bimm) {
190                 if(!(p->flags & Bmod))
191                         fprint(2, "imm and no mod %Z(%lld)\n",
192                                 p->dev, (Wideoff)p->addr);
193                 if(!devwrite(p->dev, p->addr, p->iobuf))
194                         p->flags &= ~(Bmod|Bimm);
195         }
196         iobufunmap(p);
197         qunlock(p);
198 }
199
200 int
201 checktag(Iobuf *p, int tag, Off qpath)
202 {
203         Tag *t;
204         uintptr pc;
205
206         t = (Tag*)(p->iobuf+BUFSIZE);
207         if(tag != t->tag || qpath != QPNONE && qpath != t->path){
208                 pc = getcallerpc(&p);
209
210                 if(qpath == QPNONE){
211                         fprint(2, "checktag pc=%p %Z(%llux) tag/path=%G/%llud; expected %G\n",
212                                 pc, p->dev, (Wideoff)p->addr, t->tag, (Wideoff)t->path, tag);
213                 } else {
214                         fprint(2, "checktag pc=%p %Z(%llux) tag/path=%G/%llud; expected %G/%llud\n",
215                                 pc, p->dev, (Wideoff)p->addr, t->tag, (Wideoff)t->path, tag, (Wideoff)qpath);
216                 }
217                 return 1;
218         }       
219         return 0;
220 }
221
222 void
223 settag(Iobuf *p, int tag, Off qpath)
224 {
225         Tag *t;
226
227         t = (Tag*)(p->iobuf+BUFSIZE);
228         t->tag = tag;
229         if(qpath != QPNONE)
230                 t->path = qpath;
231         p->flags |= Bmod;
232 }
233
234 int
235 qlmatch(QLock *q1, QLock *q2)
236 {
237
238         return q1 == q2;
239 }
240
241 int
242 iobufql(QLock *q)
243 {
244         Iobuf *p, *s;
245         Hiob *hp;
246         long h;
247
248         for(h=0; h<nhiob; h++) {
249                 hp = &hiob[h];
250                 lock(hp);
251                 s = hp->link;
252                 for(p=s;;) {
253                         if(qlmatch(q, p)) {
254                                 unlock(hp);
255                                 return 1;
256                         }
257                         p = p->fore;
258                         if(p == s)
259                                 break;
260                 }
261                 unlock(hp);
262         }
263         return 0;
264 }