~kris/9p

9hist

c62bf5a258a49b36cd677c1866b74c354566614c — David du Colombier 30 years ago b79e299
Plan 9 from Bell Labs 1996-02-18
1 files changed, 122 insertions(+), 54 deletions(-)

M port/devtinyfs.c
M port/devtinyfs.c => port/devtinyfs.c +122 -54
@@ 150,7 150,7 @@ validdir(Tfs *fs, uchar *p)

	if(checksum(p) != 0)
		return 0;
	if(buf[0] != Tagdir)
	if(p[0] != Tagdir)
		return 0;
	md = (Mdir*)p;
	x = GETS(md->bno);


@@ 167,8 167,8 @@ validdata(Tfs *fs, uchar *p, int *lenp)

	if(checksum(p) != 0)
		return 0;
	md = (Mdir*)p;
	switch(buf[0]){
	md = (Mdata*)p;
	switch(md->type){
	case Tagdata:
		x = GETS(md->bno);
		if(x >= fs->nblocks)


@@ 190,25 190,47 @@ validdata(Tfs *fs, uchar *p, int *lenp)
static Mdata*
readdata(Tfs *fs, ulong bno, uchar *buf, int *lenp)
{
	Mdata *md;

	if(bno >= fs->nblocks)
		return 0;
	n = devtab[fs->c->type].read(fs->c, buf, Blen, Blen*bno);
	if(n != Blen)
		return 0;
	if(devtab[fs->c->type].read(fs->c, buf, Blen, Blen*bno) != Blen)
		error(Eio);
	return validdata(fs, buf, lenp);
}

static int
static void
writedata(Tfs *fs, ulong bno, ulong next, uchar *buf, int len, int last)
{
	Mdata md;

	if(bno >= fs->nblocks)
		error(Eio);
	if(len > Dlen)
		len = Dlen;
	if(len < 0)
		error(Eio);
	memset(&md, 0, sizeof(md));
	if(last){
		md.type = Tagend;
		PUTS(md.bno, len);
	} else {
		md.type = Tagdata;
		PUTS(md.bno, next);
	}
	memmove(md.data, buf, len);
	md.sum = 0 - checksum((uchar*)&md);
	
	if(devtab[fs->c->type].write(fs->c, &md, Blen, Blen*bno) != Blen)
		error(Eio);
}

static void
writedir(Tfs *fs, Tfile *f)
{
	Mdir *md;
	int n;
	uchar buf[Blen];

	if(f->bno == Notabno)
		return Blen;
		return;

	md = (Mdir*)buf;
	memset(buf, 0, Blen);


@@ 216,9 238,10 @@ writedir(Tfs *fs, Tfile *f)
	strncpy(md->name, f->name, sizeof(md->name)-1);
	PUTS(md->bno, f->dbno);
	PUTS(md->pin, f->pin);
	f->sum = 0 - checksum(buf);
	md->sum = 0 - checksum(buf);

	return devtab[fs->c->type].write(fs->c, buf, Blen, Blen*f->bno);
	if(devtab[fs->c->type].write(fs->c, buf, Blen, Blen*f->bno) != Blen)
		error(Eio);
}

static void


@@ 277,6 300,7 @@ newfile(Tfs *fs, char *name)
	Tfile *f;

	/* find free entry in file table */
	f = 0;
	for(;;) {
		for(i = 0; i < fs->fsize; i++){
			f = &fs->f[i];


@@ 298,10 322,10 @@ newfile(Tfs *fs, char *name)

	/* write directory block */
	if(waserror()){
		filefree(fs, f, Notabno);
		freefile(fs, f, Notabno);
		nexterror();
	}
	if(b->bno == Notabno)
	if(f->bno == Notabno)
		error("out of space");
	writedir(fs, f);
	poperror();


@@ 317,16 341,17 @@ newfile(Tfs *fs, char *name)
static void
fsinit(Tfs *fs)
{
	uchar buf[Blen+DIRLEN];
	char dbuf[DIRLEN];
	Dir d;
	uchar buf[Blen];
	ulong x, bno;
	int n, done;
	Tfile *f;
	Mdir *mdir;
	Mdata *mdat;
	Mdata *mdata;

	devtab[fs->c->type].stat(fs->c, buf);
	convM2D(buf, &d);
	devtab[fs->c->type].stat(fs->c, dbuf);
	convM2D(dbuf, &d);
	fs->nblocks = d.length/Blen;
	if(fs->nblocks < 3)
		error("tinyfs medium too small");


@@ 344,11 369,11 @@ fsinit(Tfs *fs)
		if(n != Blen)
			break;

		mdir = validdir(buf);
		mdir = validdir(fs, buf);
		if(mdir == 0)
			continue;

		if(fs->nfs >= fs->fsize)
		if(fs->nf >= fs->fsize)
			expand(fs);

		f = &fs->f[fs->nf++];


@@ 363,10 388,10 @@ fsinit(Tfs *fs)

	/* follow files */
	for(f = fs->f; f < &(fs->f[fs->nf]); f++){
		bno = fs->dbno;
		bno = f->dbno;
		for(done = 0; !done;) {
			if(isalloced(fs, bno)){
				freefile(f, bno);
				freefile(fs, f, bno);
				break;
			}
			n = devtab[fs->c->type].read(fs->c, buf, Blen, Blen*bno);


@@ 383,10 408,10 @@ fsinit(Tfs *fs)
			switch(mdata->type){
			case Tagdata:
				bno = GETS(mdata->bno);
				f->len += Dlen;
				f->length += Dlen;
				break;
			case Tagend:
				f->len += GETS(mdata->bno);
				f->length += GETS(mdata->bno);
				done = 1;
				break;
			}


@@ 406,6 431,8 @@ tinyfsgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp)
	Tfile *f;
	Qid qid;

	USED(ntab, tab);

	fs = &tinyfs.fs[c->dev];
	if(i >= fs->nf)
		return -1;


@@ 435,7 462,7 @@ tinyfsattach(char *spec)
	Chan *c, *cc;
	int i;

	cc = namec((char*)arg[0], Aopen, arg[1], 0);
	cc = namec(spec, Aopen, ORDWR, 0);
	if(waserror()){
		close(cc);
		qunlock(&tinyfs);


@@ 443,9 470,10 @@ tinyfsattach(char *spec)
	}

	qlock(&tinyfs);
	fs = 0;
	for(i = 0; i < tinyfs.nfs; i++){
		fs = &tinyfs.fs[i];
		if(fs && eqchan(c, fs->c))
		if(fs && eqchan(cc, fs->c, 0))
			break;
	}
	if(i < tinyfs.nfs){


@@ 477,6 505,10 @@ tinyfsattach(char *spec)
Chan *
tinyfsclone(Chan *c, Chan *nc)
{
	Tfs *fs;

	fs = &tinyfs.fs[c->dev];

	qlock(fs);
	fs->r++;
	qunlock(fs);


@@ 488,6 520,9 @@ int
tinyfswalk(Chan *c, char *name)
{
	int n;
	Tfs *fs;

	fs = &tinyfs.fs[c->dev];

	qlock(fs);
	n = devwalk(c, name, 0, 0, tinyfsgen);


@@ 513,13 548,13 @@ tinyfsopen(Chan *c, int omode)

	fs = &tinyfs.fs[c->dev];

	if(c->path & CHDIR){
	if(c->qid.path & CHDIR){
		if(omode != OREAD)
			error(Eperm);
	} else {
		qlock(fs);
		if(omode == (OTRUNC|ORDWR)){
			f = newfile(fs, fs->f[c->qid.path]);
			f = newfile(fs, fs->f[c->qid.path].name);
			c->qid.path = f - fs->f;
		} else if(omode != OREAD){
			qunlock(fs);


@@ 540,6 575,8 @@ tinyfscreate(Chan *c, char *name, int omode, ulong perm)
	if(perm & CHDIR)
		error("directory creation illegal");

	fs = &tinyfs.fs[c->dev];

	qlock(fs);
	f = newfile(fs, name);
	qunlock(fs);


@@ 570,7 607,7 @@ tinyfsclose(Chan *c)
	Tfile *f, *nf;
	int i;

	fs = c->aux;
	fs = &tinyfs.fs[c->dev];

	qlock(fs);



@@ 594,16 631,16 @@ tinyfsclose(Chan *c)
				}
				f->flag &= ~(Frmonclose|Fcreating);
			}
			if(f->flag & Frmonclose){
			if(f->flag & Frmonclose)
				freefile(fs, f, Notabno);
		}
	}

	/* dereference fs and remove on zero refs */
	fs->r--;
	unlock(fs);
	qunlock(fs);
	qlock(&tinyfs);
	if(fs->ref == 0){
	if(fs->r == 0){
		for(l = &fs->l; *l;){
			if(*l == fs){
				*l = fs->next;


@@ 625,7 662,7 @@ tinyfsread(Chan *c, void *a, long n, ulong offset)
	Tfs *fs;
	Tfile *f;
	int sofar, i;
	ulong bno, tbno;
	ulong bno;
	Mdata *md;
	uchar buf[Blen];
	uchar *p = a;


@@ 644,8 681,6 @@ tinyfsread(Chan *c, void *a, long n, ulong offset)
	bno = f->dbno;
	for(sofar = 0; sofar + Blen < offset; sofar += Blen){
		md = readdata(fs, bno, buf, 0);
		if(md == 0)
			error(Eio);
		bno = GETS(md->bno);
	}



@@ 653,8 688,6 @@ tinyfsread(Chan *c, void *a, long n, ulong offset)
	offset = offset%Blen;
	for(sofar = 0; sofar < n; sofar += i){
		md = readdata(fs, bno, buf, &i);
		if(md == 0)
			error(Eio);
		i -= offset;
		if(i > n)
			i = n;


@@ 680,7 713,7 @@ tinyfswrite(Chan *c, char *a, long n, ulong offset)
{
	Tfs *fs;
	Tfile *f;
	int sofar, i;
	int sofar, i, x;
	ulong bno, tbno;
	Mdata *md;
	uchar buf[Blen];


@@ 689,32 722,67 @@ tinyfswrite(Chan *c, char *a, long n, ulong offset)
	if(c->qid.path & CHDIR)
		error(Eperm);

	if(n == 0)
		return 0;

	fs = tinyfs.fs[c->dev];
	f = &fs->f[c->qid.path];

	/* walk to first data block */
	/* files are append only, anything else is illegal */
	if(offset != f->length)
		error("append only");

	qlock(fs);
	if(waserror()){
		f->flag |= Frmonclose;
		qunlock(fs);
		nexterror();
	}

	/* walk to last data block */
	bno = f->dbno;
	for(sofar = 0; sofar + Blen < offset; sofar += Blen){
		md = readdata(fs, bno, buf, 0);
		if(md == 0)
			error(Eio);
		if(md->type == Tagend)
			break;
		bno = GETS(md->bno);
	}

	/* write data */
	offset = offset%Blen;
	for(sofar = 0; sofar < n; sofar += i){
		md = readdata(fs, bno, buf, 0);
		if(md == 0)
			error(Eio);
		i = Blen - offset;
		if(i > n)
			i = n;
		memmove(p, a, i);
		bno = GETS(md->bno);
		offset = 0;
	sofar = 0;
	i = offset%Dlen;
	if(i){
		x = n;
		if(i + x > Dlen)
			x = Dlen - i;
		memmove(md->data + i, p, sofar);
		f->length += x;
		sofar += x;
	}

	while(x = n - sofar) {
		tbno = mapalloc(fs);
		if(f->length == 0){
			f->dbno = tbno;
			writedir(fs, f);
		} else {
			writedata(fs, bno, tbno, md->data, Dlen, 0);
		}
		if(x > Dlen)
			x = Dlen;
		memmove(md->data, p + sofar, x);
		sofar += x;
		f->length += x;
		bno = tbno;
	}

	i = f->length%Dlen;
	if(i == 0)
		i = Dlen;
	writedata(fs, bno, tbno, md->data, i, 1);

	poperror();
	qunlock(fs);

	return sofar;
}