M ip/kio.c => ip/kio.c +1 -1
@@ 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);
M pc/vgacyber938x.c => pc/vgacyber938x.c +11 -33
@@ 11,6 11,11 @@
#include <memdraw.h>
#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 = {
M port/chan.c => port/chan.c +74 -40
@@ 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);
+}
M port/dev.c => port/dev.c +3 -1
@@ 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;
M port/devcons.c => port/devcons.c +3 -3
@@ 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);
}
M port/devmnt.c => port/devmnt.c +1 -1
@@ 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();
/*
M port/pgrp.c => port/pgrp.c +7 -1
@@ 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);
}
}
/*
M port/portdat.h => port/portdat.h +5 -2
@@ 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 */
M port/portfns.h => port/portfns.h +1 -0
@@ 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*);
M port/sysfile.c => port/sysfile.c +18 -19
@@ 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();
}