~kris/9p

9hist

7dbdf51ceed61f04b3bc019ab419814a7a12144e — David du Colombier 28 years ago d722fb5
Plan 9 from Bell Labs 1998-08-29
10 files changed, 124 insertions(+), 101 deletions(-)

M ip/kio.c
M pc/vgacyber938x.c
M port/chan.c
M port/dev.c
M port/devcons.c
M port/devmnt.c
M port/pgrp.c
M port/portdat.h
M port/portfns.h
M port/sysfile.c
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();
}