~moody/drawterm

823eea4c3d7da44cd4b2a27aa53cc16c7c67680b — cinap_lenrek 3 months ago c6f547e
chan: minimize differences with 9front...
4 files changed, 133 insertions(+), 133 deletions(-)

M kern/chan.c
M kern/devmnt.c
M kern/fns.h
M kern/sysfile.c
M kern/chan.c => kern/chan.c +104 -97
@@ 441,6 441,12 @@ cunique(Chan *c)
		c = nc;
	}

	if(c->umh != nil){	//BUG
		print("cunique umh != nil from %#p\n", getcallerpc(&c));
		putmhead(c->umh);
		c->umh = nil;
	}

	return c;
}



@@ 512,128 518,124 @@ newmhead(Chan *from)
void
putmhead(Mhead *m)
{
	if(m != nil && decref(&m->ref) == 0){
		assert(m->mount == nil);
		cclose(m->from);
		free(m);
	}
	if(m == nil)
		return;
	if(decref(&m->ref))
		return;
	assert(m->mount == nil);
	cclose(m->from);
	free(m);
}

int
cmount(Chan **newp, Chan *old, int flag, char *spec)
cmount(Chan *new, Chan *old, int flag, char *spec)
{
	int order, flg;
	Chan *new;
	int order;
	Mhead *m, **l, *mh;
	Mount *nm, *f, *um, **h;
	Mount *nm, *f, *um;
	Pgrp *pg;

	if(QTDIR & (old->qid.type^(*newp)->qid.type))
		error(Emount);

	if(old->umh != nil)
		print("cmount: unexpected umh, caller %#p\n", getcallerpc(&newp));
		print("cmount: unexpected umh, caller %#p\n", getcallerpc(&new));

	if(QTDIR & (old->qid.type^new->qid.type))
		error(Emount);

	order = flag&MORDER;

	if((old->qid.type&QTDIR) == 0 && order != MREPL)
		error(Emount);

	new = *newp;
	nm = newmount(new, flag, spec);
	mh = new->umh;
	if(mh != nil) {
		rlock(&mh->lock);
		if(waserror()) {
			runlock(&mh->lock);
			mountfree(nm);
			nexterror();
		}
		um = mh->mount;
		if(um != nil){
			/*
			 * Not allowed to bind when the old directory is itself a union. 
			 * (Maybe it should be allowed, but I don't see what the semantics
			 * would be.)
			 *
			 * We need to check mh->mount->next to tell unions apart from
			 * simple mount points, so that things like
			 *	mount -c fd /root
			 *	bind -c /root /
			 * work.  
			 * 
			 * The check of mount->mflag allows things like
			 *	mount fd /root
			 *	bind -c /root /
			 * 
			 * This is far more complicated than it should be, but I don't
			 * see an easier way at the moment.
			 */
			if((flag&MCREATE) != 0 && (um->next != nil || (um->mflag&MCREATE) == 0))
				error(Emount);

	/*
	 * Not allowed to bind when the old directory is itself a union. 
	 * (Maybe it should be allowed, but I don't see what the semantics
	 * would be.)
	 *
	 * We need to check mh->mount->next to tell unions apart from
	 * simple mount points, so that things like
	 *	mount -c fd /root
	 *	bind -c /root /
	 * work.  
	 * 
	 * The check of mount->mflag allows things like
	 *	mount fd /root
	 *	bind -c /root /
	 * 
	 * This is far more complicated than it should be, but I don't
	 * see an easier way at the moment.
	 */
	if((flag&MCREATE) != 0 && mh != nil && mh->mount != nil
	&& (mh->mount->next != nil || (mh->mount->mflag&MCREATE) == 0))
		error(Emount);
			/*
			 *  copy a union when binding it onto a directory
			 */
			f = nm;
			for(um = um->next; um != nil; um = um->next){
				f->next = newmount(um->to, order==MREPL? MAFTER: order, um->spec);
				f = f->next;
			}
		}
		runlock(&mh->lock);
		poperror();
	}

	pg = up->pgrp;
	wlock(&pg->ns);

	l = &MOUNTH(pg, old->qid);
	for(m = *l; m != nil; m = m->hash){
		if(eqchan(m->from, old, 1))
			break;
		l = &m->hash;
	}

	if(m == nil){
		/*
		 *  nothing mounted here yet.  create a mount
		 *  head and add to the hash table.
		 */
		m = newmhead(old);
		*l = m;

		/*
		 *  if this is a union mount, add the old
		 *  node to the mount chain.
		 */
		if(order != MREPL)
			m->mount = newmount(old, 0, nil);
		*l = m;
	}
	wlock(&m->lock);
	if(waserror()){
		wunlock(&m->lock);
		nexterror();
	}
	wunlock(&pg->ns);

	nm = newmount(new, flag, spec);
	if(mh != nil && mh->mount != nil){
		/*
		 *  copy a union when binding it onto a directory
		 */
		flg = order;
		if(order == MREPL)
			flg = MAFTER;
		h = &nm->next;
		um = mh->mount;
		for(um = um->next; um != nil; um = um->next){
			f = newmount(um->to, flg, um->spec);
			*h = f;
			h = &f->next;
		}
	}

	if(m->mount != nil && order == MREPL){
		mountfree(m->mount);
		m->mount = nil;
	}

	if(flag & MCREATE)
		nm->mflag |= MCREATE;

	if(m->mount != nil && order == MAFTER){
		for(f = m->mount; f->next != nil; f = f->next)
	um = m->mount;
	if(um != nil && order == MAFTER){
		for(f = um; f->next != nil; f = f->next)
			;
		f->next = nm;
	}else{
		for(f = nm; f->next != nil; f = f->next)
			;
		f->next = m->mount;
		um = nil;
	} else {
		if(order != MREPL){
			for(f = nm; f->next != nil; f = f->next)
				;
			f->next = um;
			um = nil;
		}
		m->mount = nm;
	}
	order = nm->mountid;
	wunlock(&m->lock);
	poperror();
	return nm->mountid;
	wunlock(&pg->ns);

	mountfree(um);

	return order;
}

void


@@ 736,13 738,13 @@ findmount(Chan **cp, Mhead **mp, int type, int dev, Qid qid)
	rlock(&pg->ns);
	for(m = MOUNTH(pg, qid); m != nil; m = m->hash){
		if(eqchantdqid(m->from, type, dev, qid, 1)){
			rlock(&m->lock);
			runlock(&pg->ns);
			if(mp != nil)
				incref(&m->ref);
			rlock(&m->lock);
			to = m->mount->to;
			incref(&to->ref);
			runlock(&m->lock);
			runlock(&pg->ns);
			if(mp != nil){
				putmhead(*mp);
				*mp = m;


@@ 957,7 959,7 @@ walk(Chan **cp, char **names, int nnames, int nomount, int *nerror)
				n = wq->nqid;
				nc = wq->clone;
			}else{		/* stopped early, at a mount point */
				didmount = 1;
				assert(didmount);
				if(wq->clone != nil){
					cclose(wq->clone);
					wq->clone = nil;


@@ 979,11 981,6 @@ walk(Chan **cp, char **names, int nnames, int nomount, int *nerror)
	}
	putmhead(mh);
	c = cunique(c);
	if(c->umh != nil){	//BUG
		print("walk umh\n");
		putmhead(c->umh);
		c->umh = nil;
	}

	pathclose(c->path);
	c->path = path;


@@ 1293,8 1290,13 @@ namec(char *aname, int amode, int omode, ulong perm)
		m = nil;
		if(!nomount)
			domount(&c, &m, nil);
		putmhead(c->umh);
		if(waserror()){
			putmhead(m);
			nexterror();
		}
		c = cunique(c);
		c->umh = m;
		poperror();
		break;

	case Aaccess:


@@ 1311,9 1313,13 @@ namec(char *aname, int amode, int omode, ulong perm)
		m = nil;
		if(!nomount)
			domount(&c, &m, &path);

		if(waserror()){
			putmhead(m);
			nexterror();
		}
		/* our own copy to open or remove */
		c = cunique(c);
		poperror();

		/* now it's our copy anyway, we can put the name back */
		pathclose(c->path);


@@ 1331,16 1337,17 @@ namec(char *aname, int amode, int omode, ulong perm)

		case Aopen:
		case Acreate:
			if(c->umh != nil){
				print("cunique umh Open\n");
				putmhead(c->umh);
				c->umh = nil;
			}
			/* only save the mount head if it's a multiple element union */
			if(m != nil && m->mount != nil && m->mount->next != nil)
				c->umh = m;
			else
				putmhead(m);
			if(m != nil) {
				rlock(&m->lock);
				if(m->mount != nil && m->mount->next != nil) {
					c->umh = m;
					runlock(&m->lock);
				} else {
					runlock(&m->lock);
					putmhead(m);
				}
			}

			/* save registers else error() in open has wrong value of c saved */
			saveregisters();

M kern/devmnt.c => kern/devmnt.c +3 -0
@@ 301,6 301,9 @@ mntattach(Chan *c, Chan *ac, char *spec, int flags)
	Mnt *m;
	Mntrpc *r;

	if(ac != nil && ac->mchan != c)
		error(Ebadusefd);

	m = c->mux;
	if(m == nil){
		mntversion(c, nil, 0, 0);

M kern/fns.h => kern/fns.h +2 -1
@@ 25,7 25,7 @@ void		closemount(Mount*);
void		closepgrp(Pgrp*);
void		closergrp(Rgrp*);
void		cmderror(Cmdbuf*, char*);
int		cmount(Chan**, Chan*, int, char*);
int		cmount(Chan*, Chan*, int, char*);
Block*		concatblock(Block*);
Block*		copyblock(Block*, int);
void		cunmount(Chan*, Chan*);


@@ 101,6 101,7 @@ void		mkqid(Qid*, vlong, ulong, int);
Chan*		mntauth(Chan*, char*);
void		mntdump(void);
long		mntversion(Chan*, char*, int, int);
Chan*		mntattach(Chan*, Chan*, char*, int);
void		mountfree(Mount*);
void		muxclose(Mnt*);
Chan*		namec(char*, int, int, ulong);

M kern/sysfile.c => kern/sysfile.c +24 -35
@@ 293,7 293,7 @@ _sysopen(char *name, int mode)
}

static void
closefd(int fd, int flag)
fdclose(int fd, int flag)
{
	int i;
	Chan *c;


@@ 325,7 325,7 @@ long
_sysclose(int fd)
{
	fdtochan(fd, -1, 0, 0);
	closefd(fd, 0);
	fdclose(fd, 0);

	return 0;
}


@@ 636,31 636,30 @@ _syschdir(char *name)
	return 0;
}

long
bindmount(int ismount, int fd, int afd, char* arg0, char* arg1, ulong flag, char* spec)
static int
bindmount(int ismount, int fd, int afd, char* arg0, char* arg1, int flag, char* spec)
{
	int ret;
	Chan *c0, *c1, *ac, *bc;
	struct{
		Chan	*chan;
		Chan	*authchan;
		char	*spec;
		int	flags;
	}bogus;

	if((flag&~MMASK) || (flag&MORDER)==(MBEFORE|MAFTER))
		error(Ebadarg);

	bogus.flags = flag & MCACHE;

	if(ismount){
		validaddr((uintptr)spec, 1, 0);
		spec = validnamedup(spec, 1);
		if(waserror()){
			free(spec);
			nexterror();
		}

		if(up->pgrp->noattach)
			error(Enoattach);

		ac = nil;
		bc = fdtochan(fd, ORDWR, 0, 1);
		if(waserror()) {
			if(ac)
			if(ac != nil)
				cclose(ac);
			cclose(bc);
			nexterror();


@@ 669,26 668,14 @@ bindmount(int ismount, int fd, int afd, char* arg0, char* arg1, ulong flag, char
		if(afd >= 0)
			ac = fdtochan(afd, ORDWR, 0, 1);

		bogus.chan = bc;
		bogus.authchan = ac;

		validaddr((ulong)spec, 1, 0);
		bogus.spec = spec;
		if(waserror())
			error(Ebadspec);
		validname(spec, 1);
		poperror();

		ret = devno('M', 0);
		c0 = devtab[ret]->attach((char*)&bogus);

		poperror();
		if(ac)
		c0 = mntattach(bc, ac, spec, flag&MCACHE);
		poperror();	/* ac bc */
		if(ac != nil)
			cclose(ac);
		cclose(bc);
	}else{
		bogus.spec = 0;
		validaddr((ulong)arg0, 1, 0);
		spec = nil;
		validaddr((uintptr)arg0, 1, 0);
		c0 = namec(arg0, Abind, 0, 0);
	}



@@ 697,22 684,24 @@ bindmount(int ismount, int fd, int afd, char* arg0, char* arg1, ulong flag, char
		nexterror();
	}

	validaddr((ulong)arg1, 1, 0);
	validaddr((uintptr)arg1, 1, 0);
	c1 = namec(arg1, Amount, 0, 0);
	if(waserror()){
		cclose(c1);
		nexterror();
	}

	ret = cmount(&c0, c1, flag, bogus.spec);
	ret = cmount(c0, c1, flag, spec);

	poperror();
	cclose(c1);
	poperror();
	cclose(c0);
	if(ismount)
		closefd(fd, 0);

	if(ismount){
		fdclose(fd, 0);
		poperror();
		free(spec);
	}
	return ret;
}