From 7dbdf51ceed61f04b3bc019ab419814a7a12144e Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 29 Aug 1998 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1998-08-29 --- ip/kio.c | 2 +- pc/vgacyber938x.c | 44 +++++------------- port/chan.c | 114 ++++++++++++++++++++++++++++++---------------- port/dev.c | 4 +- port/devcons.c | 6 +-- port/devmnt.c | 2 +- port/pgrp.c | 8 +++- port/portdat.h | 7 ++- port/portfns.h | 1 + port/sysfile.c | 37 ++++++++------- 10 files changed, 124 insertions(+), 101 deletions(-) diff --git a/ip/kio.c b/ip/kio.c index 96dcc2af727ded690147437606e65b0796014cec..a80352cba034650f50a1c5410bb409554afb0e3f 100644 --- a/ip/kio.c +++ b/ip/kio.c @@ -69,7 +69,7 @@ kread(int fd, void *va, long n) error(Etoosmall); } - if(dir && c->mnt) + if(dir && c->mh) n = unionread(c, va, n); else if(devtab[c->type]->dc != L'M') n = devtab[c->type]->read(c, va, n, c->offset); diff --git a/pc/vgacyber938x.c b/pc/vgacyber938x.c index 00309ec1c7b35f1fba770ce3ad24eb68c84b94e1..96b6ddffc9204e97d27692595b504e76a940c116 100644 --- a/pc/vgacyber938x.c +++ b/pc/vgacyber938x.c @@ -11,6 +11,11 @@ #include #include "screen.h" +enum { + CursorON = 0xC8, + CursorOFF = 0x00, +}; + static int cyber938xpageset(VGAscr*, int page) { @@ -67,7 +72,7 @@ cyber938xlinear(VGAscr* scr, int* size, int* align) static void cyber938xcurdisable(VGAscr*) { - vgaxo(Crtx, 0x50, 0); + vgaxo(Crtx, 0x50, CursorOFF); } static void @@ -94,39 +99,12 @@ cyber938xcurload(VGAscr* scr, Cursor* curs) *p++ = curs->set[2*y + 1]|curs->clr[2*y + 1]; *p++ = 0x00; *p++ = 0x00; - } - while(y < 32){ - *p++ = 0x00; - *p++ = 0x00; - *p++ = 0x00; - *p++ = 0x00; - y++; - } - - /* - * This is clearly not what's supposed to be done, but - * without a proper datasheet this is what binary search - * through the display memory gives as the place for the - * pattern. - * Note also that it seems the cursor image offset (CRT44 - * and CRT45) cannot be set above 512KB. - * This will do for now as the ThinkPad 560E has 1MB and - * can only manage 800x600x8. - */ - p += 512*1024 - 128; - for(y = 0; y < 16; y++){ *p++ = curs->set[2*y]; *p++ = curs->set[2*y + 1]; *p++ = 0x00; *p++ = 0x00; } - while(y < 32){ - *p++ = 0x00; - *p++ = 0x00; - *p++ = 0x00; - *p++ = 0x00; - y++; - } + memset(p, 0, (32-y)*8); if(!islinear){ cyber938xpageset(scr, opage); @@ -137,7 +115,7 @@ cyber938xcurload(VGAscr* scr, Cursor* curs) * Save the cursor hotpoint and enable the cursor. */ scr->offset = curs->offset; - vgaxo(Crtx, 0x50, 0xC8); + vgaxo(Crtx, 0x50, CursorON); } static int @@ -195,10 +173,10 @@ cyber938xcurenable(VGAscr* scr) /* * Find a place for the cursor data in display memory. */ - storage = ((scr->gscreen->width*BY2WD*scr->gscreen->r.max.y+1023)/1024)*2; + storage = ((scr->gscreen->width*BY2WD*scr->gscreen->r.max.y+1023)/1024); vgaxo(Crtx, 0x44, storage & 0xFF); vgaxo(Crtx, 0x45, (storage>>8) & 0xFF); - storage *= 512; + storage *= 1024; scr->storage = storage; /* @@ -209,7 +187,7 @@ cyber938xcurenable(VGAscr* scr) */ cyber938xcurload(scr, &arrow); cyber938xcurmove(scr, ZP); - vgaxo(Crtx, 0x50, 0xC8); + vgaxo(Crtx, 0x50, CursorON); } VGAdev vgacyber938xdev = { diff --git a/port/chan.c b/port/chan.c index 2de9a71169e40746bd59f12551dbc614732efada..176e07ea626351b8b0f9adf5993e90c18fe89ca4 100644 --- a/port/chan.c +++ b/port/chan.c @@ -95,7 +95,9 @@ newchan(void) c->ref = 1; c->dev = 0; c->offset = 0; - c->mnt = 0; + c->mh = 0; + c->xmh = 0; + c->uri = 0; c->aux = 0; c->mchan = 0; c->path = 0; @@ -114,6 +116,11 @@ chanfree(Chan *c) c->session = 0; } + if(c->mh != nil){ + putmhead(c->mh); + c->mh = nil; + } + /* * Channel can be closed before a path is created or the last * channel in a mount which has already cleared its pt names @@ -187,10 +194,6 @@ cmount(Chan *new, Chan *old, int flag, char *spec) pg = up->pgrp; wlock(&pg->ns); - if(waserror()) { - wunlock(&pg->ns); - nexterror(); - } l = &MOUNTH(pg, old); for(m = *l; m; m = m->hash) { @@ -205,6 +208,7 @@ cmount(Chan *new, Chan *old, int flag, char *spec) * head and add to the hash table. */ m = smalloc(sizeof(Mhead)); + m->ref = 1; m->from = old; incref(old); m->hash = *l; @@ -217,9 +221,15 @@ cmount(Chan *new, Chan *old, int flag, char *spec) if(order != MREPL) m->mount = newmount(m, old, 0, 0); } + wlock(&m->lock); + if(waserror()){ + wunlock(&m->lock); + nexterror(); + } + wunlock(&pg->ns); nm = newmount(m, new, flag, spec); - if(new->mnt != 0) { + if(new->mh != nil && new->mh->mount != nil) { /* * copy a union when binding it onto a directory */ @@ -227,7 +237,8 @@ cmount(Chan *new, Chan *old, int flag, char *spec) if(order == MREPL) flg = MAFTER; h = &nm->next; - for(um = new->mnt->next; um; um = um->next) { + um = new->mh->mount; + for(um = um->next; um; um = um->next) { f = newmount(m, um->to, flg, um->spec); *h = f; h = &f->next; @@ -254,7 +265,7 @@ cmount(Chan *new, Chan *old, int flag, char *spec) m->mount = nm; } - wunlock(&pg->ns); + wunlock(&m->lock); poperror(); return nm->mountid; } @@ -281,14 +292,18 @@ cunmount(Chan *mnt, Chan *mounted) error(Eunmount); } + wlock(&m->lock); if(mounted == 0) { *l = m->hash; wunlock(&pg->ns); mountfree(m->mount); + m->mount = nil; cclose(m->from); - free(m); + wunlock(&m->lock); + putmhead(m); return; } + wunlock(&pg->ns); p = &m->mount; for(f = *p; f; f = f->next) { @@ -298,19 +313,20 @@ cunmount(Chan *mnt, Chan *mounted) *p = f->next; f->next = 0; mountfree(f); - if(m->mount == 0) { + if(m->mount == nil) { *l = m->hash; wunlock(&pg->ns); cclose(m->from); - free(m); + wunlock(&m->lock); + putmhead(m); return; } - wunlock(&pg->ns); + wunlock(&m->lock); return; } p = &f->next; } - wunlock(&pg->ns); + wunlock(&m->lock); error(Eunion); } @@ -329,24 +345,34 @@ domount(Chan *c) pg = up->pgrp; rlock(&pg->ns); - if(waserror()) { - runlock(&pg->ns); - nexterror(); + if(c->mh){ + putmhead(c->mh); + c->mh = 0; } - c->mnt = 0; - for(m = MOUNTH(pg, c); m; m = m->hash) + for(m = MOUNTH(pg, c); m; m = m->hash){ + rlock(&m->lock); if(eqchan(m->from, c, 1)) { + if(waserror()) { + runlock(&m->lock); + nexterror(); + } + runlock(&pg->ns); nc = cclone(m->mount->to, 0); - nc->mnt = m->mount; - nc->xmnt = nc->mnt; - nc->mountid = m->mount->mountid; + if(nc->mh != nil) + putmhead(nc->mh); + nc->mh = m; + nc->xmh = m; + incref(m); cclose(c); c = nc; - break; + poperror(); + runlock(&m->lock); + return c; } + runlock(&m->lock); + } - poperror(); runlock(&pg->ns); return c; } @@ -387,7 +413,6 @@ undomount(Chan *c) int walk(Chan **cp, char *name, int domnt) { - Pgrp *pg; Chan *c, *ac; Mount *f; int dotdot; @@ -412,20 +437,19 @@ walk(Chan **cp, char *name, int domnt) return 0; } - if(ac->mnt == nil) + if(ac->mh == nil) return -1; c = nil; - pg = up->pgrp; - rlock(&pg->ns); + rlock(&ac->mh->lock); if(waserror()) { - runlock(&pg->ns); + runlock(&ac->mh->lock); if(c) cclose(c); nexterror(); } - for(f = ac->mnt; f; f = f->next) { + for(f = ac->mh->mount; f; f = f->next) { c = cclone(f->to, 0); c->flag &= ~CCREATE; /* not inherited through a walk */ if(devtab[c->type]->walk(c, name) != 0) @@ -434,7 +458,7 @@ walk(Chan **cp, char *name, int domnt) c = nil; } poperror(); - runlock(&pg->ns); + runlock(&ac->mh->lock); if(c == nil) return -1; @@ -442,7 +466,10 @@ walk(Chan **cp, char *name, int domnt) if(dotdot) c = undomount(c); - c->mnt = 0; + if(c->mh){ + putmhead(c->mh); + c->mh = nil; + } if(domnt) { if(waserror()) { cclose(c); @@ -462,21 +489,22 @@ walk(Chan **cp, char *name, int domnt) Chan* createdir(Chan *c) { - Pgrp *pg; Chan *nc; Mount *f; - pg = up->pgrp; - rlock(&pg->ns); + rlock(&c->mh->lock); if(waserror()) { - runlock(&pg->ns); + runlock(&c->mh->lock); nexterror(); } - for(f = c->mnt; f; f = f->next) { + for(f = c->mh->mount; f; f = f->next) { if(f->to->flag&CCREATE) { nc = cclone(f->to, 0); - nc->mnt = f; - runlock(&pg->ns); + if(nc->mh != nil) + putmhead(nc->mh); + nc->mh = c->mh; + incref(c->mh); + runlock(&c->mh->lock); poperror(); cclose(c); return nc; @@ -604,7 +632,6 @@ namec(char *name, int amode, int omode, ulong perm) if(*name == 0) isdot = 1; } - c->mnt = nil; if(waserror()){ cclose(c); @@ -708,7 +735,7 @@ namec(char *name, int amode, int omode, ulong perm) /* * the file didn't exist, try the create */ - if(c->mnt && !(c->flag&CCREATE)) + if(c->mh != nil && !(c->flag&CCREATE)) c = createdir(c); /* @@ -813,3 +840,10 @@ isdir(Chan *c) return; error(Enotdir); } + +void +putmhead(Mhead *m) +{ + if(decref(m) == 0) + free(m); +} diff --git a/port/dev.c b/port/dev.c index 28588b4bc83bf178e93882074c8624a3ac333740..0b6ed54a6070d1da23d72201fdeed9f7d638cdcf 100644 --- a/port/dev.c +++ b/port/dev.c @@ -93,7 +93,9 @@ devclone(Chan *c, Chan *nc) nc->qid = c->qid; nc->offset = c->offset; nc->flag = c->flag; - nc->mnt = c->mnt; + nc->mh = c->mh; + if(c->mh != nil) + incref(c->mh); nc->mountid = c->mountid; nc->aux = c->aux; nc->mchan = c->mchan; diff --git a/port/devcons.c b/port/devcons.c index 2fc4ead3e6a52786e306769242ffb8e4dd488a23..8e5d66ef714daa751b37cb331f0438f0bd9fc931 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -900,7 +900,7 @@ Dev consdevtab = { devwstat, }; -static struct +struct Rb { QLock; Rendez producer; @@ -964,8 +964,8 @@ genrandom(void*) for(;;) if(++rb.randomcount > 100000) break; - if(anyhigher()) - sched(); + if(anyhigher()) + sched(); if(!rbnotfull(0)) sleep(&rb.producer, rbnotfull, 0); } diff --git a/port/devmnt.c b/port/devmnt.c index feb55e42095c817d2bde52b86200a777716e8f94..a8cb1843393e8b31dd5c228cbbd5202fad7f08dc 100644 --- a/port/devmnt.c +++ b/port/devmnt.c @@ -893,7 +893,7 @@ recoverchan(Mnt *m, Chan *c) } /* Attach the fid onto the file server (sets c->path to #Mxxx) */ - mattach(m, c, c->xmnt->spec); + mattach(m, c, c->xmh->mount->spec); poperror(); /* diff --git a/port/pgrp.c b/port/pgrp.c index 0d3105b3fda296a84e2f912587bf92da374688f7..53abfefe8cc50864a3d731bf0910cbde1c7d4a77 100644 --- a/port/pgrp.c +++ b/port/pgrp.c @@ -82,10 +82,13 @@ closepgrp(Pgrp *p) e = &p->mnthash[MNTHASH]; for(h = p->mnthash; h < e; h++) { for(f = *h; f; f = next) { + wlock(&f->lock); cclose(f->from); mountfree(f->mount); + f->mount = nil; next = f->hash; - free(f); + wunlock(&f->lock); + putmhead(f); } } wunlock(&p->ns); @@ -130,8 +133,10 @@ pgrpcpy(Pgrp *to, Pgrp *from) for(i = 0; i < MNTHASH; i++) { l = tom++; for(f = from->mnthash[i]; f; f = f->hash) { + rlock(&f->lock); mh = smalloc(sizeof(Mhead)); mh->from = f->from; + mh->ref = 1; incref(mh->from); *l = mh; l = &mh->hash; @@ -149,6 +154,7 @@ pgrpcpy(Pgrp *to, Pgrp *from) *link = n; link = &n->next; } + runlock(&f->lock); } } /* diff --git a/port/portdat.h b/port/portdat.h index 4bf75d4ada519b27332fada1315e3184b03a8427..0ac6e5febf4c76955b332ec2b74939aa4a74dacb 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -150,8 +150,9 @@ struct Chan Qid qid; int fid; /* for devmnt */ Path* path; - Mount* mnt; /* mount point that derived Chan */ - Mount* xmnt; /* Last mount point crossed */ + Mhead* mh; /* mount point that derived Chan */ + Mhead* xmh; /* Last mount point crossed */ + int uri; /* union read index */ ulong mountid; Mntcache *mcp; /* Mount cache pointer */ union { @@ -232,6 +233,8 @@ struct Mount struct Mhead { + Ref; + RWlock lock; Chan* from; /* channel mounted upon */ Mount* mount; /* what's mounted upon it */ Mhead* hash; /* Hash chain */ diff --git a/port/portfns.h b/port/portfns.h index eb027cd043dd25694ad0ceb707d4deddfb33d375..1cbbef0824fba3688a77a3fedd0efe57a77d7a86 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -203,6 +203,7 @@ int ptpath(Path*, char*, int); int pullblock(Block**, int); Block* pullupblock(Block*, int); void putimage(Image*); +void putmhead(Mhead*); void putmmu(ulong, ulong, Page*); void putpage(Page*); void putseg(Segment*); diff --git a/port/sysfile.c b/port/sysfile.c index f8d5458074fa732894ce080ff0f098e54e203148..a039e164c318efd211923f439d97095947eaea06 100644 --- a/port/sysfile.c +++ b/port/sysfile.c @@ -279,28 +279,26 @@ sysclose(ulong *arg) long unionread(Chan *c, void *va, long n) { + int i; long nr; Chan *nc; - Pgrp *pg; + Mhead *m; + Mount *mount; - pg = up->pgrp; - rlock(&pg->ns); + m = c->mh; + rlock(&m->lock); + mount = m->mount; + for(i = 0; mount != nil && i < c->uri; i++) + mount = mount->next; for(;;) { if(waserror()) { - runlock(&pg->ns); + runlock(&m->lock); nexterror(); } - nc = cclone(c->mnt->to, 0); + nc = cclone(mount->to, 0); poperror(); - if(c->mountid != c->mnt->mountid) { - pprint("unionread: changed underfoot?\n"); - runlock(&pg->ns); - cclose(nc); - return 0; - } - /* Error causes component of union to be skipped */ if(waserror()) { cclose(nc); @@ -316,18 +314,18 @@ unionread(Chan *c, void *va, long n) cclose(nc); if(nr > 0) { - runlock(&pg->ns); + runlock(&m->lock); return nr; } /* Advance to next element */ next: - c->mnt = c->mnt->next; - if(c->mnt == 0) + c->uri++; + mount = mount->next; + if(mount == nil) break; - c->mountid = c->mnt->mountid; c->offset = 0; } - runlock(&pg->ns); + runlock(&m->lock); return 0; } @@ -354,7 +352,7 @@ sysread9p(ulong *arg) error(Etoosmall); } - if(dir && c->mnt) + if(dir && c->mh) n = unionread(c, (void*)arg[1], n); else if(devtab[c->type]->dc != L'M') n = devtab[c->type]->read(c, (void*)arg[1], n, c->offset); @@ -394,7 +392,7 @@ sysread(ulong *arg) error(Etoosmall); } - if(dir && c->mnt) + if(dir && c->mh) n = unionread(c, (void*)arg[1], n); else n = devtab[c->type]->read(c, (void*)arg[1], n, c->offset); @@ -514,6 +512,7 @@ sseek(ulong *arg) break; } *(vlong*)arg[0] = off; + c->uri = 0; cclose(c); poperror(); }