History

kern: update qio and devmnt, remove mount cache stub

cinap_lenrek committed 10 years ago

Commit 3b886fc1 parent 278bcb76 files · +475 −764Browse files

Unified · Split

6 files
  1. kern/Makefile +0 −1
  2. kern/allocb.c +21 −55
  3. kern/cache.c +0 −46
  4. kern/devmnt.c +207 −288
  5. kern/fns.h +2 −10
  6. kern/qio.c +245 −364
kern/Makefile+0−1
@@ -5,7 +5,6 @@ LIB=libkern.a · 4 unmodified lines
55 OFILES=\
66 alloc.$O\
77 allocb.$O\
8− cache.$O\
98 chan.$O\
109 data.$O\
1110 dev.$O\
kern/allocb.c+21−55
@@ -7,27 +7,23 @@ · 6 unmodified lines
77 enum
88 {
99 Hdrspc = 64, /* leave room for high-level headers */
10+ Tlrspc = 16, /* extra room at the end for pad/crc/mac */
1011 Bdead = 0x51494F42, /* "QIOB" */
1112 };
1213
13−struct
14−{
15− Lock lk;
16− ulong bytes;
17−} ialloc;
18−
1914 static Block*
2015 _allocb(int size)
2116 {
2217 Block *b;
2318 uintptr addr;
2419
20+ size += Tlrspc;
2521 if((b = mallocz(sizeof(Block)+size+Hdrspc, 0)) == nil)
2622 return nil;
2723
2824 b->next = nil;
2925 b->list = nil;
30− b->free = 0;
26+ b->free = nil;
3127 b->flag = 0;
3228
3329 /* align start of data portion by rounding up */
@@ -36,9 +32,9 @@ _allocb(int size) · 2 unmodified lines
3632 b->base = (uchar*)addr;
3733
3834 /* align end of data portion by rounding down */
39− b->lim = ((uchar*)b) + sizeof(Block)+size+Hdrspc;
40− addr = (uintptr)(b->lim);
41− addr = addr & ~(BLOCKALIGN-1);
35+ b->lim = (uchar*)b + sizeof(Block)+size+Hdrspc;
36+ addr = (uintptr)b->lim;
37+ addr &= ~(BLOCKALIGN-1);
4238 b->lim = (uchar*)addr;
4339
4440 /* leave sluff at beginning for added headers */
@@ -57,13 +53,11 @@ allocb(int size) · 12 unmodified lines
5753
5854 /*
5955 * Check in a process and wait until successful.
60− * Can still error out of here, though.
6156 */
6257 if(up == nil)
63− panic("allocb without up: %p\n", getcallerpc(&size));
64− if((b = _allocb(size)) == nil){
65− panic("allocb: no memory for %d bytes\n", size);
66− }
58+ panic("allocb without up: %#p", getcallerpc(&size));
59+ if((b = _allocb(size)) == nil)
60+ panic("allocb: no memory for %d bytes", size);
6761 setmalloctag(b, getcallerpc(&size));
6862
6963 return b;
@@ -73,28 +67,12 @@ Block* · 3 unmodified lines
7367 iallocb(int size)
7468 {
7569 Block *b;
76− static int m1, m2;
7770
78− if(ialloc.bytes > conf.ialloc){
79− if((m1++%10000)==0)
80− print("iallocb: limited %lud/%lud\n",
81− ialloc.bytes, conf.ialloc);
82− return 0;
83− }
84−
85− if((b = _allocb(size)) == nil){
86− if((m2++%10000)==0)
87− print("iallocb: no memory %lud/%lud\n",
88− ialloc.bytes, conf.ialloc);
89− return nil;
90− }
71+ if((b = _allocb(size)) == nil)
72+ panic("iallocb: no memory for %d bytes", size);
9173 setmalloctag(b, getcallerpc(&size));
9274 b->flag = BINTR;
9375
94− ilock(&ialloc.lk);
95− ialloc.bytes += b->lim - b->base;
96− iunlock(&ialloc.lk);
97−
9876 return b;
9977 }
10078
@@ -110,15 +88,10 @@ freeb(Block *b) · 9 unmodified lines
11088 * drivers which perform non cache coherent DMA manage their own buffer
11189 * pool of uncached buffers and provide their own free routine.
11290 */
113− if(b->free) {
91+ if(b->free != nil) {
11492 b->free(b);
11593 return;
11694 }
117− if(b->flag & BINTR) {
118− ilock(&ialloc.lk);
119− ialloc.bytes -= b->lim - b->base;
120− iunlock(&ialloc.lk);
121− }
12295
12396 /* poison the block in case someone is still holding onto it */
12497 b->next = dead;
@@ -136,30 +109,23 @@ checkb(Block *b, char *msg) · 11 unmodified lines
136109 void *dead = (void*)Bdead;
137110
138111 if(b == dead)
139− panic("checkb b %s %lux", msg, b);
112+ panic("checkb b %s %#p", msg, b);
140113 if(b->base == dead || b->lim == dead || b->next == dead
141114 || b->rp == dead || b->wp == dead){
142− print("checkb: base 0x%8.8luX lim 0x%8.8luX next 0x%8.8luX\n",
115+ print("checkb: base %#p lim %#p next %#p\n",
143116 b->base, b->lim, b->next);
144− print("checkb: rp 0x%8.8luX wp 0x%8.8luX\n", b->rp, b->wp);
145− panic("checkb dead: %s\n", msg);
117+ print("checkb: rp %#p wp %#p\n", b->rp, b->wp);
118+ panic("checkb dead: %s", msg);
146119 }
147120
148121 if(b->base > b->lim)
149− panic("checkb 0 %s %lux %lux", msg, b->base, b->lim);
122+ panic("checkb 0 %s %#p %#p", msg, b->base, b->lim);
150123 if(b->rp < b->base)
151− panic("checkb 1 %s %lux %lux", msg, b->base, b->rp);
124+ panic("checkb 1 %s %#p %#p", msg, b->base, b->rp);
152125 if(b->wp < b->base)
153− panic("checkb 2 %s %lux %lux", msg, b->base, b->wp);
126+ panic("checkb 2 %s %#p %#p", msg, b->base, b->wp);
154127 if(b->rp > b->lim)
155− panic("checkb 3 %s %lux %lux", msg, b->rp, b->lim);
128+ panic("checkb 3 %s %#p %#p", msg, b->rp, b->lim);
156129 if(b->wp > b->lim)
157− panic("checkb 4 %s %lux %lux", msg, b->wp, b->lim);
158−
159−}
160−
161−void
162−iallocsummary(void)
163−{
164− print("ialloc %lud/%lud\n", ialloc.bytes, conf.ialloc);
130+ panic("checkb 4 %s %#p %#p", msg, b->wp, b->lim);
165131 }
kern/cache.c+0−46
@@ -1,46 +0,0 @@
1−#include "u.h"
2−#include "lib.h"
3−#include "dat.h"
4−#include "fns.h"
5−#include "error.h"
6−
7−
8−void
9−cinit(void)
10−{
11−}
12−
13−void
14−copen(Chan *c)
15−{
16− USED(c);
17−}
18−
19−int
20−cread(Chan *c, uchar *buf, int len, vlong off)
21−{
22− USED(c);
23− USED(buf);
24− USED(len);
25− USED(off);
26−
27− return 0;
28−}
29−
30−void
31−cupdate(Chan *c, uchar *buf, int len, vlong off)
32−{
33− USED(c);
34− USED(buf);
35− USED(len);
36− USED(off);
37−}
38−
39−void
40−cwrite(Chan* c, uchar *buf, int len, vlong off)
41−{
42− USED(c);
43− USED(buf);
44− USED(len);
45− USED(off);
46−}
kern/devmnt.c+207−288
@@ -24,15 +24,10 @@ struct Mntrpc · 23 unmodified lines
2424 Fcall request; /* Outgoing file system protocol message */
2525 Fcall reply; /* Incoming reply */
2626 Mnt* m; /* Mount device during rpc */
27− Rendez r; /* Place to hang out */
28− uchar* rpc; /* I/O Data buffer */
29− uint rpclen; /* len of buffer */
30− Block *b; /* reply blocks */
31− char done; /* Rpc completed */
32− uvlong stime; /* start time for mnt statistics */
33− ulong reqlen; /* request length for mnt statistics */
34− ulong replen; /* reply length for mnt statistics */
27+ Rendez* z; /* Place to hang out */
28+ Block* b; /* reply blocks */
3529 Mntrpc* flushed; /* message this one flushes */
30+ char done; /* Rpc completed */
3631 };
3732
3833 enum
@@ -42,42 +37,38 @@ enum · 3 unmodified lines
4237 NMASK = (64*1024)>>TAGSHIFT,
4338 };
4439
45−struct Mntalloc
40+static struct Mntalloc
4641 {
47− Lock lk;
42+ Lock lk;
4843 Mnt* list; /* Mount devices in use */
4944 Mnt* mntfree; /* Free list */
5045 Mntrpc* rpcfree;
51− int nrpcfree;
52− int nrpcused;
46+ ulong nrpcfree;
47+ ulong nrpcused;
5348 ulong id;
5449 ulong tagmask[NMASK];
55−}mntalloc;
56−
57−void mattach(Mnt*, Chan*, char*);
58−Mnt* mntchk(Chan*);
59−void mntdirfix(uchar*, Chan*);
60−Mntrpc* mntflushalloc(Mntrpc*, ulong);
61−void mntflushfree(Mnt*, Mntrpc*);
62−void mntfree(Mntrpc*);
63−void mntgate(Mnt*);
64−void mntpntfree(Mnt*);
65−void mntqrm(Mnt*, Mntrpc*);
66−Mntrpc* mntralloc(Chan*, ulong);
67−long mntrdwr(int, Chan*, void*, long, vlong);
68−int mntrpcread(Mnt*, Mntrpc*);
69−void mountio(Mnt*, Mntrpc*);
70−void mountmux(Mnt*, Mntrpc*);
71−void mountrpc(Mnt*, Mntrpc*);
72−int rpcattn(void*);
73−Chan* mntchan(void);
50+} mntalloc;
51+
52+static Chan* mntchan(void);
53+static Mnt* mntchk(Chan*);
54+static void mntdirfix(uchar*, Chan*);
55+static Mntrpc* mntflushalloc(Mntrpc*);
56+static Mntrpc* mntflushfree(Mnt*, Mntrpc*);
57+static void mntfree(Mntrpc*);
58+static void mntgate(Mnt*);
59+static void mntqrm(Mnt*, Mntrpc*);
60+static Mntrpc* mntralloc(Chan*);
61+static long mntrdwr(int, Chan*, void*, long, vlong);
62+static int mntrpcread(Mnt*, Mntrpc*);
63+static void mountio(Mnt*, Mntrpc*);
64+static void mountmux(Mnt*, Mntrpc*);
65+static void mountrpc(Mnt*, Mntrpc*);
66+static int rpcattn(void*);
7467
7568 char Esbadstat[] = "invalid directory entry received from server";
76−char Enoversion[] = "version not established for mount channel";
69+char Enoversion[] = "version not established for mount channel";
7770
7871
79−void (*mntstats)(int, Chan*, uvlong, ulong);
80−
8172 static void
8273 mntreset(void)
8374 {
@@ -87,20 +78,19 @@ mntreset(void) · 3 unmodified lines
8778 fmtinstall('F', fcallfmt);
8879 fmtinstall('D', dirfmt);
8980 /* We can't install %M since eipfmt does and is used in the kernel [sape] */
90−
91− cinit();
9281 }
9382
9483 /*
9584 * Version is not multiplexed: message sent only once per connection.
9685 */
97−long
86+int
9887 mntversion(Chan *c, char *version, int msize, int returnlen)
9988 {
10089 Fcall f;
10190 uchar *msg;
10291 Mnt *m;
10392 char *v;
93+ Queue *q;
10494 long k, l;
10595 uvlong oo;
10696 char buf[128];
@@ -167,7 +157,6 @@ mntversion(Chan *c, char *version, int msize, int returnlen) · 60 unmodified lines
167157 unlock(&c->ref.lk);
168158
169159 l = devtab[c->type]->write(c, msg, k, oo);
170−
171160 if(l < k){
172161 lock(&c->ref.lk);
173162 c->offset -= k - l;
@@ -176,13 +165,14 @@ mntversion(Chan *c, char *version, int msize, int returnlen) · 2 unmodified lines
176165 }
177166
178167 /* message sent; receive and decode reply */
179− k = devtab[c->type]->read(c, msg, 8192+IOHDRSZ, c->offset);
180− if(k <= 0)
181− error("EOF receiving fversion reply");
182−
183− lock(&c->ref.lk);
184− c->offset += k;
185− unlock(&c->ref.lk);
168+ for(k = 0; k < BIT32SZ || (k < GBIT32(msg) && k < 8192+IOHDRSZ); k += l){
169+ l = devtab[c->type]->read(c, msg+k, 8192+IOHDRSZ-k, c->offset);
170+ if(l <= 0)
171+ error("EOF receiving fversion reply");
172+ lock(&c->ref.lk);
173+ c->offset += l;
174+ unlock(&c->ref.lk);
175+ }
186176
187177 l = convM2S(msg, k, &f);
188178 if(l != k)
@@ -199,40 +189,49 @@ mntversion(Chan *c, char *version, int msize, int returnlen) · 10 unmodified lines
199189 k = strlen(f.version);
200190 if(strncmp(f.version, v, k) != 0)
201191 error("bad 9P version returned from server");
192+ if(returnlen > 0 && returnlen < k)
193+ error(Eshort);
194+
195+ v = nil;
196+ kstrdup(&v, f.version);
197+ q = qopen(10*MAXRPC, 0, nil, nil);
198+ if(q == nil){
199+ free(v);
200+ exhausted("mount queues");
201+ }
202202
203203 /* now build Mnt associated with this connection */
204204 lock(&mntalloc.lk);
205205 m = mntalloc.mntfree;
206− if(m != 0)
206+ if(m != nil)
207207 mntalloc.mntfree = m->list;
208208 else {
209+ unlock(&mntalloc.lk);
209210 m = malloc(sizeof(Mnt));
210− if(m == 0) {
211− unlock(&mntalloc.lk);
211+ if(m == nil) {
212+ qfree(q);
213+ free(v);
212214 exhausted("mount devices");
213215 }
216+ lock(&mntalloc.lk);
214217 }
215218 m->list = mntalloc.list;
216219 mntalloc.list = m;
217− m->version = nil;
218− kstrdup(&m->version, f.version);
220+ m->version = v;
219221 m->id = mntalloc.id++;
220− m->q = qopen(10*MAXRPC, 0, 0, nil);
222+ m->q = q;
221223 m->msize = f.msize;
222224 unlock(&mntalloc.lk);
223225
224− if(returnlen > 0){
225− if(returnlen < k)
226− error(Eshort);
227− memmove(version, f.version, k);
228− }
226+ if(returnlen > 0)
227+ memmove(version, f.version, k); /* length was checked above */
229228
230229 poperror(); /* msg */
231230 free(msg);
232231
233232 lock(&m->lk);
234− m->queue = 0;
235− m->rip = 0;
233+ m->queue = nil;
234+ m->rip = nil;
236235
237236 c->flag |= CMSG;
238237 c->mux = m;
@@ -252,9 +251,8 @@ mntauth(Chan *c, char *spec) · 13 unmodified lines
252251 Mntrpc *r;
253252
254253 m = c->mux;
255−
256254 if(m == nil){
257− mntversion(c, VERSION9P, MAXRPC, 0);
255+ mntversion(c, nil, 0, 0);
258256 m = c->mux;
259257 if(m == nil)
260258 error(Enoversion);
@@ -269,8 +267,7 @@ mntauth(Chan *c, char *spec) · 8 unmodified lines
269267 nexterror();
270268 }
271269
272− r = mntralloc(0, m->msize);
273−
270+ r = mntralloc(c);
274271 if(waserror()) {
275272 mntfree(r);
276273 nexterror();
@@ -287,6 +284,7 @@ mntauth(Chan *c, char *spec) · 10 unmodified lines
287284 incref(&m->c->ref);
288285 c->mqid = c->qid;
289286 c->mode = ORDWR;
287+ c->iounit = m->msize-IOHDRSZ;
290288
291289 poperror(); /* r */
292290 mntfree(r);
@@ -297,24 +295,13 @@ mntauth(Chan *c, char *spec) · 4 unmodified lines
297295
298296 }
299297
300−static Chan*
301−mntattach(char *muxattach)
298+Chan*
299+mntattach(Chan *c, Chan *ac, char *spec, int flags)
302300 {
303301 Mnt *m;
304− Chan *c;
305302 Mntrpc *r;
306− struct bogus{
307− Chan *chan;
308− Chan *authchan;
309− char *spec;
310− int flags;
311− }bogus;
312−
313− bogus = *((struct bogus *)muxattach);
314− c = bogus.chan;
315303
316304 m = c->mux;
317−
318305 if(m == nil){
319306 mntversion(c, nil, 0, 0);
320307 m = c->mux;
@@ -331,21 +318,19 @@ mntattach(char *muxattach) · 10 unmodified lines
331318 nexterror();
332319 }
333320
334− r = mntralloc(0, m->msize);
335−
321+ r = mntralloc(c);
336322 if(waserror()) {
337323 mntfree(r);
338324 nexterror();
339325 }
340−
341326 r->request.type = Tattach;
342327 r->request.fid = c->fid;
343− if(bogus.authchan == nil)
328+ if(ac == nil)
344329 r->request.afid = NOFID;
345330 else
346− r->request.afid = bogus.authchan->fid;
331+ r->request.afid = ac->fid;
347332 r->request.uname = up->user;
348− r->request.aname = bogus.spec;
333+ r->request.aname = spec;
349334 mountrpc(m, r);
350335
351336 c->qid = r->reply.qid;
@@ -358,12 +343,20 @@ mntattach(char *muxattach) · 6 unmodified lines
358343
359344 poperror(); /* c */
360345
361− if(bogus.flags&MCACHE)
346+ if(flags&MCACHE)
362347 c->flag |= CCACHE;
363348 return c;
364349 }
365350
366−Chan*
351+static Chan*
352+noattach(char *s)
353+{
354+ USED(s);
355+ error(Enoattach);
356+ return nil;
357+}
358+
359+static Chan*
367360 mntchan(void)
368361 {
369362 Chan *c;
@@ -373,7 +366,7 @@ mntchan(void) · 3 unmodified lines
373366 c->dev = mntalloc.id++;
374367 unlock(&mntalloc.lk);
375368
376− if(c->mchan)
369+ if(c->mchan != nil)
377370 panic("mntchan non-zero %p", c->mchan);
378371 return c;
379372 }
@@ -401,7 +394,7 @@ mntwalk(Chan *c, Chan *nc, char **name, int nname) · 21 unmodified lines
401394
402395 alloc = 0;
403396 m = mntchk(c);
404− r = mntralloc(c, m->msize);
397+ r = mntralloc(c);
405398 if(nc == nil){
406399 nc = devclone(c);
407400 /*
@@ -409,6 +402,7 @@ mntwalk(Chan *c, Chan *nc, char **name, int nname) · 1 unmodified line
409402 * Therefore set type to 0 for now; rootclose is known to be safe.
410403 */
411404 nc->type = 0;
405+ nc->flag |= (c->flag & CCACHE);
412406 alloc = 1;
413407 }
414408 wq->clone = nc;
@@ -468,7 +462,7 @@ mntstat(Chan *c, uchar *dp, int n) · 53 unmodified lines
468462 if(n < BIT16SZ)
469463 error(Eshortstat);
470464 m = mntchk(c);
471− r = mntralloc(c, m->msize);
465+ r = mntralloc(c);
472466 if(waserror()) {
473467 mntfree(r);
474468 nexterror();
@@ -477,28 +471,9 @@ mntstat(Chan *c, uchar *dp, int n) · 2 unmodified lines
477471 r->request.fid = c->fid;
478472 mountrpc(m, r);
479473
480−/* r->reply.nstat is 16 bits
481− if(r->reply.nstat >= 1<<16)
482− error("returned stat buffer count too large");
483−*/
484−
485474 if(r->reply.nstat > n){
486− /*
487− * 12/31/2002 RSC
488− *
489− * This should be nstat-2, which is the first two
490− * bytes of the stat buffer. But dirstat and dirfstat
491− * depended on getting the full nstat (they didn't
492− * add BIT16SZ themselves). I fixed dirstat and dirfstat
493− * but am leaving this unchanged for now. After a
494− * few months, once enough of the relevant binaries
495− * have been recompiled for other reasons, we can
496− * change this to nstat-2. Devstat gets this right
497− * (via convD2M).
498− */
499− /* doesn't fit; just patch the count and return */
500− PBIT16((uchar*)dp, r->reply.nstat);
501475 n = BIT16SZ;
476+ PBIT16((uchar*)dp, r->reply.nstat-2);
502477 }else{
503478 n = r->reply.nstat;
504479 memmove(dp, r->reply.stat, n);
@@ -517,7 +492,7 @@ mntopencreate(int type, Chan *c, char *name, int omode, ulong perm) · 12 unmodified lines
517492 Mntrpc *r;
518493
519494 m = mntchk(c);
520− r = mntralloc(c, m->msize);
495+ r = mntralloc(c);
521496 if(waserror()) {
522497 mntfree(r);
523498 nexterror();
@@ -541,9 +516,6 @@ mntopencreate(int type, Chan *c, char *name, int omode, ulong perm) · 17 unmodified lines
541516 poperror();
542517 mntfree(r);
543518
544− if(c->flag & CCACHE)
545− copen(c);
546−
547519 return c;
548520 }
549521
@@ -566,12 +538,11 @@ mntclunk(Chan *c, int t) · 16 unmodified lines
566538 Mntrpc *r;
567539
568540 m = mntchk(c);
569− r = mntralloc(c, m->msize);
570− if(waserror()){
541+ r = mntralloc(c);
542+ if(waserror()) {
571543 mntfree(r);
572544 nexterror();
573545 }
574−
575546 r->request.type = t;
576547 r->request.fid = c->fid;
577548 mountrpc(m, r);
@@ -582,27 +553,22 @@ mntclunk(Chan *c, int t) · 4 unmodified lines
582553 void
583554 muxclose(Mnt *m)
584555 {
585− Mntrpc *q, *r;
556+ Mnt *f, **l;
557+ Mntrpc *r;
586558
587− for(q = m->queue; q; q = r) {
588− r = q->list;
589− mntfree(q);
559+ while((r = m->queue) != nil){
560+ m->queue = r->list;
561+ mntfree(r);
590562 }
591563 m->id = 0;
592564 free(m->version);
593565 m->version = nil;
594− mntpntfree(m);
595−}
596−
597−void
598−mntpntfree(Mnt *m)
599−{
600− Mnt *f, **l;
601− Queue *q;
566+ qfree(m->q);
567+ m->q = nil;
602568
603569 lock(&mntalloc.lk);
604570 l = &mntalloc.list;
605− for(f = *l; f; f = f->list) {
571+ for(f = *l; f != nil; f = f->list) {
606572 if(f == m) {
607573 *l = m->list;
608574 break;
@@ -611,10 +577,7 @@ mntpntfree(Mnt *m) · 2 unmodified lines
611577 }
612578 m->list = mntalloc.mntfree;
613579 mntalloc.mntfree = m;
614− q = m->q;
615580 unlock(&mntalloc.lk);
616−
617− qfree(q);
618581 }
619582
620583 static void
@@ -636,7 +599,7 @@ mntwstat(Chan *c, uchar *dp, int n) · 15 unmodified lines
636599 Mntrpc *r;
637600
638601 m = mntchk(c);
639− r = mntralloc(c, m->msize);
602+ r = mntralloc(c);
640603 if(waserror()) {
641604 mntfree(r);
642605 nexterror();
@@ -655,32 +618,11 @@ static long · 12 unmodified lines
655618 mntread(Chan *c, void *buf, long n, vlong off)
656619 {
657620 uchar *p, *e;
658− int nc, cache, isdir, dirlen;
659−
660− isdir = 0;
661− cache = c->flag & CCACHE;
662− if(c->qid.type & QTDIR) {
663− cache = 0;
664− isdir = 1;
665− }
621+ int dirlen;
666622
667623 p = buf;
668− if(cache) {
669− nc = cread(c, buf, n, off);
670− if(nc > 0) {
671− n -= nc;
672− if(n == 0)
673− return nc;
674− p += nc;
675− off += nc;
676− }
677− n = mntrdwr(Tread, c, p, n, off);
678− cupdate(c, p, n, off);
679− return n + nc;
680− }
681−
682− n = mntrdwr(Tread, c, buf, n, off);
683− if(isdir) {
624+ n = mntrdwr(Tread, c, p, n, off);
625+ if(c->qid.type & QTDIR) {
684626 for(e = &p[n]; p+BIT16SZ < e; p += dirlen){
685627 dirlen = BIT16SZ+GBIT16(p);
686628 if(p+dirlen > e)
@@ -700,23 +642,24 @@ mntwrite(Chan *c, void *buf, long n, vlong off) · 13 unmodified lines
700642 return mntrdwr(Twrite, c, buf, n, off);
701643 }
702644
703−long
645+static long
704646 mntrdwr(int type, Chan *c, void *buf, long n, vlong off)
705647 {
706648 Mnt *m;
707649 Mntrpc *r;
708650 char *uba;
709− int cache;
710651 ulong cnt, nr, nreq;
711652
712653 m = mntchk(c);
713654 uba = buf;
714655 cnt = 0;
715− cache = c->flag & CCACHE;
716− if(c->qid.type & QTDIR)
717− cache = 0;
656+
718657 for(;;) {
719− r = mntralloc(c, m->msize);
658+ nreq = n;
659+ if(nreq > c->iounit)
660+ nreq = c->iounit;
661+
662+ r = mntralloc(c);
720663 if(waserror()) {
721664 mntfree(r);
722665 nexterror();
@@ -725,23 +668,16 @@ mntrdwr(int type, Chan *c, void *buf, long n, vlong off) · 2 unmodified lines
725668 r->request.fid = c->fid;
726669 r->request.offset = off;
727670 r->request.data = uba;
728− nr = n;
729− if(nr > m->msize-IOHDRSZ)
730− nr = m->msize-IOHDRSZ;
731− r->request.count = nr;
671+ r->request.count = nreq;
732672 mountrpc(m, r);
733− nreq = r->request.count;
734673 nr = r->reply.count;
735674 if(nr > nreq)
736675 nr = nreq;
737−
738676 if(type == Tread)
739− r->b = bl2mem((uchar*)uba, r->b, nr);
740− else if(cache)
741− cwrite(c, (uchar*)uba, nr, off);
742−
743− poperror();
677+ nr = readblist(r->b, (uchar*)uba, nr, 0);
744678 mntfree(r);
679+ poperror();
680+
745681 off += nr;
746682 uba += nr;
747683 cnt += nr;
@@ -752,10 +688,9 @@ mntrdwr(int type, Chan *c, void *buf, long n, vlong off) · 4 unmodified lines
752688 return cnt;
753689 }
754690
755−void
691+static void
756692 mountrpc(Mnt *m, Mntrpc *r)
757693 {
758− char *sn, *cn;
759694 int t;
760695
761696 r->reply.tag = 0;
@@ -772,60 +707,70 @@ mountrpc(Mnt *m, Mntrpc *r) · 10 unmodified lines
772707 default:
773708 if(t == r->request.type+1)
774709 break;
775− sn = "?";
776− if(m->c->name != nil)
777− sn = m->c->name->s;
778− cn = "?";
779− if(r->c != nil && r->c->name != nil)
780− cn = r->c->name->s;
781− print("mnt: proc %lud: mismatch from %s %s rep 0x%lux tag %d fid %d T%d R%d rp %d\n",
782− up->pid, sn, cn,
710+ print("mnt: proc %s %lud: mismatch from %s %s rep %#p tag %d fid %d T%d R%d rp %d\n",
711+ up->text, up->pid, chanpath(m->c), chanpath(r->c),
783712 r, r->request.tag, r->request.fid, r->request.type,
784713 r->reply.type, r->reply.tag);
785714 error(Emountrpc);
786715 }
787716 }
788717
789−void
718+static void
790719 mountio(Mnt *m, Mntrpc *r)
791720 {
721+ Block *b;
792722 int n;
793723
794724 while(waserror()) {
795725 if(m->rip == up)
796726 mntgate(m);
797− if(strcmp(up->errstr, Eintr) != 0){
798− mntflushfree(m, r);
727+ if(strcmp(up->errstr, Eintr) != 0 || waserror()){
728+ r = mntflushfree(m, r);
729+ switch(r->request.type){
730+ case Tremove:
731+ case Tclunk:
732+ /* botch, abandon fid */
733+ if(strcmp(up->errstr, Ehungup) != 0)
734+ r->c->fid = 0;
735+ }
799736 nexterror();
800737 }
801− r = mntflushalloc(r, m->msize);
738+ r = mntflushalloc(r);
739+ poperror();
802740 }
803741
804742 lock(&m->lk);
743+ r->z = &up->sleep;
805744 r->m = m;
806745 r->list = m->queue;
807746 m->queue = r;
808747 unlock(&m->lk);
809748
810749 /* Transmit a file system rpc */
811− if(m->msize == 0)
812− panic("msize");
813− n = convS2M(&r->request, r->rpc, m->msize);
814− if(n < 0)
815− panic("bad message type in mountio");
816− if(devtab[m->c->type]->write(m->c, r->rpc, n, 0) != n)
750+ n = sizeS2M(&r->request);
751+ b = allocb(n);
752+ if(waserror()){
753+ freeb(b);
754+ nexterror();
755+ }
756+ n = convS2M(&r->request, b->wp, n);
757+ if(n <= 0 || n > m->msize) {
758+ print("mountio: proc %s %lud: convS2M returned %d for tag %d fid %d T%d\n",
759+ up->text, up->pid, n, r->request.tag, r->request.fid, r->request.type);
817760 error(Emountrpc);
818− r->stime = fastticks(nil);
819− r->reqlen = n;
761+ }
762+ b->wp += n;
763+ poperror();
764+ devtab[m->c->type]->bwrite(m->c, b, 0);
820765
821766 /* Gate readers onto the mount point one at a time */
822767 for(;;) {
823768 lock(&m->lk);
824− if(m->rip == 0)
769+ if(m->rip == nil)
825770 break;
826771 unlock(&m->lk);
827− sleep(&r->r, rpcattn, r);
828− if(r->done){
772+ sleep(r->z, rpcattn, r);
773+ if(r->done) {
829774 poperror();
830775 mntflushfree(m, r);
831776 return;
@@ -850,18 +795,13 @@ doread(Mnt *m, int len) · 18 unmodified lines
850795
851796 while(qlen(m->q) < len){
852797 b = devtab[m->c->type]->bread(m->c, m->msize, 0);
853− if(b == nil)
798+ if(b == nil || qaddlist(m->q, b) == 0)
854799 return -1;
855− if(BLEN(b) == 0){
856− freeblist(b);
857− return -1;
858− }
859− qaddlist(m->q, b);
860800 }
861801 return 0;
862802 }
863803
864−int
804+static int
865805 mntrpcread(Mnt *m, Mntrpc *r)
866806 {
867807 int i, t, len, hlen;
@@ -875,7 +815,7 @@ mntrpcread(Mnt *m, Mntrpc *r) · 7 unmodified lines
875815 return -1;
876816 nb = pullupqueue(m->q, BIT32SZ+BIT8SZ+BIT16SZ);
877817
878− /* read in the rest of the message, avoid rediculous (for now) message sizes */
818+ /* read in the rest of the message, avoid ridiculous (for now) message sizes */
879819 len = GBIT32(nb->rp);
880820 if(len > m->msize){
881821 qdiscard(m->q, qlen(m->q));
@@ -933,49 +873,50 @@ mntrpcread(Mnt *m, Mntrpc *r) · 51 unmodified lines
933873 return 0;
934874 }
935875
936−void
876+static void
937877 mntgate(Mnt *m)
938878 {
939879 Mntrpc *q;
940880
941881 lock(&m->lk);
942− m->rip = 0;
943− for(q = m->queue; q; q = q->list) {
882+ m->rip = nil;
883+ for(q = m->queue; q != nil; q = q->list) {
944884 if(q->done == 0)
945− if(wakeup(&q->r))
885+ if(wakeup(q->z))
946886 break;
947887 }
948888 unlock(&m->lk);
949889 }
950890
951−void
891+static void
952892 mountmux(Mnt *m, Mntrpc *r)
953893 {
954894 Mntrpc **l, *q;
895+ Rendez *z;
955896
956897 lock(&m->lk);
957898 l = &m->queue;
958− for(q = *l; q; q = q->list) {
899+ for(q = *l; q != nil; q = q->list) {
959900 /* look for a reply to a message */
960901 if(q->request.tag == r->reply.tag) {
961902 *l = q->list;
962− if(q != r) {
963− /*
964− * Completed someone else.
965− * Trade pointers to receive buffer.
966− */
967− q->reply = r->reply;
968− q->b = r->b;
969− r->b = nil;
903+ if(q == r) {
904+ q->done = 1;
905+ unlock(&m->lk);
906+ return;
970907 }
908+ /*
909+ * Completed someone else.
910+ * Trade pointers to receive buffer.
911+ */
912+ q->reply = r->reply;
913+ q->b = r->b;
914+ r->b = nil;
915+ z = q->z;
916+ // coherence();
971917 q->done = 1;
918+ wakeup(z);
972919 unlock(&m->lk);
973− if(mntstats != 0)
974− (*mntstats)(q->request.type,
975− m->c, q->stime,
976− q->reqlen + r->replen);
977− if(q != r)
978− wakeup(&q->r);
979920 return;
980921 }
981922 l = &q->list;
@@ -988,13 +929,12 @@ mountmux(Mnt *m, Mntrpc *r) · 6 unmodified lines
988929 * Create a new flush request and chain the previous
989930 * requests from it
990931 */
991−Mntrpc*
992−mntflushalloc(Mntrpc *r, ulong iounit)
932+static Mntrpc*
933+mntflushalloc(Mntrpc *r)
993934 {
994935 Mntrpc *fr;
995936
996− fr = mntralloc(0, iounit);
997−
937+ fr = mntralloc(r->c);
998938 fr->request.type = Tflush;
999939 if(r->request.type == Tflush)
1000940 fr->request.oldtag = r->request.oldtag;
@@ -1010,26 +950,28 @@ mntflushalloc(Mntrpc *r, ulong iounit) · 9 unmodified lines
1010950 * flush and the original message from the unanswered
1011951 * request queue. Mark the original message as done
1012952 * and if it hasn't been answered set the reply to to
1013− * Rflush.
953+ * Rflush. Return the original rpc.
1014954 */
1015−void
955+static Mntrpc*
1016956 mntflushfree(Mnt *m, Mntrpc *r)
1017957 {
1018958 Mntrpc *fr;
1019959
1020− while(r){
960+ while(r != nil){
1021961 fr = r->flushed;
1022962 if(!r->done){
1023963 r->reply.type = Rflush;
1024964 mntqrm(m, r);
1025965 }
1026− if(fr)
1027− mntfree(r);
966+ if(fr == nil)
967+ break;
968+ mntfree(r);
1028969 r = fr;
1029970 }
971+ return r;
1030972 }
1031973
1032−int
974+static int
1033975 alloctag(void)
1034976 {
1035977 int i, j;
@@ -1037,7 +979,7 @@ alloctag(void) · 1 unmodified line
1037979
1038980 for(i = 0; i < NMASK; i++){
1039981 v = mntalloc.tagmask[i];
1040− if(v == ~0)
982+ if(v == ~0UL)
1041983 continue;
1042984 for(j = 0; j < 1<<TAGSHIFT; j++)
1043985 if((v & (1<<j)) == 0){
@@ -1049,52 +991,33 @@ alloctag(void) · 5 unmodified lines
1049991 return NOTAG;
1050992 }
1051993
1052−void
994+static void
1053995 freetag(int t)
1054996 {
1055997 mntalloc.tagmask[t>>TAGSHIFT] &= ~(1<<(t&TAGMASK));
1056998 }
1057999
1058−Mntrpc*
1059−mntralloc(Chan *c, ulong msize)
1000+static Mntrpc*
1001+mntralloc(Chan *c)
10601002 {
10611003 Mntrpc *new;
10621004
1063− lock(&mntalloc.lk);
1064− new = mntalloc.rpcfree;
1065− if(new == nil){
1005+ if(mntalloc.nrpcfree == 0) {
1006+ Alloc:
10661007 new = malloc(sizeof(Mntrpc));
1067− if(new == nil) {
1068− unlock(&mntalloc.lk);
1008+ if(new == nil)
10691009 exhausted("mount rpc header");
1070− }
1071− /*
1072− * The header is split from the data buffer as
1073− * mountmux may swap the buffer with another header.
1074− */
1075− new->rpc = mallocz(msize, 0);
1076− if(new->rpc == nil){
1077− free(new);
1010+ lock(&mntalloc.lk);
1011+ new->request.tag = alloctag();
1012+ } else {
1013+ lock(&mntalloc.lk);
1014+ new = mntalloc.rpcfree;
1015+ if(new == nil) {
10781016 unlock(&mntalloc.lk);
1079− exhausted("mount rpc buffer");
1017+ goto Alloc;
10801018 }
1081− new->rpclen = msize;
1082− new->request.tag = alloctag();
1083− }
1084− else {
10851019 mntalloc.rpcfree = new->list;
10861020 mntalloc.nrpcfree--;
1087− if(new->rpclen < msize){
1088− free(new->rpc);
1089− new->rpc = mallocz(msize, 0);
1090− if(new->rpc == nil){
1091− free(new);
1092− mntalloc.nrpcused--;
1093− unlock(&mntalloc.lk);
1094− exhausted("mount rpc buffer");
1095− }
1096− new->rpclen = msize;
1097− }
10981021 }
10991022 mntalloc.nrpcused++;
11001023 unlock(&mntalloc.lk);
@@ -1105,27 +1028,25 @@ mntralloc(Chan *c, ulong msize) · 4 unmodified lines
11051028 return new;
11061029 }
11071030
1108−void
1031+static void
11091032 mntfree(Mntrpc *r)
11101033 {
1111− if(r->b != nil)
1112− freeblist(r->b);
1034+ freeblist(r->b);
11131035 lock(&mntalloc.lk);
1114− if(mntalloc.nrpcfree >= 10){
1115− free(r->rpc);
1116− free(r);
1117− freetag(r->request.tag);
1118− }
1119− else{
1036+ mntalloc.nrpcused--;
1037+ if(mntalloc.nrpcfree < 32) {
11201038 r->list = mntalloc.rpcfree;
11211039 mntalloc.rpcfree = r;
11221040 mntalloc.nrpcfree++;
1041+ unlock(&mntalloc.lk);
1042+ return;
11231043 }
1124− mntalloc.nrpcused--;
1044+ freetag(r->request.tag);
11251045 unlock(&mntalloc.lk);
1046+ free(r);
11261047 }
11271048
1128−void
1049+static void
11291050 mntqrm(Mnt *m, Mntrpc *r)
11301051 {
11311052 Mntrpc **l, *f;
@@ -1134,7 +1055,7 @@ mntqrm(Mnt *m, Mntrpc *r) · 2 unmodified lines
11341055 r->done = 1;
11351056
11361057 l = &m->queue;
1137− for(f = *l; f; f = f->list) {
1058+ for(f = *l; f != nil; f = f->list) {
11381059 if(f == r) {
11391060 *l = r->list;
11401061 break;
@@ -1144,23 +1065,21 @@ mntqrm(Mnt *m, Mntrpc *r) · 3 unmodified lines
11441065 unlock(&m->lk);
11451066 }
11461067
1147−Mnt*
1068+static Mnt*
11481069 mntchk(Chan *c)
11491070 {
11501071 Mnt *m;
11511072
11521073 /* This routine is mostly vestiges of prior lives; now it's just sanity checking */
1153−
11541074 if(c->mchan == nil)
1155− panic("mntchk 1: nil mchan c %s\n", chanpath(c));
1075+ panic("mntchk 1: nil mchan c %s", chanpath(c));
11561076
11571077 m = c->mchan->mux;
1158−
11591078 if(m == nil)
11601079 print("mntchk 2: nil mux c %s c->mchan %s \n", chanpath(c), chanpath(c->mchan));
11611080
11621081 /*
1163− * Was it closed and reused (was error(Eshutdown); now, it can't happen)
1082+ * Was it closed and reused (was error(Eshutdown); now, it cannot happen)
11641083 */
11651084 if(m->id == 0 || m->id >= c->dev)
11661085 panic("mntchk 3: can't happen");
@@ -1173,7 +1092,7 @@ mntchk(Chan *c) · 6 unmodified lines
11731092 * reflect local values. These entries are known to be
11741093 * the first two in the Dir encoding after the count.
11751094 */
1176−void
1095+static void
11771096 mntdirfix(uchar *dirbuf, Chan *c)
11781097 {
11791098 uint r;
@@ -1185,13 +1104,13 @@ mntdirfix(uchar *dirbuf, Chan *c) · 5 unmodified lines
11851104 PBIT32(dirbuf, c->dev);
11861105 }
11871106
1188−int
1107+static int
11891108 rpcattn(void *v)
11901109 {
11911110 Mntrpc *r;
11921111
11931112 r = v;
1194− return r->done || r->m->rip == 0;
1113+ return r->done || r->m->rip == nil;
11951114 }
11961115
11971116 Dev mntdevtab = {
@@ -1201,7 +1120,7 @@ Dev mntdevtab = { · 3 unmodified lines
12011120 mntreset,
12021121 devinit,
12031122 devshutdown,
1204− mntattach,
1123+ noattach,
12051124 mntwalk,
12061125 mntstat,
12071126 mntopen,
kern/fns.h+2−10
@@ -10,7 +10,6 @@ Block* allocb(int); · 9 unmodified lines
1010 int anyhigher(void);
1111 int anyready(void);
1212 Page* auxpage(void);
13−Block* bl2mem(uchar*, Block*, int);
1413 int blocklen(Block*);
1514 void callwithureg(void(*)(Ureg*));
1615 char* chanpath(Chan*);
@@ -27,7 +26,6 @@ void chanfree(Chan*); · 10 unmodified lines
2726 void chanrec(Mnt*);
2827 void checkalarms(void);
2928 void checkb(Block*, char*);
30−void cinit(void);
3129 Chan* cclone(Chan*);
3230 void cclose(Chan*);
3331 char* clipread(void);
@@ -45,14 +43,10 @@ void confinit(void); · 11 unmodified lines
4543 void confinit1(int);
4644 int consactive(void);
4745 extern void (*consdebug)(void);
48−void copen(Chan*);
4946 Block* concatblock(Block*);
5047 Block* copyblock(Block*, int);
5148 void copypage(Page*, Page*);
52−int cread(Chan*, uchar*, int, vlong);
5349 void cunmount(Chan*, Chan*);
54−void cupdate(Chan*, uchar*, int, vlong);
55−void cwrite(Chan*, uchar*, int, vlong);
5650 ulong dbgpc(Proc*);
5751 int decref(Ref*);
5852 int decrypt(void*, void*, int);
@@ -119,7 +113,6 @@ long hostownerwrite(char*, int); · 60 unmodified lines
119113 void hzsched(void);
120114 void iallocinit(void);
121115 Block* iallocb(int);
122−void iallocsummary(void);
123116 long ibrk(ulong, int);
124117 void ilock(Lock*);
125118 void iunlock(Lock*);
@@ -161,8 +154,6 @@ void machinit(void); · 35 unmodified lines
161154 void* mallocz(ulong, int);
162155 #define malloc kmalloc
163156 void* malloc(ulong);
164−void mallocsummary(void);
165−Block* mem2bl(uchar*, int);
166157 void mfreeseg(Segment*, ulong, int);
167158 void microdelay(int);
168159 void mkqid(Qid*, vlong, ulong, int);
@@ -238,7 +229,8 @@ void putstrn(char*, int); · 69 unmodified lines
238229 void putswap(Page*);
239230 ulong pwait(Waitmsg*);
240231 Label* pwaserror(void);
241−void qaddlist(Queue*, Block*);
232+long readblist(Block*, uchar *, long, long);
233+int qaddlist(Queue*, Block*);
242234 Block* qbread(Queue*, int);
243235 long qbwrite(Queue*, Block*);
244236 Queue* qbypass(void (*)(void*, Block*), void*);
kern/qio.c+245−364
@@ -10,18 +10,17 @@ static ulong pullupblockcnt; · 9 unmodified lines
1010 static ulong copyblockcnt;
1111 static ulong consumecnt;
1212 static ulong producecnt;
13−static ulong qcopycnt;
14−
15−static int debugging;
1613
1714 #define QDEBUG if(0)
1815
1916 /*
2017 * IO queues
2118 */
19+typedef struct Queue Queue;
20+
2221 struct Queue
2322 {
24− Lock lk;
23+ Lock lk;
2524
2625 Block* bfirst; /* buffer */
2726 Block* blast;
@@ -53,17 +52,6 @@ enum · 25 unmodified lines
5352
5453 uint qiomaxatomic = Maxatomic;
5554
56−void
57−ixsummary(void)
58−{
59− debugging ^= 1;
60− iallocsummary();
61− print("pad %lud, concat %lud, pullup %lud, copy %lud\n",
62− padblockcnt, concatblockcnt, pullupblockcnt, copyblockcnt);
63− print("consume %lud, produce %lud, qcopy %lud\n",
64− consumecnt, producecnt, qcopycnt);
65−}
66−
6755 /*
6856 * free a list of blocks
6957 */
@@ -72,9 +60,9 @@ freeblist(Block *b) · 2 unmodified lines
7260 {
7361 Block *next;
7462
75− for(; b != 0; b = next){
63+ for(; b != nil; b = next){
7664 next = b->next;
77− b->next = 0;
65+ b->next = nil;
7866 freeb(b);
7967 }
8068 }
@@ -88,40 +76,31 @@ padblock(Block *bp, int size) · 7 unmodified lines
8876 int n;
8977 Block *nbp;
9078
91− QDEBUG checkb(bp, "padblock 1");
79+ QDEBUG checkb(bp, "padblock 0");
9280 if(size >= 0){
9381 if(bp->rp - bp->base >= size){
9482 bp->rp -= size;
9583 return bp;
9684 }
97−
98− if(bp->next)
99− panic("padblock 0x%p", getcallerpc(&bp));
10085 n = BLEN(bp);
101− padblockcnt++;
10286 nbp = allocb(size+n);
10387 nbp->rp += size;
10488 nbp->wp = nbp->rp;
10589 memmove(nbp->wp, bp->rp, n);
10690 nbp->wp += n;
107− freeb(bp);
10891 nbp->rp -= size;
10992 } else {
11093 size = -size;
111−
112− if(bp->next)
113− panic("padblock 0x%p", getcallerpc(&bp));
114−
11594 if(bp->lim - bp->wp >= size)
11695 return bp;
117−
11896 n = BLEN(bp);
119− padblockcnt++;
120− nbp = allocb(size+n);
97+ nbp = allocb(n+size);
12198 memmove(nbp->wp, bp->rp, n);
12299 nbp->wp += n;
123− freeb(bp);
124100 }
101+ nbp->next = bp->next;
102+ freeb(bp);
103+ padblockcnt++;
125104 QDEBUG checkb(nbp, "padblock 1");
126105 return nbp;
127106 }
@@ -135,7 +114,7 @@ blocklen(Block *bp) · 7 unmodified lines
135114 int len;
136115
137116 len = 0;
138− while(bp) {
117+ while(bp != nil) {
139118 len += BLEN(bp);
140119 bp = bp->next;
141120 }
@@ -151,7 +130,7 @@ blockalloclen(Block *bp) · 9 unmodified lines
151130 int len;
152131
153132 len = 0;
154− while(bp) {
133+ while(bp != nil) {
155134 len += BALLOC(bp);
156135 bp = bp->next;
157136 }
@@ -159,28 +138,19 @@ blockalloclen(Block *bp) · 1 unmodified line
159138 }
160139
161140 /*
162− * copy the string of blocks into
141+ * copy the string of blocks into
163142 * a single block and free the string
164143 */
165144 Block*
166145 concatblock(Block *bp)
167146 {
168147 int len;
169− Block *nb, *f;
170148
171− if(bp->next == 0)
149+ if(bp->next == nil)
172150 return bp;
173−
174− nb = allocb(blocklen(bp));
175− for(f = bp; f; f = f->next) {
176− len = BLEN(f);
177− memmove(nb->wp, f->rp, len);
178− nb->wp += len;
179− }
180− concatblockcnt += BLEN(nb);
181− freeblist(bp);
182− QDEBUG checkb(nb, "concatblock 1");
183− return nb;
151+ len = blocklen(bp);
152+ concatblockcnt += len;
153+ return pullupblock(bp, len);
184154 }
185155
186156 /*
@@ -189,8 +159,8 @@ concatblock(Block *bp) · 2 unmodified lines
189159 Block*
190160 pullupblock(Block *bp, int n)
191161 {
192− int i;
193162 Block *nbp;
163+ int i;
194164
195165 /*
196166 * this should almost always be true, it's
@@ -213,11 +183,11 @@ pullupblock(Block *bp, int n) · 16 unmodified lines
213183 * copy bytes from the trailing blocks into the first
214184 */
215185 n -= BLEN(bp);
216− while((nbp = bp->next)){
186+ while((nbp = bp->next) != nil){
187+ pullupblockcnt++;
217188 i = BLEN(nbp);
218189 if(i > n) {
219190 memmove(bp->wp, nbp->rp, n);
220− pullupblockcnt++;
221191 bp->wp += n;
222192 nbp->rp += n;
223193 QDEBUG checkb(bp, "pullupblock 1");
@@ -225,14 +195,14 @@ pullupblock(Block *bp, int n) · 1 unmodified line
225195 } else {
226196 /* shouldn't happen but why crash if it does */
227197 if(i < 0){
228− print("pullup negative length packet\n");
198+ print("pullup negative length packet, called from %#p\n",
199+ getcallerpc(&bp));
229200 i = 0;
230201 }
231202 memmove(bp->wp, nbp->rp, i);
232− pullupblockcnt++;
233203 bp->wp += i;
234204 bp->next = nbp->next;
235− nbp->next = 0;
205+ nbp->next = nil;
236206 freeb(nbp);
237207 n -= i;
238208 if(n == 0){
@@ -242,7 +212,7 @@ pullupblock(Block *bp, int n) · 3 unmodified lines
242212 }
243213 }
244214 freeb(bp);
245− return 0;
215+ return nil;
246216 }
247217
248218 /*
@@ -295,7 +265,7 @@ trimblock(Block *bp, int offset, int len) · 46 unmodified lines
295265
296266 bp->wp -= (BLEN(bp) - len);
297267
298− if(bp->next) {
268+ if(bp->next != nil) {
299269 freeblist(bp->next);
300270 bp->next = nil;
301271 }
@@ -314,7 +284,7 @@ copyblock(Block *bp, int count) · 12 unmodified lines
314284
315285 QDEBUG checkb(bp, "copyblock 0");
316286 nbp = allocb(count);
317− for(; count > 0 && bp != 0; bp = bp->next){
287+ for(; count > 0 && bp != nil; bp = bp->next){
318288 l = BLEN(bp);
319289 if(l > count)
320290 l = count;
@@ -412,11 +382,11 @@ qget(Queue *q) · 91 unmodified lines
412382 iunlock(&q->lk);
413383 return nil;
414384 }
385+ QDEBUG checkb(b, "qget");
415386 q->bfirst = b->next;
416− b->next = 0;
387+ b->next = nil;
417388 q->len -= BALLOC(b);
418389 q->dlen -= BLEN(b);
419− QDEBUG checkb(b, "qget");
420390
421391 /* if writer flow controlled, restart */
422392 if((q->state & Qflow) && q->len < q->limit/2){
@@ -439,7 +409,7 @@ qget(Queue *q) · 16 unmodified lines
439409 int
440410 qdiscard(Queue *q, int len)
441411 {
442− Block *b;
412+ Block *b, *tofree = nil;
443413 int dowakeup, n, sofar;
444414
445415 ilock(&q->lk);
@@ -451,10 +421,12 @@ qdiscard(Queue *q, int len) · 5 unmodified lines
451421 n = BLEN(b);
452422 if(n <= len - sofar){
453423 q->bfirst = b->next;
454− b->next = 0;
455424 q->len -= BALLOC(b);
456425 q->dlen -= BLEN(b);
457− freeb(b);
426+
427+ /* remember to free this */
428+ b->next = tofree;
429+ tofree = b;
458430 } else {
459431 n = len - sofar;
460432 b->rp += n;
@@ -483,6 +455,9 @@ qdiscard(Queue *q, int len) · 22 unmodified lines
483455 if(dowakeup)
484456 wakeup(&q->wr);
485457
458+ if(tofree != nil)
459+ freeblist(tofree);
460+
486461 return sofar;
487462 }
488463
@@ -492,20 +467,19 @@ qdiscard(Queue *q, int len) · 3 unmodified lines
492467 int
493468 qconsume(Queue *q, void *vp, int len)
494469 {
495− Block *b;
470+ Block *b, *tofree = nil;
496471 int n, dowakeup;
497472 uchar *p = vp;
498− Block *tofree = nil;
499473
500474 /* sync with qwrite */
501475 ilock(&q->lk);
502476
503477 for(;;) {
504478 b = q->bfirst;
505− if(b == 0){
479+ if(b == nil){
506480 q->state |= Qstarve;
507− iunlock(&q->lk);
508− return -1;
481+ len = -1;
482+ goto out;
509483 }
510484 QDEBUG checkb(b, "qconsume 1");
511485
@@ -520,17 +494,16 @@ qconsume(Queue *q, void *vp, int len) · 8 unmodified lines
520494 tofree = b;
521495 };
522496
497+ consumecnt += n;
523498 if(n < len)
524499 len = n;
525500 memmove(p, b->rp, len);
526− consumecnt += n;
527501 b->rp += len;
528502 q->dlen -= len;
529503
530504 /* discard the block if we're done with it */
531505 if((q->state & Qmsg) || len == n){
532506 q->bfirst = b->next;
533− b->next = 0;
534507 q->len -= BALLOC(b);
535508 q->dlen -= BLEN(b);
536509
@@ -539,6 +512,7 @@ qconsume(Queue *q, void *vp, int len) · 2 unmodified lines
539512 tofree = b;
540513 }
541514
515+out:
542516 /* if writer flow controlled, restart */
543517 if((q->state & Qflow) && q->len < q->limit/2){
544518 q->state &= ~Qflow;
@@ -560,39 +534,23 @@ qconsume(Queue *q, void *vp, int len) · 15 unmodified lines
560534 int
561535 qpass(Queue *q, Block *b)
562536 {
563− int dlen, len, dowakeup;
537+ int len, dowakeup;
564538
565539 /* sync with qread */
566540 dowakeup = 0;
567541 ilock(&q->lk);
568542 if(q->len >= q->limit){
569− freeblist(b);
570543 iunlock(&q->lk);
544+ freeblist(b);
571545 return -1;
572546 }
573547 if(q->state & Qclosed){
574− freeblist(b);
575548 iunlock(&q->lk);
576− return BALLOC(b);
549+ freeblist(b);
550+ return 0;
577551 }
578552
579− /* add buffer to queue */
580− if(q->bfirst)
581− q->blast->next = b;
582− else
583− q->bfirst = b;
584− len = BALLOC(b);
585− dlen = BLEN(b);
586− QDEBUG checkb(b, "qpass");
587− while(b->next){
588− b = b->next;
589− QDEBUG checkb(b, "qpass");
590− len += BALLOC(b);
591− dlen += BLEN(b);
592− }
593− q->blast = b;
594− q->len += len;
595− q->dlen += dlen;
553+ len = qaddlist(q, b);
596554
597555 if(q->len >= q->limit/2)
598556 q->state |= Qflow;
@@ -612,35 +570,19 @@ qpass(Queue *q, Block *b) · 13 unmodified lines
612570 int
613571 qpassnolim(Queue *q, Block *b)
614572 {
615− int dlen, len, dowakeup;
573+ int len, dowakeup;
616574
617575 /* sync with qread */
618576 dowakeup = 0;
619577 ilock(&q->lk);
620578
621579 if(q->state & Qclosed){
622− freeblist(b);
623580 iunlock(&q->lk);
624− return BALLOC(b);
581+ freeblist(b);
582+ return 0;
625583 }
626584
627− /* add buffer to queue */
628− if(q->bfirst)
629− q->blast->next = b;
630− else
631− q->bfirst = b;
632− len = BALLOC(b);
633− dlen = BLEN(b);
634− QDEBUG checkb(b, "qpass");
635− while(b->next){
636− b = b->next;
637− QDEBUG checkb(b, "qpass");
638− len += BALLOC(b);
639− dlen += BLEN(b);
640− }
641− q->blast = b;
642− q->len += len;
643− q->dlen += dlen;
585+ len = qaddlist(q, b);
644586
645587 if(q->len >= q->limit/2)
646588 q->state |= Qflow;
@@ -667,8 +609,7 @@ packblock(Block *bp) · 20 unmodified lines
667609 Block **l, *nbp;
668610 int n;
669611
670− for(l = &bp; *l; l = &(*l)->next){
671− nbp = *l;
612+ for(l = &bp; (nbp = *l) != nil; l = &(*l)->next){
672613 n = BLEN(nbp);
673614 if((n<<2) < BALLOC(nbp)){
674615 *l = allocb(n);
@@ -689,6 +630,10 @@ qproduce(Queue *q, void *vp, int len) · 14 unmodified lines
689630 int dowakeup;
690631 uchar *p = vp;
691632
633+ b = iallocb(len);
634+ if(b == nil)
635+ return 0;
636+
692637 /* sync with qread */
693638 dowakeup = 0;
694639 ilock(&q->lk);
@@ -699,25 +644,12 @@ qproduce(Queue *q, void *vp, int len) · 4 unmodified lines
699644 iunlock(&q->lk);
700645 return -1;
701646 }
647+ producecnt += len;
702648
703649 /* save in buffer */
704− b = iallocb(len);
705− if(b == 0){
706− iunlock(&q->lk);
707− return 0;
708− }
709650 memmove(b->wp, p, len);
710− producecnt += len;
711651 b->wp += len;
712− if(q->bfirst)
713− q->blast->next = b;
714− else
715− q->bfirst = b;
716− q->blast = b;
717− /* b->next = 0; done by iallocb() */
718− q->len += BALLOC(b);
719− q->dlen += BLEN(b);
720− QDEBUG checkb(b, "qproduce");
652+ qaddlist(q, b);
721653
722654 if(q->state & Qstarve){
723655 q->state &= ~Qstarve;
@@ -740,49 +672,13 @@ qproduce(Queue *q, void *vp, int len) · 16 unmodified lines
740672 Block*
741673 qcopy(Queue *q, int len, ulong offset)
742674 {
743− int sofar;
744− int n;
745− Block *b, *nb;
746− uchar *p;
747−
748− nb = allocb(len);
675+ Block *b;
749676
677+ b = allocb(len);
750678 ilock(&q->lk);
751−
752− /* go to offset */
753− b = q->bfirst;
754− for(sofar = 0; ; sofar += n){
755− if(b == nil){
756− iunlock(&q->lk);
757− return nb;
758− }
759− n = BLEN(b);
760− if(sofar + n > offset){
761− p = b->rp + offset - sofar;
762− n -= offset - sofar;
763− break;
764− }
765− QDEBUG checkb(b, "qcopy");
766− b = b->next;
767− }
768−
769− /* copy bytes from there */
770− for(sofar = 0; sofar < len;){
771− if(n > len - sofar)
772− n = len - sofar;
773− memmove(nb->wp, p, n);
774− qcopycnt += n;
775− sofar += n;
776− nb->wp += n;
777− b = b->next;
778− if(b == nil)
779− break;
780− n = BLEN(b);
781− p = b->rp;
782− }
679+ b->wp += readblist(q->bfirst, b->wp, len, offset);
783680 iunlock(&q->lk);
784−
785− return nb;
681+ return b;
786682 }
787683
788684 /*
@@ -794,8 +690,8 @@ qopen(int limit, int msg, void (*kick)(void*), void *arg) · 5 unmodified lines
794690 Queue *q;
795691
796692 q = malloc(sizeof(Queue));
797− if(q == 0)
798− return 0;
693+ if(q == nil)
694+ return nil;
799695
800696 q->limit = q->inilim = limit;
801697 q->kick = kick;
@@ -816,8 +712,8 @@ qbypass(void (*bypass)(void*, Block*), void *arg) · 14 unmodified lines
816712 Queue *q;
817713
818714 q = malloc(sizeof(Queue));
819− if(q == 0)
820− return 0;
715+ if(q == nil)
716+ return nil;
821717
822718 q->limit = 0;
823719 q->arg = arg;
@@ -832,7 +728,7 @@ notempty(void *a) · 8 unmodified lines
832728 {
833729 Queue *q = a;
834730
835− return (q->state & Qclosed) || q->bfirst != 0;
731+ return (q->state & Qclosed) || q->bfirst != nil;
836732 }
837733
838734 /*
@@ -864,21 +760,34 @@ qwait(Queue *q) · 25 unmodified lines
864760 }
865761
866762 /*
867− * add a block list to a queue
763+ * add a block list to a queue, return bytes added
868764 */
869−void
765+int
870766 qaddlist(Queue *q, Block *b)
871767 {
768+ int len, dlen;
769+
770+ QDEBUG checkb(b, "qaddlist 1");
771+
872772 /* queue the block */
873− if(q->bfirst)
773+ if(q->bfirst != nil)
874774 q->blast->next = b;
875775 else
876776 q->bfirst = b;
877− q->len += blockalloclen(b);
878− q->dlen += blocklen(b);
879− while(b->next)
777+
778+ len = BALLOC(b);
779+ dlen = BLEN(b);
780+ while(b->next != nil){
880781 b = b->next;
782+ QDEBUG checkb(b, "qaddlist 2");
783+
784+ len += BALLOC(b);
785+ dlen += BLEN(b);
786+ }
881787 q->blast = b;
788+ q->len += len;
789+ q->dlen += dlen;
790+ return dlen;
882791 }
883792
884793 /*
@@ -892,74 +801,42 @@ qremove(Queue *q) · 7 unmodified lines
892801 b = q->bfirst;
893802 if(b == nil)
894803 return nil;
804+ QDEBUG checkb(b, "qremove");
895805 q->bfirst = b->next;
896806 b->next = nil;
897807 q->dlen -= BLEN(b);
898808 q->len -= BALLOC(b);
899− QDEBUG checkb(b, "qremove");
900809 return b;
901810 }
902811
903812 /*
904813 * copy the contents of a string of blocks into
905− * memory. emptied blocks are freed. return
906− * pointer to first unconsumed block.
814+ * memory from an offset. blocklist kept unchanged.
815+ * return number of copied bytes.
907816 */
908−Block*
909−bl2mem(uchar *p, Block *b, int n)
817+long
818+readblist(Block *b, uchar *p, long n, long o)
910819 {
911− int i;
912− Block *next;
820+ long m, r;
913821
914− for(; b != nil; b = next){
915− i = BLEN(b);
916− if(i > n){
917− memmove(p, b->rp, n);
918− b->rp += n;
919− return b;
822+ r = 0;
823+ while(n > 0 && b != nil){
824+ m = BLEN(b);
825+ if(o >= m)
826+ o -= m;
827+ else {
828+ m -= o;
829+ if(n < m)
830+ m = n;
831+ memmove(p, b->rp + o, m);
832+ p += m;
833+ r += m;
834+ n -= m;
835+ o = 0;
920836 }
921− memmove(p, b->rp, i);
922− n -= i;
923− p += i;
924− b->rp += i;
925− next = b->next;
926− freeb(b);
927− }
928− return nil;
929−}
930−
931−/*
932− * copy the contents of memory into a string of blocks.
933− * return nil on error.
934− */
935−Block*
936−mem2bl(uchar *p, int len)
937−{
938− int n;
939− Block *b, *first, **l;
940−
941− first = nil;
942− l = &first;
943− if(waserror()){
944− freeblist(first);
945− nexterror();
837+ b = b->next;
946838 }
947− do {
948− n = len;
949− if(n > Maxatomic)
950− n = Maxatomic;
951−
952− *l = b = allocb(n);
953− /* setmalloctag(b, (up->text[0]<<24)|(up->text[1]<<16)|(up->text[2]<<8)|up->text[3]); */
954− memmove(b->wp, p, n);
955− b->wp += n;
956− p += n;
957− len -= n;
958− l = &b->next;
959− } while(len > 0);
960− poperror();
961−
962− return first;
839+ return r;
963840 }
964841
965842 /*
@@ -977,6 +854,35 @@ qputback(Queue *q, Block *b) · 11 unmodified lines
977854 q->dlen += BLEN(b);
978855 }
979856
857+/*
858+ * cut off n bytes from the end of *h. return a new
859+ * block with the tail and change *h to refer to the
860+ * head.
861+ */
862+static Block*
863+splitblock(Block **h, int n)
864+{
865+ Block *a, *b;
866+ int m;
867+
868+ a = *h;
869+ m = BLEN(a) - n;
870+ if(m < n){
871+ b = allocb(m);
872+ memmove(b->wp, a->rp, m);
873+ b->wp += m;
874+ a->rp += m;
875+ *h = b;
876+ return a;
877+ } else {
878+ b = allocb(n);
879+ a->wp -= n;
880+ memmove(b->wp, a->wp, n);
881+ b->wp += n;
882+ return b;
883+ }
884+}
885+
980886 /*
981887 * flow control, get producer going again
982888 * called with q ilocked
@@ -996,7 +902,7 @@ qwakeup_iunlock(Queue *q) · 13 unmodified lines
996902
997903 /* wakeup flow controlled writers */
998904 if(dowakeup){
999− if(q->kick)
905+ if(q->kick != nil)
1000906 q->kick(q->arg);
1001907 wakeup(&q->wr);
1002908 }
@@ -1008,7 +914,7 @@ qwakeup_iunlock(Queue *q) · 5 unmodified lines
1008914 Block*
1009915 qbread(Queue *q, int len)
1010916 {
1011− Block *b, *nb;
917+ Block *b;
1012918 int n;
1013919
1014920 qlock(&q->rlock);
@@ -1036,24 +942,21 @@ qbread(Queue *q, int len) · 21 unmodified lines
1036942 n = BLEN(b);
1037943
1038944 /* split block if it's too big and this is not a message queue */
1039− nb = b;
1040945 if(n > len){
1041− if((q->state&Qmsg) == 0){
1042− n -= len;
1043− b = allocb(n);
1044− memmove(b->wp, nb->rp+len, n);
1045− b->wp += n;
1046− qputback(q, b);
1047− }
1048− nb->wp = nb->rp + len;
946+ n -= len;
947+ if((q->state & Qmsg) == 0)
948+ qputback(q, splitblock(&b, n));
949+ else
950+ b->wp -= n;
1049951 }
1050952
1051953 /* restart producer */
1052954 qwakeup_iunlock(q);
1053955
1054− poperror();
1055956 qunlock(&q->rlock);
1056− return nb;
957+ poperror();
958+
959+ return b;
1057960 }
1058961
1059962 /*
@@ -1063,7 +966,7 @@ qbread(Queue *q, int len) · 3 unmodified lines
1063966 long
1064967 qread(Queue *q, void *vp, int len)
1065968 {
1066− Block *b, *first, **l;
969+ Block *b, *first, **last;
1067970 int m, n;
1068971
1069972 qlock(&q->rlock);
@@ -1088,57 +991,53 @@ again: · 18 unmodified lines
1088991 }
1089992
1090993 /* if we get here, there's at least one block in the queue */
994+ last = &first;
1091995 if(q->state & Qcoalesce){
1092996 /* when coalescing, 0 length blocks just go away */
1093997 b = q->bfirst;
1094− if(BLEN(b) <= 0){
998+ m = BLEN(b);
999+ if(m <= 0){
10951000 freeb(qremove(q));
10961001 goto again;
10971002 }
10981003
10991004 /* grab the first block plus as many
1100− * following blocks as will completely
1005+ * following blocks as will partially
11011006 * fit in the read.
11021007 */
11031008 n = 0;
1104− l = &first;
1105− m = BLEN(b);
11061009 for(;;) {
1107− *l = qremove(q);
1108− l = &b->next;
1010+ *last = qremove(q);
11091011 n += m;
1110−
1111− b = q->bfirst;
1112− if(b == nil)
1012+ if(n >= len || q->bfirst == nil)
11131013 break;
1014+ last = &b->next;
1015+ b = q->bfirst;
11141016 m = BLEN(b);
1115− if(n+m > len)
1116− break;
11171017 }
11181018 } else {
11191019 first = qremove(q);
11201020 n = BLEN(first);
11211021 }
11221022
1123− /* copy to user space outside of the ilock */
1124− iunlock(&q->lk);
1125− b = bl2mem(vp, first, len);
1126− ilock(&q->lk);
1127−
1128− /* take care of any left over partial block */
1129− if(b != nil){
1130− n -= BLEN(b);
1131− if(q->state & Qmsg)
1132− freeb(b);
1133− else
1134− qputback(q, b);
1135− }
1023+ /* split last block if it's too big and this is not a message queue */
1024+ if(n > len && (q->state & Qmsg) == 0)
1025+ qputback(q, splitblock(last, n - len));
11361026
11371027 /* restart producer */
11381028 qwakeup_iunlock(q);
11391029
1140− poperror();
11411030 qunlock(&q->rlock);
1031+ poperror();
1032+
1033+ if(waserror()){
1034+ freeblist(first);
1035+ nexterror();
1036+ }
1037+ n = readblist(first, vp, len, 0);
1038+ freeblist(first);
1039+ poperror();
1040+
11421041 return n;
11431042 }
11441043
@@ -1150,7 +1049,30 @@ qnotfull(void *a) · 5 unmodified lines
11501049 return q->len < q->limit || (q->state & Qclosed);
11511050 }
11521051
1153−ulong noblockcnt;
1052+/*
1053+ * flow control, wait for queue to get below the limit
1054+ */
1055+static void
1056+qflow(Queue *q)
1057+{
1058+ for(;;){
1059+ if(q->noblock || qnotfull(q))
1060+ break;
1061+
1062+ ilock(&q->lk);
1063+ q->state |= Qflow;
1064+ iunlock(&q->lk);
1065+
1066+ qlock(&q->wlock);
1067+ if(waserror()){
1068+ qunlock(&q->wlock);
1069+ nexterror();
1070+ }
1071+ sleep(&q->wr, qnotfull, q);
1072+ qunlock(&q->wlock);
1073+ poperror();
1074+ }
1075+}
11541076
11551077 /*
11561078 * add a block to a queue obeying flow control
@@ -1158,24 +1080,19 @@ ulong noblockcnt; · 1 unmodified line
11581080 long
11591081 qbwrite(Queue *q, Block *b)
11601082 {
1161− int n, dowakeup;
1083+ int len, dowakeup;
11621084
1163− n = BLEN(b);
1164−
1165− if(q->bypass){
1085+ if(q->bypass != nil){
1086+ len = blocklen(b);
11661087 (*q->bypass)(q->arg, b);
1167− return n;
1088+ return len;
11681089 }
11691090
11701091 dowakeup = 0;
1171− qlock(&q->wlock);
11721092 if(waserror()){
1173− if(b != nil)
1174− freeb(b);
1175− qunlock(&q->wlock);
1093+ freeblist(b);
11761094 nexterror();
11771095 }
1178−
11791096 ilock(&q->lk);
11801097
11811098 /* give up if the queue is closed */
@@ -1184,29 +1101,16 @@ qbwrite(Queue *q, Block *b) · 2 unmodified lines
11841101 error(q->err);
11851102 }
11861103
1187− /* if nonblocking, don't queue over the limit */
1188− if(q->len >= q->limit){
1189− if(q->noblock){
1190− iunlock(&q->lk);
1191− freeb(b);
1192− noblockcnt += n;
1193− qunlock(&q->wlock);
1194− poperror();
1195− return n;
1196− }
1104+ /* don't queue over the limit */
1105+ if(q->len >= q->limit && q->noblock){
1106+ iunlock(&q->lk);
1107+ poperror();
1108+ len = blocklen(b);
1109+ freeblist(b);
1110+ return len;
11971111 }
11981112
1199− /* queue the block */
1200− if(q->bfirst)
1201− q->blast->next = b;
1202− else
1203− q->bfirst = b;
1204− q->blast = b;
1205− b->next = 0;
1206− q->len += BALLOC(b);
1207− q->dlen += n;
1208− QDEBUG checkb(b, "qbwrite");
1209− b = nil;
1113+ len = qaddlist(q, b);
12101114
12111115 /* make sure other end gets awakened */
12121116 if(q->state & Qstarve){
@@ -1214,49 +1118,26 @@ qbwrite(Queue *q, Block *b) · 1 unmodified line
12141118 dowakeup = 1;
12151119 }
12161120 iunlock(&q->lk);
1121+ poperror();
12171122
12181123 /* get output going again */
1219− if(q->kick && (dowakeup || (q->state&Qkick)))
1124+ if(q->kick != nil && (dowakeup || (q->state&Qkick)))
12201125 q->kick(q->arg);
12211126
12221127 /* wakeup anyone consuming at the other end */
1223− if(dowakeup){
1128+ if(dowakeup)
12241129 wakeup(&q->rr);
12251130
1226− /* if we just wokeup a higher priority process, let it run */
1227− /*
1228− p = wakeup(&q->rr);
1229− if(p != nil && p->priority > up->priority)
1230− sched();
1231− */
1232− }
1233−
12341131 /*
1235− * flow control, wait for queue to get below the limit
1236− * before allowing the process to continue and queue
1237− * more. We do this here so that postnote can only
1238− * interrupt us after the data has been queued. This
1239− * means that things like 9p flushes and ssl messages
1240− * will not be disrupted by software interrupts.
1241− *
1242− * Note - this is moderately dangerous since a process
1243− * that keeps getting interrupted and rewriting will
1244− * queue infinite crud.
1132+ * flow control, before allowing the process to continue and
1133+ * queue more. We do this here so that postnote can only
1134+ * interrupt us after the data has been queued. This means that
1135+ * things like 9p flushes and ssl messages will not be disrupted
1136+ * by software interrupts.
12451137 */
1246− for(;;){
1247− if(q->noblock || qnotfull(q))
1248− break;
1138+ qflow(q);
12491139
1250− ilock(&q->lk);
1251− q->state |= Qflow;
1252− iunlock(&q->lk);
1253− sleep(&q->wr, qnotfull, q);
1254− }
1255− USED(b);
1256−
1257− qunlock(&q->wlock);
1258− poperror();
1259− return n;
1140+ return len;
12601141 }
12611142
12621143 /*
@@ -1270,7 +1151,15 @@ qwrite(Queue *q, void *vp, int len) · 7 unmodified lines
12701151 uchar *p = vp;
12711152
12721153 QDEBUG if(!islo())
1273− print("qwrite hi %p\n", getcallerpc(&q));
1154+ print("qwrite hi %#p\n", getcallerpc(&q));
1155+
1156+ /* stop queue bloat before allocating blocks */
1157+ if(q->len/2 >= q->limit && q->noblock == 0 && q->bypass == nil){
1158+ while(waserror())
1159+ ;
1160+ qflow(q);
1161+ poperror();
1162+ }
12741163
12751164 sofar = 0;
12761165 do {
@@ -1279,7 +1168,6 @@ qwrite(Queue *q, void *vp, int len) · 2 unmodified lines
12791168 n = Maxatomic;
12801169
12811170 b = allocb(n);
1282− /* setmalloctag(b, (up->text[0]<<24)|(up->text[1]<<16)|(up->text[2]<<8)|up->text[3]); */
12831171 if(waserror()){
12841172 freeb(b);
12851173 nexterror();
@@ -1288,9 +1176,7 @@ qwrite(Queue *q, void *vp, int len) · 2 unmodified lines
12881176 poperror();
12891177 b->wp += n;
12901178
1291− qbwrite(q, b);
1292−
1293− sofar += n;
1179+ sofar += qbwrite(q, b);
12941180 } while(sofar < len && (q->state & Qmsg) == 0);
12951181
12961182 return len;
@@ -1323,14 +1209,16 @@ qiwrite(Queue *q, void *vp, int len) · 26 unmodified lines
13231209
13241210 ilock(&q->lk);
13251211
1326− QDEBUG checkb(b, "qiwrite");
1327− if(q->bfirst)
1328− q->blast->next = b;
1329− else
1330− q->bfirst = b;
1331− q->blast = b;
1332− q->len += BALLOC(b);
1333− q->dlen += n;
1212+ /* we use an artificially high limit for kernel prints since anything
1213+ * over the limit gets dropped
1214+ */
1215+ if((q->state & Qclosed) != 0 || q->len/2 >= q->limit){
1216+ iunlock(&q->lk);
1217+ freeb(b);
1218+ break;
1219+ }
1220+
1221+ qaddlist(q, b);
13341222
13351223 if(q->state & Qstarve){
13361224 q->state &= ~Qstarve;
@@ -1340,7 +1228,7 @@ qiwrite(Queue *q, void *vp, int len) · 3 unmodified lines
13401228 iunlock(&q->lk);
13411229
13421230 if(dowakeup){
1343− if(q->kick)
1231+ if(q->kick != nil)
13441232 q->kick(q->arg);
13451233 wakeup(&q->rr);
13461234 }
@@ -1378,9 +1266,9 @@ qclose(Queue *q) · 31 unmodified lines
13781266 ilock(&q->lk);
13791267 q->state |= Qclosed;
13801268 q->state &= ~(Qflow|Qstarve);
1381− strcpy(q->err, Ehungup);
1269+ kstrcpy(q->err, Ehungup, ERRMAX);
13821270 bfirst = q->bfirst;
1383− q->bfirst = 0;
1271+ q->bfirst = nil;
13841272 q->len = 0;
13851273 q->dlen = 0;
13861274 q->noblock = 0;
@@ -1404,10 +1292,9 @@ qhangup(Queue *q, char *msg) · 17 unmodified lines
14041292 /* mark it */
14051293 ilock(&q->lk);
14061294 q->state |= Qclosed;
1407− if(msg == 0 || *msg == 0)
1408− strcpy(q->err, Ehungup);
1409− else
1410− strncpy(q->err, msg, ERRMAX-1);
1295+ if(msg == nil || *msg == '\0')
1296+ msg = Ehungup;
1297+ kstrcpy(q->err, msg, ERRMAX);
14111298 iunlock(&q->lk);
14121299
14131300 /* wake up readers/writers */
@@ -1467,7 +1354,7 @@ qwindow(Queue *q) · 53 unmodified lines
14671354 int
14681355 qcanread(Queue *q)
14691356 {
1470− return q->bfirst!=0;
1357+ return q->bfirst != nil;
14711358 }
14721359
14731360 /*
@@ -1499,7 +1386,7 @@ qflush(Queue *q) · 25 unmodified lines
14991386 /* mark it */
15001387 ilock(&q->lk);
15011388 bfirst = q->bfirst;
1502− q->bfirst = 0;
1389+ q->bfirst = nil;
15031390 q->len = 0;
15041391 q->dlen = 0;
15051392 iunlock(&q->lk);
@@ -1507,7 +1394,7 @@ qflush(Queue *q) · 1 unmodified line
15071394 /* free queued blocks */
15081395 freeblist(bfirst);
15091396
1510− /* wake up readers/writers */
1397+ /* wake up writers */
15111398 wakeup(&q->wr);
15121399 }
15131400
@@ -1516,9 +1403,3 @@ qfull(Queue *q) · 2 unmodified lines
15161403 {
15171404 return q->state & Qflow;
15181405 }
1519−
1520−int
1521−qstate(Queue *q)
1522−{
1523− return q->state;
1524−}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t