7 Channel *getb, *putb, *syncb;
9 BufReq *freereq, *freereqlast;
16 b->fnext->fprev = b->fprev;
17 b->fprev->fnext = b->fnext;
18 b->fnext = b->fprev = nil;
27 b->fprev = bfree.fprev;
33 changedev(Buf *b, Dev *d, uvlong off)
36 b->dnext->dprev = b->dprev;
37 b->dprev->dnext = b->dnext;
44 b->dnext = &d->buf[b->off & BUFHASH];
45 b->dprev = b->dnext->dprev;
52 delayreq(BufReq req, BufReq **first, BufReq **last)
56 r = emalloc(sizeof(*r));
67 undelayreq(BufReq **first, BufReq **last)
84 b->wprev = b->wnext->wprev;
92 givebuf(BufReq req, Buf *b)
97 if(req.d == b->d && req.off == b->off){
102 l = &req.d->buf[req.off & BUFHASH];
103 for(c = l->dnext; c != l; c = c->dnext)
104 if(c->off == req.off){
106 delayreq(req, &c->next, &c->last);
113 req = undelayreq(&b->next, &b->last);
117 givebuf(undelayreq(&b->next, &b->last), b);
121 delayreq(req, &freereq, &freereqlast);
125 if(b->d != nil && b->op & BDELWRI){
126 delayreq(req, &b->next, &b->last);
133 changedev(b, req.d, req.off);
134 b->op &= ~(BWRITE|BDELWRI|BWRIM);
144 handleget(BufReq req)
146 givebuf(req, bfree.fnext);
153 b->op &= ~(BWRIM | BDELWRI);
162 changedev(b, nil, -1);
167 givebuf(undelayreq(&b->next, &b->last), b);
168 else if(freereq != nil)
169 givebuf(undelayreq(&freereq, &freereqlast), b);
173 handlesync(Channel *resp)
177 for(b = bfree.fnext; b != &bfree; b = c){
179 if(b->d != nil && b->op & BDELWRI){
197 Alt a[] = {{getb, &req, CHANRCV}, {putb, &buf, CHANRCV}, {syncb, &r, CHANRCV}, {nil, nil, CHANEND}};
219 [TSUPERBLOCK] "superblock",
231 t = va_arg(f->args, uint);
232 if(t >= nelem(typenames) || typenames[t] == nil)
233 return fmtprint(f, "??? (%d)", t);
234 return fmtstrcpy(f, typenames[t]);
242 fmtinstall('T', Tfmt);
243 b = emalloc(sizeof(*b) * nbuf);
244 bfree.fnext = bfree.fprev = &bfree;
247 getb = chancreate(sizeof(BufReq), 0);
248 putb = chancreate(sizeof(Buf *), 32);
249 syncb = chancreate(sizeof(void*), 0);
250 proccreate(bufproc, nil, mainstacksize);
254 getbuf(Dev *d, uvlong off, int type, int nodata)
270 werrstr("%s", b->error);
276 if(b->type != type && type != TDONTCARE){
277 dprint("type mismatch, dev %s, block %lld, got %T, want %T, caller %#p\n",
278 d->name, off, b->type, type, getcallerpc(&d));
279 werrstr("phase error -- type mismatch");
283 b->callerpc = getcallerpc(&d);
302 r = getthrdata()->resp;
304 memset(&b, 0, sizeof(Buf));
307 for(d = devs; d != nil; d = d->next){