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));
57 memcpy(r, &req, sizeof(*r));
72 b->wprev = b->wnext->wprev;
80 givebuf(BufReq req, Buf *b)
85 if(req.d == b->d && req.off == b->off){
92 delayreq(req, &b->next, &b->last);
97 l = &req.d->buf[req.off & BUFHASH];
98 for(c = l->dnext; c != l; c = c->dnext)
101 changedev(b, req.d, req.off);
102 b->op &= ~(BWRITE|BDELWRI|BWRIM);
112 undelayreq(Buf *b, BufReq **first, BufReq **last)
125 handleget(BufReq req)
131 l = &d->buf[req.off & BUFHASH];
132 for(b = l->dnext; b != l; b = b->dnext)
133 if(b->off == req.off){
135 delayreq(req, &b->next, &b->last);
141 if(bfree.fnext == &bfree){
142 delayreq(req, &freereq, &freereqlast);
153 b->op &= ~(BWRIM | BDELWRI);
162 changedev(b, nil, -1);
167 undelayreq(b, &b->next, &b->last);
168 else if(freereq != nil)
169 undelayreq(b, &freereq, &freereqlast);
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(ulong), 0);
250 proccreate(bufproc, nil, mainstacksize);
254 getbuf(Dev *d, uvlong off, int type, int nodata)
271 if(b->type != type && type != -1){
272 dprint("hjfs: type mismatch, dev %s, block %lld, got %T, want %T, caller %#p\n", d->name, off, b->type, type, getcallerpc(&d));
273 werrstr("phase error -- type mismatch");
278 werrstr("%s", b->error);
282 b->callerpc = getcallerpc(&d);
301 r = getthrdata()->resp;
303 memset(&b, 0, sizeof(Buf));
306 for(d = devs; d != nil; d = d->next){