From def0bd0615970f31d47041dd2b05ca9dfd4fd7e3 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Wed, 14 Feb 2001 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2001-02-14 --- boot/boot.h | 1 + boot/bootip.c | 35 +++++----- boot/fcall.c | 171 ++++++++++++++++++++++++++++++++++++++++++++++++ port/chan.c | 1 - port/devsdp.c | 16 ++--- port/thwack.h | 1 + port/unthwack.c | 93 +++++++++++++++++++------- 7 files changed, 267 insertions(+), 51 deletions(-) create mode 100644 boot/fcall.c diff --git a/boot/boot.h b/boot/boot.h index 8cbded5ab0e3892056e2862de1f41159204d7abb..4cf8451980ecb1ebe825460572a53cd3f02e53d3 100644 --- a/boot/boot.h +++ b/boot/boot.h @@ -15,6 +15,7 @@ extern int cpuflag; extern char cputype[]; extern int fflag; extern int kflag; +extern int pushfcall(int); extern Method method[]; extern void (*pword)(int, Method*); extern char sys[]; diff --git a/boot/bootip.c b/boot/bootip.c index 5091eef39fc2d77f65b1d1fc3b4ae97f2da7270a..f9e7dbc98bccd65a0dab103ce2aad80abc24d0e8 100644 --- a/boot/bootip.c +++ b/boot/bootip.c @@ -97,54 +97,55 @@ configip(void) } void -configtcp(Method*) +configil(Method*) { - sleep(100); - print("t"); - sleep(100); configip(); - sleep(100); - print("."); - sleep(100); } int -authtcp(void) +authil(void) { - return -1; + char buf[2*NAMELEN]; + + sprint(buf, "il!%I!566", auip); + return dial(buf, 0, 0, 0); } int -connecttcp(void) +connectil(void) { char buf[2*NAMELEN]; - sprint(buf, "tcp!%I!564", fsip); + sprint(buf, "il!%I!17008", fsip); return dial(buf, 0, 0, 0); } void -configil(Method*) +configtcp(Method*) { configip(); } int -authil(void) +authtcp(void) { char buf[2*NAMELEN]; - sprint(buf, "il!%I!566", auip); + sprint(buf, "tcp!%I!567", auip); return dial(buf, 0, 0, 0); } int -connectil(void) +connecttcp(void) { char buf[2*NAMELEN]; + int fd; - sprint(buf, "il!%I!17008", fsip); - return dial(buf, 0, 0, 0); + sprint(buf, "tcp!%I!564", fsip); + fd = dial(buf, 0, 0, 0); + if(fd < 0) + return -1; + return pushfcall(fd); } static int diff --git a/boot/fcall.c b/boot/fcall.c new file mode 100644 index 0000000000000000000000000000000000000000..296ec670d69862c7cf80e141830bd4afd2d2af2c --- /dev/null +++ b/boot/fcall.c @@ -0,0 +1,171 @@ +#include +#include +#include +#include +#include + +#include "boot.h" + +/* + * reassemble 9P messages for stream based protocols + * interposed between devmnt and the network by srv for tcp connections + * fcall expects devmnt on fd0, network fd1 + */ +static uchar msglen[256] = +{ + [Tnop] 3, + [Rnop] 3, + [Tsession] 3+CHALLEN, + [Rsession] 3+NAMELEN+DOMLEN+CHALLEN, + [Terror] 0, + [Rerror] 67, + [Tflush] 5, + [Rflush] 3, + [Tattach] 5+2*NAMELEN+TICKETLEN+AUTHENTLEN, + [Rattach] 13+AUTHENTLEN, + [Tclone] 7, + [Rclone] 5, + [Twalk] 33, + [Rwalk] 13, + [Topen] 6, + [Ropen] 13, + [Tcreate] 38, + [Rcreate] 13, + [Tread] 15, + [Rread] 8, + [Twrite] 16, + [Rwrite] 7, + [Tclunk] 5, + [Rclunk] 5, + [Tremove] 5, + [Rremove] 5, + [Tstat] 5, + [Rstat] 121, + [Twstat] 121, + [Rwstat] 5, + [Tclwalk] 35, + [Rclwalk] 13, +}; + +enum +{ + Twritehdr = 16, /* Min bytes for Twrite */ + Rreadhdr = 8, /* Min bytes for Rread */ + Twritecnt = 13, /* Offset in byte stream of write count */ + Rreadcnt = 5, /* Offset for Readcnt */ +}; + +void +echo(int f, int t) +{ + int n; + char buf[MAXRPC]; + + for(;;) { + n = read9p(f, buf, MAXRPC); + if(n <= 0) + break; + if(write(t, buf, n) < n) + break; + } +} + +int +mntrpclen(uchar *d, int n) +{ + uchar t; + int len, off; + + if(n < 1) + return 0; + + t = d[0]; + switch(t) { /* This is the type */ + default: + len = msglen[t]; + if(len == 0) /* Illegal type so consume */ + return n; + if(n < len) + return 0; + return len; + case Twrite: /* Fmt: TGGFFOOOOOOOOCC */ + len = Twritehdr; /* T = type, G = tag, F = fid */ + off = Twritecnt; /* O = offset, C = count */ + break; + case Rread: /* Fmt: TGGFFCC */ + len = Rreadhdr; + off = Rreadcnt; + break; + } + if(n < off+2) + return 0; + + len += d[off]|(d[off+1]<<8); + if(n < len) + return 0; + + return len; +} + +int +pushfcall(int fd) +{ + int r, n, l, pfd[2]; + uchar *p, buf[MAXRPC]; + + if(pipe(pfd) < 0){ + fprint(2, "pipe: %r\n"); + exits("pipe"); + } + + /* Downstream is just a copy process */ + switch(rfork(RFPROC|RFFDG|RFMEM)){ + case 0: + close(pfd[1]); + echo(pfd[0], fd); + fprint(2, "echo finished\n"); + exits("echo done"); + case -1: + fprint(2, "fcall fork failed: %r\n"); + exits("fork"); + } + + switch(rfork(RFPROC|RFFDG|RFMEM)){ + default: + close(pfd[0]); + return pfd[1]; + case 0: + close(pfd[1]); + break; + case -1: + fprint(2, "fcall fork failed: %r\n"); + exits("fork"); + } + + /* Dispatch only full RPC's to the mount driver */ + l = MAXRPC; + p = buf; + for(;;) { + n = read(fd, p, l); + if(n < 0) + break; + p += n; + l -= n; + + for(;;) { + r = mntrpclen(buf, p - buf); + if(r == 0) + break; + + if(write(pfd[0], buf, r) < 0) + break; + + n = (p - buf) - r; + memmove(buf, buf+r, n); + p = buf+n; + l = MAXRPC - n; + } + } + abort(); + return 0; +} diff --git a/port/chan.c b/port/chan.c index b2ac2d67dadb79c1c6faefadfc1ada19256eaa6e..1c2a8f22e9f47f1652b85301cf51c25bbd1822dc 100644 --- a/port/chan.c +++ b/port/chan.c @@ -361,7 +361,6 @@ cunmount(Chan *mnt, Chan *mounted) mountfree(f); if(m->mount == nil) { *l = m->hash; - wunlock(&pg->ns); cclose(m->from); wunlock(&m->lock); putmhead(m); diff --git a/port/devsdp.c b/port/devsdp.c index d17c4843b0099547d2c8b786891dd9fb4b7a7469..f966136e2ff5d1412115515a315397bb251f97a6 100644 --- a/port/devsdp.c +++ b/port/devsdp.c @@ -99,8 +99,6 @@ struct OneWay int (*auth)(OneWay*, uchar *buf, int len); void *compstate; - ulong compseq; - ulong compwindow; int (*comp)(Conv*, int subtype, ulong seq, Block **); }; @@ -1310,8 +1308,6 @@ print("pad too big\n"); c->lstats.inBadComp++; return nil; } - c->in.compseq = c->in.seq; - c->in.compwindow = c->in.window; c->lstats.inDataBytes += BLEN(b); if(control) break; @@ -2238,13 +2234,17 @@ thwackcomp(Conv *c, int, ulong seq, Block **bp) { Block *b, *bb; int nn; + ulong ackseq; + uchar mask; // add ack info b = padblock(*bp, 4); - b->rp[0] = (c->in.compwindow>>1) & 0xff; - b->rp[1] = c->in.compseq>>16; - b->rp[2] = c->in.compseq>>8; - b->rp[3] = c->in.compseq; + + ackseq = unthwackstate(c->in.compstate, &mask); + b->rp[0] = mask; + b->rp[1] = ackseq>>16; + b->rp[2] = ackseq>>8; + b->rp[3] = ackseq; bb = allocb(BLEN(b)); nn = thwack(c->out.compstate, bb->wp, b->rp, BLEN(b), seq, c->lstats.outCompStats); diff --git a/port/thwack.h b/port/thwack.h index 024f24f073b1148b15aa817ef1c530abf3d69a8b..d50c47c23c26a365a1522111dd7ddd377780fb4e 100644 --- a/port/thwack.h +++ b/port/thwack.h @@ -65,3 +65,4 @@ void unthwackinit(Unthwack*); int thwack(Thwack*, uchar *dst, uchar *src, int nsrc, ulong seq, ulong stats[ThwStats]); void thwackack(Thwack*, ulong seq, ulong mask); int unthwack(Unthwack*, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq); +ulong unthwackstate(Unthwack *ut, uchar *mask); diff --git a/port/unthwack.c b/port/unthwack.c index f0faae362a7be898129e882b0a76d3d14cd7c068..3c8f40f5c1a3415309590a171e3c7d26703ea69e 100644 --- a/port/unthwack.c +++ b/port/unthwack.c @@ -59,39 +59,86 @@ unthwackinit(Unthwack *ut) ut->blocks[i].data = ut->data[i]; } -int -unthwack(Unthwack *ut, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq) +ulong +unthwackstate(Unthwack *ut, uchar *mask) { - UnthwBlock blocks[CompBlocks], *b, *eblocks; - uchar *s, *d, *dmax, *smax, lit; - ulong cmask, cseq, bseq, utbits, lithist; - int i, off, len, bits, slot, tslot, use, code, utnbits, overbits; + ulong bseq, seq; + int slot, m; - if(nsrc < 4 || nsrc > ThwMaxBlock) - return -1; + seq = ~0UL; + m = 0; + slot = ut->slot; + for(;;){ + slot--; + if(slot < 0) + slot += DWinBlocks; + if(slot == ut->slot) + break; + if(ut->blocks[slot].maxoff == 0) + continue; + bseq = ut->blocks[slot].seq; + if(seq == ~0UL) + seq = bseq; + else if(seq - bseq > MaxSeqMask) + break; + else + m |= 1 << (seq - bseq - 1); + } + *mask = m; + return seq; +} + +/* + * insert this block in it's correct sequence number order. + * replace the oldest block, which is always pointed to by ut->slot. + * the encoder doesn't use a history at wraparound, + * so don't worry about that case. + */ +static int +unthwackinsert(Unthwack *ut, int len, ulong seq) +{ + uchar *d; + int slot, tslot; - /* - * insert this block in it's correct sequence number order. - * replace the oldest block, which is always pointed to by ut->slot. - * the encoder doesn't use a history at wraparound, - * so don't worry about that case. - */ tslot = ut->slot; for(;;){ slot = tslot - 1; if(slot < 0) slot += DWinBlocks; - if(ut->blocks[slot].seq <= seq) + if(ut->blocks[slot].seq <= seq || ut->blocks[slot].maxoff == 0) break; d = ut->blocks[tslot].data; ut->blocks[tslot] = ut->blocks[slot]; ut->blocks[slot].data = d; tslot = slot; } - b = blocks; ut->blocks[tslot].seq = seq; - ut->blocks[tslot].maxoff = 0; - *b = ut->blocks[tslot]; + ut->blocks[tslot].maxoff = len; + + ut->slot++; + if(ut->slot >= DWinBlocks) + ut->slot = 0; + + ut->blocks[ut->slot].seq = ~0UL; + ut->blocks[ut->slot].maxoff = 0; + + return tslot; +} + +int +unthwack(Unthwack *ut, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq) +{ + UnthwBlock blocks[CompBlocks], *b, *eblocks; + uchar *s, *d, *dmax, *smax, lit; + ulong cmask, cseq, bseq, utbits; + int i, off, len, bits, slot, use, code, utnbits, overbits, lithist; + + if(nsrc < 4 || nsrc > ThwMaxBlock) + return -1; + + slot = ut->slot; + b = blocks; + *b = ut->blocks[slot]; d = b->data; dmax = d + ndst; @@ -101,7 +148,6 @@ unthwack(Unthwack *ut, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq) cseq = seq - src[0]; cmask = src[1]; b++; - slot = tslot; while(cseq != seq && b < blocks + CompBlocks){ slot--; if(slot < 0) @@ -125,8 +171,8 @@ unthwack(Unthwack *ut, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq) } eblocks = b; if(cseq != seq){ - print("blocks not in decompression window: cseq=%ld seq=%ld cmask=%lx nb=%ld\n", cseq, seq, cmask, eblocks - blocks); - return -1; + print("blocks dropped: seq=%ld cseq=%ld %d cmask=%#lx %#x\n", seq, cseq, src[0], cmask, src[1]); + return -2; } smax = src + nsrc; @@ -244,11 +290,8 @@ unthwack(Unthwack *ut, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq) len = d - blocks->data; memmove(dst, blocks->data, len); - ut->blocks[tslot].maxoff = len; - ut->slot++; - if(ut->slot >= DWinBlocks) - ut->slot = 0; + unthwackinsert(ut, len, seq); return len; }