From 64e77d4402970c246d0847745b7fe8dfd4d8dc70 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Wed, 14 Aug 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-08-14 --- gnot/dat.h | 2 +- gnot/trap.c | 14 ++++- pc/devhard.c | 167 +++++++++++++++++++++++++++----------------------- pc/trap.c | 10 +++ port/devmnt.c | 98 ++++++++++++++++++----------- power/trap.c | 14 ++++- ss/trap.c | 14 ++++- 7 files changed, 196 insertions(+), 123 deletions(-) diff --git a/gnot/dat.h b/gnot/dat.h index a26445cc5eb721a74fdff7a0d222b19c72106aac..a6fb38a5f395e388410cde432db3ef0da395c166 100644 --- a/gnot/dat.h +++ b/gnot/dat.h @@ -200,7 +200,7 @@ struct Scsi uchar cmdblk[16]; }; -#define NERR 15 +#define NERR 25 #define NNOTE 5 struct User { diff --git a/gnot/trap.c b/gnot/trap.c index d094d9a9f03f27a28b5dae4746e795c5cc8069fa..03c312f2e6122091b22ddab0fed1cce6ee702b14 100644 --- a/gnot/trap.c +++ b/gnot/trap.c @@ -199,21 +199,29 @@ noted(Ureg *ur, ulong arg0) Ureg *nur; nur = u->ureg; - validaddr(nur->pc, 1, 0); - validaddr(nur->usp, BY2WD, 0); if(nur->sr!=u->svsr || nur->vo!=u->svvo){ pprint("bad noted ureg sr %ux vo %ux\n", nur->sr, nur->vo); + Die: pexit("Suicide", 0); } lock(&u->p->debug); if(!u->notified){ unlock(&u->p->debug); - return; + pprint("call to noted() when not notified\n"); + goto Die; } u->notified = 0; memmove(ur, u->ureg, sizeof(Ureg)); switch(arg0){ case NCONT: + if(waserror()){ + pprint("suicide: trap in noted\n"); + unlock(&u->p->debug); + goto Die; + } + validaddr(nur->pc, 1, 0); + validaddr(nur->usp, BY2WD, 0); + poperror(); splhi(); unlock(&u->p->debug); rfnote(ur); diff --git a/pc/devhard.c b/pc/devhard.c index 257b2197bff77a8ae56e08622b04034a6b730f04..4016b6617d207a67e0f7a21313a155eed3361577 100644 --- a/pc/devhard.c +++ b/pc/devhard.c @@ -10,7 +10,6 @@ typedef struct Drive Drive; typedef struct Ident Ident; typedef struct Controller Controller; typedef struct Partition Partition; -typedef struct Ptable Ptable; enum { @@ -45,7 +44,7 @@ enum Qmask= (3<<(3+3)), Maxxfer= 4*1024, /* maximum transfer size/cmd */ - Npart= 8+1, /* 8 sub partitions and one for the disk */ + Npart= 8+2, /* 8 sub partitions, disk, and partiiton */ }; #define PART(x) ((x)&0x3) #define DRIVE(x) (((x)>>3)&0x7) @@ -93,19 +92,7 @@ struct Partition { ulong start; ulong end; - uchar name[NAMELEN]; -}; - -struct Ptable -{ - uchar magic[4]; /* ascii "disk" */ - uchar n[4]; /* number of partitions */ - struct - { - uchar start[4]; /* starting block */ - uchar end[4]; /* ending block */ - uchar name[NAMELEN]; - } p[1]; + char name[NAMELEN+1]; }; /* @@ -159,11 +146,9 @@ struct Controller Controller *hardc; Drive *hard; -Dirtab *harddir; -#define NHDIR 2 /* directory entries/drive */ static void hardintr(Ureg*); -static long hardxfer(Drive*, int, void*, long, long); +static long hardxfer(Drive*, Partition*, int, void*, long, long); static long hardident(Drive*); static void hardsetbuf(Drive*, int); static void hardpart(Drive*); @@ -173,33 +158,30 @@ hardgen(Chan *c, Dirtab *tab, long ntab, long s, Dir *dirp) { Qid qid; int drive; - char *name; + char name[NAMELEN]; Drive *dp; Partition *pp; ulong l; qid.vers = 0; - drive = s/(Npart+1); - s = s % (Npart+1); + drive = s/Npart; + s = s % Npart; if(drive >= conf.nhard) return -1; dp = &hard[drive]; - if(s == 0){ - sprint(name, "hd%dparition", drive); - qid.path = MKQID(Qpart, drive, 0); - l = dp->npart * sizeof(Partition); - } else if(s-1 < p.npart){ - pp = &dp->p[s-1]; + if(s < dp->npart){ + pp = &dp->p[s]; sprint(name, "hd%d%s", drive, pp->name); - qid.path = MKQID(Qdata, drive, s-1); - l = (pp->end - pp->start) * dp->cp->bytes; + qid.path = MKQID(Qdata, drive, s); + l = (pp->end - pp->start) * dp->bytes; } else return 0; devdir(c, qid, name, l, 0600, dirp); return 1; } + /* * we assume drives 0 and 1 are on the first controller, 2 and 3 on the * second, etc. @@ -210,11 +192,9 @@ hardreset(void) Drive *dp; Controller *cp; int drive; - Dirtab *dir; hard = ialloc(conf.nhard * sizeof(Drive), 0); hardc = ialloc(((conf.nhard+1)/2 + 1) * sizeof(Controller), 0); - dir = harddir = ialloc(NHDIR * conf.nhard * sizeof(Dirtab), 0); for(drive = 0; drive < conf.nhard; drive++){ dp = &hard[drive]; @@ -228,16 +208,6 @@ hardreset(void) cp->pbase = Pbase + (cp-hardc)*8; /* BUG!! guessing */ setvec(Hardvec + (cp-hardc)*8, hardintr); /* BUG!! guessing */ } - sprint(harddir[drive*2].name, "hd%ddata", drive); - dir->length = 0; - dir->qid.path = Qdata + drive; - dir->perm = 0600; - dir++; - sprint(dir->name, "hd%dstruct", drive); - dir->length = 8; - dir->qid.path = Qstruct + drive; - dir->perm = 0600; - dir++; } } @@ -260,14 +230,13 @@ hardattach(char *spec) dp->bytes = 512; hardsetbuf(dp, 1); hardident(dp); - hardpart(dp); dp->cyl = dp->id.lcyls; dp->heads = dp->id.lheads; dp->sectors = dp->id.ls2t; dp->bytes = 512; dp->cap = dp->bytes * dp->cyl * dp->heads * dp->sectors; - harddir[NHDIR*dp->drive].length = dp->cap; dp->online = 1; + hardpart(dp); poperror(); } else dp->online = 0; @@ -285,19 +254,19 @@ hardclone(Chan *c, Chan *nc) int hardwalk(Chan *c, char *name) { - return devwalk(c, name, harddir, conf.nhard*NHDIR, devgen); + return devwalk(c, name, 0, 0, hardgen); } void hardstat(Chan *c, char *dp) { - devstat(c, dp, harddir, conf.nhard*NHDIR, devgen); + devstat(c, dp, 0, 0, hardgen); } Chan* hardopen(Chan *c, int omode) { - return devopen(c, omode, harddir, conf.nhard*NHDIR, devgen); + return devopen(c, omode, 0, 0, hardgen); } void @@ -323,43 +292,29 @@ hardwstat(Chan *c, char *dp) error(Eperm); } -static void -ul2user(uchar *a, ulong x) -{ - a[0] = x >> 24; - a[1] = x >> 16; - a[2] = x >> 8; - a[3] = x; -} - long hardread(Chan *c, void *a, long n) { Drive *dp; long rv, i; uchar *aa = a; + Partition *pp; if(c->qid.path == CHDIR) - return devdirread(c, a, n, harddir, conf.nhard*NHDIR, devgen); + return devdirread(c, a, n, 0, 0, hardgen); rv = 0; dp = &hard[c->qid.path & ~Qmask]; switch ((int)(c->qid.path & Qmask)) { case Qdata: for(rv = 0; rv < n; rv += i){ - i = hardxfer(dp, Cread, aa+rv, c->offset+rv, n-rv); + pp = &dp->p[PART(c->qid.path)]; + i = hardxfer(dp, pp, Cread, aa+rv, c->offset+rv, n-rv); if(i <= 0) break; } break; - case Qstruct: - if (n < 2*sizeof(ulong)) - error(Ebadarg); - if (c->offset >= 2*sizeof(ulong)) - return 0; - rv = 2*sizeof(ulong); - ul2user((uchar*)a, dp->cap); - ul2user((uchar*)a+sizeof(ulong), dp->bytes); + case Qpart: break; default: panic("hardread: bad qid"); @@ -373,19 +328,20 @@ hardwrite(Chan *c, void *a, long n) Drive *dp; long rv, i; uchar *aa = a; + Partition *pp; rv = 0; dp = &hard[c->qid.path & ~Qmask]; switch ((int)(c->qid.path & Qmask)) { case Qdata: for(rv = 0; rv < n; rv += i){ - i = hardxfer(dp, Cwrite, aa+rv, c->offset+rv, n-rv); + pp = &dp->p[PART(c->qid.path)]; + i = hardxfer(dp, pp, Cwrite, aa+rv, c->offset+rv, n-rv); if(i <= 0) break; } break; - case Qstruct: - error(Eperm); + case Qpart: break; default: panic("hardwrite: bad qid"); @@ -425,7 +381,7 @@ print("cmdreadywait failed\n"); * parts. */ static long -hardxfer(Drive *dp, int cmd, void *va, long off, long len) +hardxfer(Drive *dp, Partition *pp, int cmd, void *va, long off, long len) { Controller *cp; int err; @@ -439,6 +395,9 @@ hardxfer(Drive *dp, int cmd, void *va, long off, long len) if(off % dp->bytes) errors("bad offset"); /* BUG - this shouldn't be a problem */ +print("hardxfer %ld %ld\n", off, len); +print("hardxfer part %s %ld %ld\n", pp->name, pp->start, pp->end); + cp = dp->cp; qlock(cp); if(waserror()){ @@ -450,6 +409,9 @@ hardxfer(Drive *dp, int cmd, void *va, long off, long len) * calculate the physical address of off */ lsec = off/dp->bytes; + lsec += pp->start; + if(lsec >= pp->end) + errors("xfer past end of partition\n"); cp->tcyl = lsec/(dp->sectors*dp->heads); cp->tsec = (lsec % dp->sectors) + 1; cp->thead = (lsec/dp->sectors) % dp->heads; @@ -458,6 +420,9 @@ hardxfer(Drive *dp, int cmd, void *va, long off, long len) * can't xfer across cylinder boundaries. */ lsec = (off+len)/dp->bytes; + lsec += pp->start; + if(lsec > pp->end) + errors("xfer past end of partition\n"); cyl = lsec/(dp->sectors*dp->heads); if(cyl == cp->tcyl) cp->len = len; @@ -515,6 +480,7 @@ hardsetbuf(Drive *dp, int on) cmdreadywait(cp); + cp->cmd = Csetbuf; outb(cp->pbase+Pprecomp, on ? 0xAA : 0x55); outb(cp->pbase+Pdh, (dp->drive<<4)); outb(cp->pbase+Pcmd, Csetbuf); @@ -536,6 +502,7 @@ hardident(Drive *dp) cp = dp->cp; qlock(cp); if(waserror()){ +print("waserror in hardident\n"); qunlock(cp); nexterror(); } @@ -566,24 +533,64 @@ print("bad disk magic\n"); } /* - * read partition table + * read partition table. The partition table is just ascii strings. */ +#define MAGIC "plan9 partitions" static void hardpart(Drive *dp) { Partition *pp; - Ptable *pt; - uchar buf[1024]; + char *line[Npart+1]; + char *field[3]; + char buf[1024]; + ulong n; + int i; pp = &dp->p[0]; strcpy(pp->name, "disk"); pp->start = 0; - pp->end = pp->cap / dp->bytes; + pp->end = dp->cap / dp->bytes; + pp++; + strcpy(pp->name, "partition"); + pp->start = dp->p[0].end - 1; + pp->end = dp->p[0].end; + dp->npart = 2; - qlock(dp->cp); - hardxfer(dp, Cread, buf, pp->end - 1, dp->bytes); - - qunlock(dp->cp); + if(waserror()){ + print("error in hardpart\n"); + nexterror(); + } + + hardxfer(dp, pp, Cread, buf, (pp->end - 1)*dp->bytes, dp->bytes); + buf[dp->bytes] = 0; + + n = getfields(buf, line, Npart+1, '\n'); + if(strncmp(line[0], MAGIC, sizeof(MAGIC)-1) != 0){ + print("bad partition table 1\n"); + goto out; + } + for(i = 1; i < n; i++){ + pp++; + if(getfields(line[i], field, 3, 0) != 3){ + print("bad partition field\n"); + goto out; + } + if(strlen(field[0]) > NAMELEN){ + print("bad partition name\n"); + goto out; + } + strcpy(pp->name, field[0]); + pp->start = strtoul(field[1], 0, 0); + pp->end = strtoul(field[2], 0, 0); + if(pp->start > pp->end || pp->start >= dp->p[0].end){ + print("bad partition limit\n"); + goto out; + } +print("partition %s from %d to %d\n", pp->name, pp->start, pp->end); + dp->npart++; + } +out: + poperror(); } /* @@ -642,8 +649,12 @@ hardintr(Ureg *ur) wakeup(&cp->r); } break; + case Csetbuf: + cp->cmd = 0; + wakeup(&cp->r); + break; default: - print("wierd disk interrupt\n"); + print("weird disk interrupt\n"); break; } } diff --git a/pc/trap.c b/pc/trap.c index c8893d99c30812211c2b163806bad78a371348ea..409c93c17a09c695c640d0281ced8755e557a749 100644 --- a/pc/trap.c +++ b/pc/trap.c @@ -373,10 +373,12 @@ noted(Ureg *ur, ulong arg0) || (nur->flags&0xff00)!=(u->svflags&0xff00)){ pprint("bad noted ureg cs %ux ss %ux flags %ux\n", nur->cs, nur->ss, nur->flags); + Die: pexit("Suicide", 0); } lock(&u->p->debug); if(!u->notified){ + pprint("call to noted() when not notified\n"); unlock(&u->p->debug); return; } @@ -385,6 +387,14 @@ noted(Ureg *ur, ulong arg0) memmove(ur, u->ureg, sizeof(Ureg)); switch(arg0){ case NCONT: + if(waserror()){ + pprint("suicide: trap in noted\n"); + unlock(&u->p->debug); + goto Die; + } + validaddr(nur->pc, 1, 0); + validaddr(nur->usp, BY2WD, 0); + poperror(); unlock(&u->p->debug); return; diff --git a/port/devmnt.c b/port/devmnt.c index 6ea1a63b2b3886fc6a3be5c801424d41dcf79e79..3e74e67453072c0100579bdd0a2fa7fa28a120be 100644 --- a/port/devmnt.c +++ b/port/devmnt.c @@ -9,7 +9,7 @@ #include "fcall.h" -#define NTAG 16384 /* 1 <= tag <= NTAG */ +#define NTAG 65536 /* 1 <= tag < NTAG */ typedef struct Mnt Mnt; typedef struct Mnthdr Mnthdr; @@ -52,8 +52,9 @@ struct Mnthdr { Mnthdr *next; /* in free list or writers list */ Mnthdr *prev; /* in writers list only */ - short active; - short flushing; /* a Tflush has been sent */ + char active; + char flushing; /* a Tflush has been sent */ + short seq; Fcall thdr; Fcall rhdr; Rendez r; @@ -66,7 +67,8 @@ struct { Lock; Mnthdr *arena; - Mnthdr *free; + Mnthdr *head; + Mnthdr *tail; }mnthdralloc; struct @@ -85,7 +87,6 @@ struct Mnt *mnt; void mntxmit(Mnt*, Mnthdr*); -Ref mnttag; Mntbuf* mballoc(void) @@ -119,17 +120,27 @@ mbfree(Mntbuf *mb) } Mnthdr* -mhalloc(void) +mhalloc(Mnt *m) { Mnthdr *mh; + int seq; loop: lock(&mnthdralloc); - if(mh = mnthdralloc.free){ /* assign = */ - mnthdralloc.free = mh->next; - mh->mbr = 0; - mh->thdr.tag = 1 + (incref(&mnttag) & (NTAG-1)); + if(mh = mnthdralloc.head){ /* assign = */ + mnthdralloc.head = mh->next; + if(mnthdralloc.head) + mnthdralloc.head->prev = 0; + else + mnthdralloc.tail = 0; unlock(&mnthdralloc); + mh->mbr = 0; + seq = ++mh->seq; + if(seq == (1<<7)){ + mh->seq = 1; + seq = 1; + } + mh->thdr.tag = (((mh-mnthdralloc.arena)<<7)|seq) & (NTAG-1); return mh; } unlock(&mnthdralloc); @@ -150,8 +161,13 @@ mhfree(Mnthdr *mh) lock(&mnthdralloc); mh->active = 0; mh->thdr.tag = 0; - mh->next = mnthdralloc.free; - mnthdralloc.free = mh; + mh->next = 0; + mh->prev = mnthdralloc.tail; + if(mnthdralloc.tail) + mnthdralloc.tail->next = mh; + else + mnthdralloc.head = mh; + mnthdralloc.tail = mh; unlock(&mnthdralloc); } @@ -217,27 +233,39 @@ mntreset(void) Mnthdr *mh; MntQ *mq; + if(conf.nmnthdr > 512){ + print("conf.nmnthdr is %d set to 512\n", conf.nmnthdr); + conf.nmnthdr = 512; + } mnt = ialloc(conf.nmntdev*sizeof(Mnt), 0); mb = ialloc(conf.nmntbuf*sizeof(Mntbuf), 0); - for(i=0; inext = mb+1; + --mb; + mb->next = 0; mh = ialloc(conf.nmnthdr*sizeof(Mnthdr), 0); - for(i=0; iseq = 0; + mh->next = mh+1; + mh->prev = mh-1; + } + --mh; + mnthdralloc.tail = mh; + mh->next = 0; + mnthdralloc.head->prev = 0; mq = ialloc(conf.nmntdev*sizeof(MntQ), 0); - for(i=0; inext = mq+1; + --mq; + mq->next = 0; } void @@ -302,7 +330,7 @@ mntattach(char *crud) out: qunlock(&mntqalloc); - mh = mhalloc(); + mh = mhalloc(m); if(waserror()){ mhfree(mh); close(c); @@ -339,7 +367,7 @@ mntclone(Chan *c, Chan *nc) } } m = mntdev(c, 0); - mh = mhalloc(); + mh = mhalloc(m); if(waserror()){ mhfree(mh); nexterror(); @@ -377,7 +405,7 @@ mntwalk(Chan *c, char *name) found = 1; m = mntdev(c, 0); - mh = mhalloc(); + mh = mhalloc(m); mh->thdr.type = Twalk; mh->thdr.fid = c->fid; strcpy(mh->thdr.name, name); @@ -400,7 +428,7 @@ mntstat(Chan *c, char *dp) Mnthdr *mh; m = mntdev(c, 0); - mh = mhalloc(); + mh = mhalloc(m); if(waserror()){ mhfree(mh); nexterror(); @@ -424,7 +452,7 @@ mntopen(Chan *c, int omode) Mnthdr *mh; m = mntdev(c, 0); - mh = mhalloc(); + mh = mhalloc(m); if(waserror()){ mhfree(mh); nexterror(); @@ -449,7 +477,7 @@ mntcreate(Chan *c, char *name, int omode, ulong perm) Mnthdr *mh; m = mntdev(c, 0); - mh = mhalloc(); + mh = mhalloc(m); if(waserror()){ mhfree(mh); nexterror(); @@ -477,7 +505,7 @@ mntclunk(Chan *c, int t) int waserr; m = mntdev(c, 0); - mh = mhalloc(); + mh = mhalloc(m); mh->thdr.type = t; mh->thdr.fid = c->fid; waserr = 0; @@ -519,7 +547,7 @@ mntreadwrite(Chan *c, void *vbuf, long n, int type, ulong offset) buf = vbuf; count = 0; m = mntdev(c, 0); - mh = mhalloc(); + mh = mhalloc(m); if(waserror()){ mhfree(mh); nexterror(); @@ -585,7 +613,7 @@ mntwstat(Chan *c, char *dp) Mnthdr *mh; m = mntdev(c, 0); - mh = mhalloc(); + mh = mhalloc(m); if(waserror()){ mhfree(mh); nexterror(); @@ -626,7 +654,7 @@ mntflush(Mnt *m, Mnthdr *omh) /* queue is unlocked */ return; } - mh = mhalloc(); + mh = mhalloc(m); if(waserror()){ omh->flushing = 0; mhfree(mh); @@ -814,7 +842,7 @@ mntxmit(Mnt *m, Mnthdr *mh) if(tag == mh->thdr.tag){ /* it's mine */ if(mh->rhdr.type != Rerror) if(mh->rhdr.type != mh->thdr.type+1){ - print("mail rob: '%s T(%d)%c %d %d'\n", u->p->text, + print("mail rob: '%s xxT(%d)%c %d %d'\n", u->p->text, tag, devchar[m->q->msg->type], mh->rhdr.type, mh->thdr.type+1); goto FreeRead; @@ -835,7 +863,7 @@ mntxmit(Mnt *m, Mnthdr *mh) /* * Hand response to correct recipient */ - if(tag<=0 || tag>NTAG){ + if(tag==0 || tag>=NTAG){ print("unknown tag %d\n", tag); FreeRead: mbfree(mh->mbr); @@ -854,7 +882,7 @@ mntxmit(Mnt *m, Mnthdr *mh) goto FreeRead; if(mh->rhdr.type != Rerror) if(mh->rhdr.type != w->thdr.type+1){ - print("mail rob: '%s w(%d)%c %d %d'\n", + print("mail rob: '%s xxw(%d)%c %d %d'\n", u->p->text, tag, devchar[m->q->msg->type], mh->rhdr.type, w->thdr.type+1); goto FreeRead; diff --git a/power/trap.c b/power/trap.c index fbec0bdd2a9d0458c7d5f2b9ced2c33928e9bdce..261c37ed0bf5a942a34d0395e9a52764ec74ef49 100644 --- a/power/trap.c +++ b/power/trap.c @@ -426,21 +426,29 @@ noted(Ureg **urp, ulong arg0) Ureg *nur; nur = u->ureg; - validaddr(nur->pc, 1, 0); - validaddr(nur->usp, BY2WD, 0); if(nur->status!=u->svstatus){ pprint("bad noted ureg status %lux\n", nur->status); + Die: pexit("Suicide", 0); } lock(&u->p->debug); if(!u->notified){ unlock(&u->p->debug); - return; + pprint("call to noted() when not notified\n"); + goto Die; } u->notified = 0; memmove(*urp, u->ureg, sizeof(Ureg)); switch(arg0){ case NCONT: + if(waserror()){ + pprint("suicide: trap in noted\n"); + unlock(&u->p->debug); + goto Die; + } + validaddr(nur->pc, 1, 0); + validaddr(nur->usp, BY2WD, 0); + poperror(); splhi(); unlock(&u->p->debug); rfnote(urp); diff --git a/ss/trap.c b/ss/trap.c index 68810afcd3ab4325c0e643940af4e4f2b35202e4..5da7f57fa0abce8354c21859b030a93df9d24f03 100644 --- a/ss/trap.c +++ b/ss/trap.c @@ -272,21 +272,29 @@ noted(Ureg **urp, ulong arg0) Ureg *nur; nur = u->ureg; - validaddr(nur->pc, 1, 0); - validaddr(nur->usp, BY2WD, 0); if(nur->psr!=u->svpsr){ pprint("bad noted ureg psr %lux\n", nur->psr); + Die: pexit("Suicide", 0); } lock(&u->p->debug); if(!u->notified){ unlock(&u->p->debug); - return; + pprint("call to noted() when not notified\n"); + goto Die; } u->notified = 0; memmove(*urp, u->ureg, sizeof(Ureg)); switch(arg0){ case NCONT: + if(waserror()){ + pprint("suicide: trap in noted\n"); + unlock(&u->p->debug); + goto Die; + } + validaddr(nur->pc, 1, 0); + validaddr(nur->usp, BY2WD, 0); + poperror(); splhi(); unlock(&u->p->debug); rfnote(urp);