Plan 9 from Bell Labs’s /usr/web/sources/extra/9hist/port/devtinyfs.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


## diffname port/devtinyfs.c 1996/0116
## diff -e /dev/null /n/fornaxdump/1996/0116/sys/src/brazil/port/devtinyfs.c
0a
/*
 *  template for making a new device
 */

#include	"u.h"
#include	"../port/lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"../port/error.h"

#include	"devtab.h"

enum{
	Qdir,
	Qmedium,

	Nfile=	32,
};


struct {
	QLock;
	Chan	*c;
	Dirtab	file[Nfile];
	int	nfile;
} tinyfs;

void
tinyfsreset(void)
{
	Dirtab *d;

	d = tinyfs.file;
	memmove(d->name, "medium");
	d->qid.vers = 0;
	d->qid.path = Qdata;
	d->perm = 0666;
}

void
tinyfsinit(void)
{
}

Chan *
tinyfsattach(char *spec)
{
	return devattach('E', spec);
}

Chan *
tinyfsclone(Chan *c, Chan *nc)
{
	return devclone(c, nc);
}

int
tinyfswalk(Chan *c, char *name)
{
	return devwalk(c, name, tinyfs.file, tinyfs.nfile, devgen);
}

void
tinyfsstat(Chan *c, char *db)
{
	devstat(c, db, tinyfs.file, tinyfs.nfile, devgen);
}

Chan *
tinyfsopen(Chan *c, int omode)
{
	return devopen(c, omode, tinyfs.file, tinyfs.nfile, devgen);
}

void
tinyfscreate(Chan *c, char *name, int omode, ulong perm)
{
	Dirtab	*d;

	if(perm & CHDIR)
		error("directory creation illegal");

	if(waserror()){
		qunlock(&tinyfs);
		nexterror();
	}
	qlock(&tinyfs);

	if(tinyfs.nfile == Nfile)
		error("out of space");
	for(d = tinyfs.file; d < tinyfs.file[tinyfs.nfile]; d++)
		if(strcmp(name, d->name) == 0)
			error("create race");
	strncpy(d->name, name, sizeof(d->name)-1);
	d->perm = perm;
	d->qid.vers = 0;
	d->qid.path = tinyfs.high++;
	tinyfs.nfile++;
			
	qunlock(&tinyfs);

	c->mode = openmode(omode);
	c->flag |= COPEN;
	c->qid = d->qid;
}

void
tinyfsremove(Chan *c)
{
	USED(c);
	error(Eperm);
}

void
tinyfswstat(Chan *c, char *dp)
{
	USED(c, dp);
	error(Eperm);
}

void
tinyfsclose(Chan *c)
{
}

long
tinyfsread(Chan *c, void *a, long n, ulong offset)
{
	switch(c->qid.path & ~CHDIR){
	case Qdir:
		return devdirread(c, a, n, tinyfstab, Ntinyfstab, devgen);
	case Qdata:
		break;
	default:
		n=0;
		break;
	}
	return n;
}

Block*
tinyfsbread(Chan *c, long n, ulong offset)
{
	return devbread(c, n, offset);
}

long
tinyfswrite(Chan *c, char *a, long n, ulong offset)
{
	if(waserror()){
		qunlock(&tinyfs);
		nexterror();
	}
	qlock(&tinyfs);
	qunlock(&tinyfs);

	switch(c->qid.path & ~CHDIR){
	case Qdata:
		break;
	default:
		error(Ebadusefd);
	}
	return n;
}

long
tinyfsbwrite(Chan *c, Block *bp, ulong offset)
{
	return devbwrite(c, bp, offset);
}
.
## diffname port/devtinyfs.c 1996/0120
## diff -e /n/fornaxdump/1996/0116/sys/src/brazil/port/devtinyfs.c /n/fornaxdump/1996/0120/sys/src/brazil/port/devtinyfs.c
100c

.
48a
	c = namec((char*)arg[0], Aopen, arg[1], 0);

.
38a
	tinyfs.nfile = 1;
.
37c
	d->qid.path = Qmedium;
.
25c
	Dirtab	file[Nfile+1];
.
18a
	Qmedium,
.
16,17d
## diffname port/devtinyfs.c 1996/0122
## diff -e /n/fornaxdump/1996/0120/sys/src/brazil/port/devtinyfs.c /n/fornaxdump/1996/0122/sys/src/brazil/port/devtinyfs.c
51c
	cc = namec((char*)arg[0], Aopen, arg[1], 0);
	qlock(&tinyfs);
	l = &tinyfs.l;
	for(fs = tinyfs.l; fs != 0; fs = fs->next){
		if(eqchan(c, fs->c))
			break;
		l = &(fs->next);
	}
	if(fs){
		incref(&fs->r);
		qunlock(&tinyfs);
		close(cc);
	} else {
		fs = smalloc(sizeof(*fs));
		*l = fs;
		fs->c = cc;
		incref(&fs->r);
		qunlock(&tinyfs);
	}

	c = devattach('E', spec);
	c->aux = fs;
	c->dev = fs->dev;

	return c;
.
49c
	FS *fs, **l;
	Chan *c, *cc;
.
25a
	int	maxfile;
};

struct {
	QLock;
	FS	*l;
	int	hidev;
.
24c
	Dirtab	*file;
.
22a
	Ref	r;
	int	dev;
	FS	*next;
.
21c
struct FS {
.
19a
typedef struct FS FS;
.
## diffname port/devtinyfs.c 1996/0123
## diff -e /n/fornaxdump/1996/0122/sys/src/brazil/port/devtinyfs.c /n/fornaxdump/1996/0123/sys/src/brazil/port/devtinyfs.c
126,140d
81a
	poperror();
.
79a
		if(waserror()){
			free(fs);
			nexterror();
		}
		if(fsinit(fs) < 0)
			fssetup(fs);
		poperror();
		*l = fs;
.
77d
63a
	if(waserror()){
		close(cc);
		unlock(&fs);
		nexterror();
	}
.
56a
#define GETS(x) ((x)[0]|((x)[1]<<8))
#define PUTS(x, v) {(x)[0] = (v);(x)[1] = ((v)>>8);}

#define GETL(x) (GETS(x)|(GETS(x+2)<<16))
#define PUTL(x, v) {PUTS(x, v);PUTS(x+2, (v)>>16)}; 

/*
 *  see if we have a reasonable fat/root directory
 */
static int
fsinit(FS *fs)
{
	uchar buf[DIRLEN];
	Dir d;
	ulong x;

	n = devtab[fs->c->type].read(fs->c, buf, Superlen, 0);
	if(n != Superlen)
		error(Eio);
	x = GETL(buf);
	if(x != Magic)
		return -1;
	fs->clustsize = GETL(buf+4);
	fs->nclust = GETL(buf+8);
	x = fs->clustsize*fs->nclust;

	devtab[fs->c->type].stat(fs->c, buf);
	convM2D(buf, &d);
	if(d.length < 128)
		error("tinyfs medium too small");
	if(d.length < x)
		return -1;

	fs->fat = smalloc(2*fs->nclust);
	n = devtab[fs->c->type].read(fs->c, buf, 2*fs->nclust, Superlen);
	fd(n != 2*fs->nclust)
		error(Eio);

	x = GETS(fs->fat);
	if(x == 0)
		return -1;

	return 0;
}

/*
 *  set up the fat and then a root directory (starting at first cluster (1))
 */
static void
fssetup(FS *fs)
{
	uchar buf[DIRLEN];
	Dir d;

	devtab[fs->c->type].stat(fs->c, buf);
	convM2D(buf, &d);
	fs->clustsize = d.length>>16;
	if(fs->clustsize < 64)
		fs->clustsize = 64;
	fs->nclust = (d.length - 12)/fs->clustsize;
	fs->fat = smalloc(2*fs->nclust);
	n = devtab[fs->c->type].write(fs->c, buf, 2*fs->nclust, Superlen);
	if(n < 2*fs->nclust)
		error(Eio);
	n = devtab[fs->c->type].write(fs->c, buf, Superlen, 0);
	if(n < Superlen)
		error(Eio);
}

.
42,49d
28,30c
	uchar	*fat;
	ulong	nclust;
	ulong	clustsize;
.
17a

	Magic=		0xfeedbeef,
	Superlen=	64,
.
16c
	Nfile=		32,
.
## diffname port/devtinyfs.c 1996/0131
## diff -e /n/fornaxdump/1996/0123/sys/src/brazil/port/devtinyfs.c /n/fornaxdump/1996/0131/sys/src/brazil/port/devtinyfs.c
90,94c
	for(bno = 0; bno < fs->nblocks; bno++){
		n = devtab[fs->c->type].read(fs->c, buf, Blen, Blen*bno);
		if(n != Blen)
			break;
		if(checksum(buf) != 0)
			continue;
		switch(buf[0]){
		case Tdir:
			mapset(fs, bno);
			break;
		}
	}
.
85,88c
	/* bitmap for block usage */
	x = (fs->nblocks + 8 - 1)/8;
	fs->map = malloc(x);
	memset(fs->map, 0x0, x);
	for(bno = fs->nblocks; bno < x*8; bno++)
		mapset(fs, bno);
.
82,83d
80c
	fs->nblocks = d.length/Blen;
	if(fs->nblocks < 3)
.
68,77d
66c
	ulong x, bno;
.
64c
	uchar buf[Blen+DIRLEN];
.
57a
static void
mapclr(FS *fs, int bno)
{
	fs->map[bno>>3] &= ~(1<<(bno&7));
}

static void
mapset(FS *fs, int bno)
{
	fs->map[bno>>3] |= 1<<(bno&7);
}

static int
mapalloc(FS *fs)
{
	int i, j, lim;
	uchar x;

	qlock(fs);
	lim = (fs->nblocks + 8 - 1)/8;
	for(i = 0; i < lim; i++){
		x = fs->map[i];
		if(x == 0xff)
			continue;
		for(j = 0; j < 8; j++)
			if((x & (1<<j)) == 0){
				fs->map[i] = x|(1<<j);
				qunlock(fs);
				return i*8 + j;
			}
	}
	qunlock(fs);
	return -1;
}

.
55,56c
	s = 0;
	for(e = p + Blen; p < e; p++)
		s += *p;
}
.
52,53c
static uchar
checksum(uchar *p)
{
	uchar *e;
	uchar s;
.
41a
#define GETS(x) ((x)[0]|((x)[1]<<8))
#define PUTS(x, v) {(x)[0] = (v);(x)[1] = ((v)>>8);}

#define GETL(x) (GETS(x)|(GETS(x+2)<<16))
#define PUTL(x, v) {PUTS(x, v);PUTS(x+2, (v)>>16)};

.
31,33c
	uchar	*map;
	int	nblocks;
.
24d
19,20c
	Blen=	48,

	Tdir=	0,
	Tdata,
	Tend,
.
16d
## diffname port/devtinyfs.c 1996/0201
## diff -e /n/fornaxdump/1996/0131/sys/src/brazil/port/devtinyfs.c /n/fornaxdump/1996/0201/sys/src/brazil/port/devtinyfs.c
276c
		return devdirread(c, a, n, tinyfstab, Ntinyfstab, tinyfsgen);
.
268a
	Tfs *fs, **l;
	Tfile *f, *nf;

	fs = c->aux;
	lock(fs);
	fs->ref--;
	unlock(fs);

	if(fs->ref)
		return;

	qlock(&tinyfs);
	lock(fs);
	if(fs->ref == 0){
		for(l = &fs->l; *l;){
			if(*l == fs){
				*l = fs->next;
				break;
			}
			l = &(*l)->next;
		}
		for(f = fs->f; f; f = nf){
			nf = f->next;
			free(f);
		}
		free(fs->map);
		close(fs->c);
		free(fs);
	}
	unlock(fs);
	qunlock(&tinyfs);
.
249d
246a
	unlock(fs);

	c->qid.path = f - fs->f;
	c->qid.vers = 1;		/* creating */
.
243,245c
	fs = &tinyfs.fs[c->dev];
	for(;;) {
		lock(fs);
		for(i = 0; i < fs->fsize; i++){
			f = &fs->f[i];
			if(f->name[0] == 0){
				strncpy(f->name, name, sizeof(f->name)-1);
				break;
			}
		}
		if(i < fs->fsize)
			break;

		unlock(fs);
		expand(fs);
.
238c
	Tfs *fs;
	Tfile *f;
.
232c
	Tfs *fs;
	Tfile *f;

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

	if(c->path & CHDIR){
		if(omode != OREAD)
			error(Eperm);
	} else {
		lock(fs);
		f = fs->f[c->path];
		unlock(fs);

		if(f->pin == Nopin){
			if(omode != OREAD)
				error(Eperm);
		} else {
			if(omode != ORDWR)
				error(Eperm);
		}
	}

	return devopen(c, omode, 0, 0, tinyfsgen);
.
226c
	devstat(c, db, 0, 0, tinyfsgen);
.
220c
	return devwalk(c, name, 0, 0, tinyfsgen);
.
204,206c
	c = devattach('U', spec);
	c->dev = fs - tinyfs.fs;
	c->qid.path = CHDIR;
	c->qid.vers = 0;
.
201a
	qunlock(&tinyfs);
.
191,200c
		fs->r = 1;
		fsinit(fs);
		tinyfs.nfs++;
.
189c
		if(tinyfs.nfs >= Maxfs)
			error("too many tinyfs's");
		fs = &tinyfs.fs[tinyfs.nfs];
		memset(fs, 0, sizeof(*fs));
.
184,186c
	if(i < tinyfs.nfs){
		lock(fs);
		fs->r++;
		unlock(fs);
.
182d
178,180c
	for(i = 0; i < tinyfs.nfs; i++){
		fs = &tinyfs.fs[i];
		if(fs && eqchan(c, fs->c))
.
176a

.
174c
		qunlock(&tinyfs);
.
169a
	int i;
.
168c
	Tfs *fs;
.
164a
void
tinyfsreset(void)
{
	if(Nlen > NAMELEN)
		panic("tinyfsreset");
}

void
tinyfsinit(void)
{
}

.
150,162c
	fs = &tinyfs.fs[c->dev];
	if(i >= fs->nf)
		return -1;
	f = &fs->f[i];
	qid.path = i;
	qid.vers = 0;
	devdir(c, qid, f->name, f->length, eve, f->pin==Nopin?0444:0666, dp);
	return 1;
.
147,148c
	Tfs *fs;
	Tfile *f;
	Qid qid;
.
141,145c
static int
tinyfsgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp)
.
136c
			switch(mdata->type){
			case Tagdata:
				bno = GETS(mdata->bno);
				f->len += Dlen;
				break;
			case Tagend:
				f->len += GETS(mdata->bno);
				break;
			}
.
133,134c

		if(fs->nfs <= fs->fsize)
			expand(fs);
		f = &fs->f[fs->nf++];

		x = GETS(mdir->bno);
		mapset(fs, bno);
		strncpy(f->name, mdir->name, sizeof(f->name));
		f->pin = GETS(mdir->pin);
		f->bno = bno;
		f->dbno = x;
	}

	/* follow files */
	for(f = fs->f; f; f = f->next){
		bno = fs->dbno;
		for(;;) {
			if(isalloced(fs, bno)){
				freefile(f, bno);
				break;
			}
			n = devtab[fs->c->type].read(fs->c, buf, Blen, Blen*bno);
			if(n != Blen){
				freefile(fs, f, bno);
				break;
			}
			mdata = validdata(fs, buf);
			if(mdata == 0){
				freefile(fs, f, bno);
				break;
			}
.
131c

		mdir = validdir(buf);
		if(mdir == 0)
.
126a
	/* find files */
.
122c
	fs->map = smalloc(x);
.
112a
	int n;
	Tfile *f;
	Mdir *mdir;
	Mdata *mdat;
.
107,108c
static void
fsinit(Tfs *fs)
.
103a
static Mdir*
validdir(Tfs *fs, uchar *p)
{
	Mdir *md;
	ulong x;

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

static Mdata*
validdata(Tfs *fs, uchar *p)
{
	Mdata *md;
	ulong x;

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

static void
freefile(Tfs *fs, Tfile *f, ulong bend)
{
	uchar buf[Blen];
	ulong bno;
	int n;
	Mdata *md;

	/* remove blocks from map */
	bno = f->dbno;
	while(bend != bno){
		mapclr(fs, bno);
		n = devtab[fs->c->type].read(fs->c, buf, Blen, Blen*bno);
		if(n != Blen)
			break;
		md = validdata(buf);
		if(md == 0)
			break;
		if(md->type == Tagend)
			break;
		bno = GETS(md->bno);
	}

	/* change file type to free on medium */
	n = devtab[fs->c->type].read(fs->c, buf, Blen, Blen*f->bno);
	if(n != Blen)
		return;
	buf[0] = Tagfree;
	devtab[fs->c->type].write(fs->c, buf, Blen, Blen*f->bno);

	/* forget we ever knew about it */
	memset(f, 0, sizeof(*f));
}

static void
expand(Tfs *fs)
{
	Tfile *f;

	fs->fsize += 8;
	f = smalloc(fs->fsize*sizeof(*f));

	lock(fs);
	memmove(f, fs->f, fs->nf*sizoef(f));
	free(fs->f);
	fs->f = f;
	unlock(fs);
}

.
83a
	return fs->map[bno>>3] & (1<<(bno&7));
}

static int
mapalloc(Tfs *fs)
{
.
82c
isalloced(Tfs *fs, ulong bno)
.
76c
mapset(Tfs *fs, ulong bno)
.
70c
mapclr(Tfs *fs, ulong bno)
.
48,57d
38,39c
	Tfs	fs[Maxfs];
	short	nfs;
.
33a
	Tfile	*f;
	int	nf;
	int	fsize;
.
25,30c
/* medium representation of a Tdir */
typedef struct Mdir Mdir;
struct Mdir {
	uchar	type;
	uchar	bno[2];
	uchar	pin[2];
	char	name[Nlen];
	char	pad[Blen - Nlen - 6];
	uchar	sum;
};

/* medium representation of a Tdata/Tend */
typedef struct Mdata Mdata;
struct Mdata {
	uchar	type;
	uchar	bno[2];
	char	data[Dlen];
	uchar	sum;
};

typedef struct Tfile Tfile;
struct Tfile {
	char	name[NAMELEN];
	ushort	bno;
	ushort	dbno;
	ushort	pin;
	ulong	length;
};

typedef struct Tfs Tfs;
struct Tfs {
	Lock;
	int	r;
.
20,22c
	Blen=		48,	/* block length */
	Nlen=		28,	/* name length */
	Dlen=		Blen - 4,

	Tagdir=		'd',
	Tagdata=	'D',
	Tagend=		'e',
	Tagfree=	'f',

	Nopin=		0xffff;
.
18c
	Maxfs=		10,	/* max file systems */
.
## diffname port/devtinyfs.c 1996/0202
## diff -e /n/fornaxdump/1996/0201/sys/src/brazil/port/devtinyfs.c /n/fornaxdump/1996/0202/sys/src/brazil/port/devtinyfs.c
490,491c
	/* dereference file and remove old versions */
	if(c->qid.path != CHDIR){
		f = &fs->f[c->qid.path];
		f->r--;
		if(f->r == 0 && f->creating){
			/* remove all other files with this name */
			for(i = 0; i < fs->fsize; i++){
				nf = &fs->f[i];
				if(f == nf)
					continue;
				if(strcmp(nf->name, f->name) == 0)
					freefile(fs, nf, Notabno);
			}
		}
	}

	/* dereference fs and remove on zero refs */
	fs->r--;
.
487,488c
	qlock(fs);
.
483,485d
480a
	int i;
.
459d
457c
	c->qid.vers = 0;
.
451,455d
438,449c
	qlock(fs);
	f = newfile(fs, name);
	qunlock(fs);
.
423a
		qunlock(fs);
.
413,422c
		qlock(fs);
		if(omode == (OTRUNC|ORDWR)){
			f = newfile(fs, fs->f[c->qid.path]);
			c->qid.path = f - fs->f;
		} else if(omode != OREAD){
			qunlock(fs);
			error(Eperm);
.
392c
	int n;

	qlock(fs);
	n = devwalk(c, name, 0, 0, tinyfsgen);
	if(n != 0 && c->qid.path != CHDIR){
		fs = &tinyfs.fs[c->dev];
		fs->f[c->qid.path].r++;
	}
	qunlock(fs);
	return n;
.
385a
	qlock(fs);
	fs->r++;
	qunlock(fs);

.
360c
		qunlock(fs);
.
358c
		qlock(fs);
.
321c
	devdir(c, qid, f->name, f->length, eve, 0664, dp);
.
307a
/*
 *  single directory
 */
.
265a

.
228c
 *  Read the whole medium and build a file table and used
 *  block bitmap.  Inconsistent files are purged.
.
226a
static Tfile*
newfile(Tfs *fs, char *name)
{
	int i;
	Tfile *f;

	/* find free entry in file table */
	for(;;) {
		for(i = 0; i < fs->fsize; i++){
			f = &fs->f[i];
			if(f->name[0] == 0){
				strncpy(f->name, name, sizeof(f->name)-1);
				break;
			}
		}

		if(i < fs->fsize)
			break;

		expand(fs);
	}

	f->creating = 1;
	f->dbno = Notabno;
	f->bno = mapalloc(fs);

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

.
224d
220d
202,206c
	if(f->bno != Notabno){
		n = devtab[fs->c->type].read(fs->c, buf, Blen, Blen*f->bno);
		if(n != Blen)
			return;
		buf[0] = Tagfree;
		devtab[fs->c->type].write(fs->c, buf, Blen, Blen*f->bno);
	}
.
188c
	while(bno != bend && bno != Notabno){
.
177a
static int
writedir(Tfs *fs, Tfile *f)
{
	Mdir *md;
	int n;
	uchar buf[Blen];

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

	md = (Mdir*)buf;
	memset(buf, 0, Blen);
	md->type = Tagdir;
	strncpy(md->name, f->name, sizeof(md->name)-1);
	PUTS(md->bno, f->dbno);
	PUTS(md->pin, f->pin);
	f->sum = 0 - checksum(buf);

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

.
93a
	return s;
.
63c
	QLock;
.
57a
	char	creating;
.
53a
	int	r;
.
43c
/* representation of a Tdata/Tend on medium */
.
32c
/* representation of a Tdir on medium */
.
29c
	Notapin=		0xffff,
	Notabno=		0xffff,
.
2c
 *  a pity the code isn't also tiny...
.
## diffname port/devtinyfs.c 1996/0203
## diff -e /n/fornaxdump/1996/0202/sys/src/brazil/port/devtinyfs.c /n/fornaxdump/1996/0203/sys/src/brazil/port/devtinyfs.c
596,601c

	fs = tinyfs.fs[c->dev];
	f = &fs->f[c->qid.path];
	if(offset >= f->length)
		return 0;
	if(n + offset >= f->length)
		n = f->length - offset;

.
593,594c
	Tfs *fs;
	Tfile *f;
	int sofar, i;

	if(c->qid.path & CHDIR)
.
586d
584c
		memset(fs, 0, sizeof(*fs));
.
578,581c
		free(fs-f);
.
569a
	unlock(fs);
	qlock(&tinyfs);
.
564a
			if(f->flag & Frmonclose){
				freefile(fs, f, Notabno);
.
556,563c
		if(f->r == 0){
			if(f->creating){
				/* remove all other files with this name */
				for(i = 0; i < fs->fsize; i++){
					nf = &fs->f[i];
					if(f == nf)
						continue;
					if(strcmp(nf->name, f->name) == 0){
						if(nf->r)
							nf->flag |= Frmonclose;
						else
							freefile(fs, nf, Notabno);
					}
				}
				f->flag &= ~(Frmonclose|Fcreating);
.
274c
	f->flag = Fcreating;
.
60c
	uchar	flag;
.
30a

	Fcreating=	1,
	Frmonclose=	2,
.
## diffname port/devtinyfs.c 1996/0206
## diff -e /n/fornaxdump/1996/0203/sys/src/brazil/port/devtinyfs.c /n/fornaxdump/1996/0206/sys/src/brazil/port/devtinyfs.c
615a

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

	/* read first block */
	i = offset%Blen;

	/* read data */
	for(sofar = 0; sofar+Blen < offset; sofar += Blen){
	
.
605a
	ulong bno, tbno;
	Mdata *md;
	uchar buf[Blen];
.
184a
static Mdata*
readdata(Tfs *fs, ulong bno, uchar *buf)
{
	if(bno >= fs->nblocks)
		return 0;
	n = devtab[fs->c->type].read(fs->c, buf, Blen, Blen*bno);
	if(n != Blen)
		return 0;
	return validdata(fs, buf);
}

.
57a
	Lock;
.
## diffname port/devtinyfs.c 1996/0217
## diff -e /n/fornaxdump/1996/0206/sys/src/brazil/port/devtinyfs.c /n/fornaxdump/1996/0217/sys/src/brazil/port/devtinyfs.c
673c

	return sofar;
.
667,671c
	/* 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;
.
664,665d
660,662c
	Tfs *fs;
	Tfile *f;
	int sofar, i;
	ulong bno, tbno;
	Mdata *md;
	uchar buf[Blen];
	uchar *p = a;

	if(c->qid.path & CHDIR)
		error(Eperm);

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

	/* walk to first data block */
	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);
.
648c
	return sofar;
.
645,646c
	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;
		if(i < 0)
			break;
		memmove(p, md->data, i);
		p += i;
		bno = GETS(md->bno);
		offset = 0;
	}
.
641,643d
634,635c
	for(sofar = 0; sofar + Blen < offset; sofar += Blen){
		md = readdata(fs, bno, buf, 0);
.
632c
	/* walk to starting data block */
.
623c
		return devdirread(c, a, n, 0, 0, tinyfsgen);
.
620a
	uchar *p = a;
.
604c
		free(fs->f);
.
572c
			if(f->flag & Fcreating){
.
384a
			if(done)
				f->flag &= ~Fcreating;
.
382a
				done = 1;
.
370c
			mdata = validdata(fs, buf, 0);
.
360c
		for(done = 0; !done;) {
.
358c
	for(f = fs->f; f < &(fs->f[fs->nf]); f++){
.
344c
		if(fs->nfs >= fs->fsize)
.
316c
	int n, done;
.
308c
 *  block bitmap.  Inconsistent files are purged.  The medium
 *  had better be small or this could take a while.
.
262c
	memmove(f, fs->f, fs->nf*sizeof(f));
.
233c
		md = validdata(fs, buf, 0);
.
194c
	return validdata(fs, buf, lenp);
.
188a
	Mdata *md;

.
187c
readdata(Tfs *fs, ulong bno, uchar *buf, int *lenp)
.
180a
		if(lenp)
			*lenp = x;
.
179c
		if(x > Dlen)
.
175a
		if(lenp)
			*lenp = Dlen;
.
163c
validdata(Tfs *fs, uchar *p, int *lenp)
.
## diffname port/devtinyfs.c 1996/0218
## diff -e /n/fornaxdump/1996/0217/sys/src/brazil/port/devtinyfs.c /n/fornaxdump/1996/0218/sys/src/brazil/port/devtinyfs.c
716a

	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);
.
704,715c
	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;
.
699,700c
		if(md->type == Tagend)
			break;
.
695c
	/* 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 */
.
691a
	if(n == 0)
		return 0;

.
683c
	int sofar, i, x;
.
656,657d
647,648d
628c
	ulong bno;
.
606c
	if(fs->r == 0){
.
604c
	qunlock(fs);
.
597c
			if(f->flag & Frmonclose)
.
573c
	fs = &tinyfs.fs[c->dev];
.
542a
	fs = &tinyfs.fs[c->dev];

.
522c
			f = newfile(fs, fs->f[c->qid.path].name);
.
516c
	if(c->qid.path & CHDIR){
.
491a
	fs = &tinyfs.fs[c->dev];

.
490a
	Tfs *fs;
.
479a
	Tfs *fs;

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

.
448c
		if(fs && eqchan(cc, fs->c, 0))
.
445a
	fs = 0;
.
438c
	cc = namec(spec, Aopen, ORDWR, 0);
.
408a
	USED(ntab, tab);

.
389c
				f->length += GETS(mdata->bno);
.
386c
				f->length += Dlen;
.
369c
				freefile(fs, f, bno);
.
366c
		bno = f->dbno;
.
351c
		if(fs->nf >= fs->fsize)
.
347c
		mdir = validdir(fs, buf);
.
328,329c
	devtab[fs->c->type].stat(fs->c, dbuf);
	convM2D(dbuf, &d);
.
326c
	Mdata *mdata;
.
321a
	uchar buf[Blen];
.
320c
	char dbuf[DIRLEN];
.
304c
	if(f->bno == Notabno)
.
301c
		freefile(fs, f, Notabno);
.
279a
	f = 0;
.
221c
	if(devtab[fs->c->type].write(fs->c, buf, Blen, Blen*f->bno) != Blen)
		error(Eio);
.
219c
	md->sum = 0 - checksum(buf);
.
211c
		return;
.
207d
203c
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
.
197,199c
	if(devtab[fs->c->type].read(fs->c, buf, Blen, Blen*bno) != Blen)
		error(Eio);
.
193,194d
170,171c
	md = (Mdata*)p;
	switch(md->type){
.
153c
	if(p[0] != Tagdir)
.
## diffname port/devtinyfs.c 1996/0220
## diff -e /n/fornaxdump/1996/0218/sys/src/brazil/port/devtinyfs.c /n/fornaxdump/1996/0220/sys/src/brazil/port/devtinyfs.c
786c
	return n;
.
778,782c
	/* update finger */
	if(fbno != Notabno){
		f->finger = finger;
		f->fbno =  fbno;
	}
.
776a
	f->length += n;
.
770,775c
		writedata(fs, bno, dbno, md->data, i+next, last == n+offset);
.
751,768c
	/* point to new blocks */
	if(offset == 0){
		f->dbno = dbno;
		writedir(fs, f);
	} else {
		i = last - offset;
		next = offset%Dlen;
		if(i > 0){
			p -= i;
			memmove(md->data + next, p, i);
.
745a
		if(md == 0)
			error(Eio);
.
743,744c
	md = (Mdata*)buf;
	if(f->finger < offset && f->fbno != Notabno){
		next = f->finger;
		bno = f->fbno;
	} else {
		next = 0;
		bno = f->dbno;
	}
	for(; next < offset; next += Dlen){
.
741a
	/* write blocks backwards */
	p += n;
	last = offset + n;
	off = offset;
	fbno = Notabno;
	finger = 0;
	for(next = (last/Dlen)*Dlen; next >= off; next -= Dlen){
		bno = mapalloc(fs);
		if(bno == Notabno){
			error("out of space");
		}
		i = last - next;
		p -= i;
		if(last == n+offset){
			writedata(fs, bno, dbno, p, i, 1);
			finger = next;	/* remember for later */
			fbno = bno;
		} else
			writedata(fs, bno, dbno, p, i, 0);
		dbno = bno;
		last = next;
	}

.
737c
		freeblocks(fs, dbno, Notabno);
.
735a
	dbno = Notabno;
.
728c
	fs = &tinyfs.fs[c->dev];
.
716,717c
	int last, next, i, off, finger;
	ulong bno, dbno, fbno;
.
712c
tinyfswrite(Chan *c, void *a, long n, ulong offset)
.
710a
/*
 *  if we get a write error in this routine, blocks will
 *  be lost.  They should be recovered next fsinit.
 */
.
700a
	qunlock(fs);
	poperror();
.
699c
		off = 0;
.
694,695d
691c
		if(md == 0)
			error(Eio);

		/* update finger for successful read */
		f->finger = offset + sofar;
		f->fbno = bno;

		i -= off;
.
688c
	off = offset%Dlen;
	offset -= off;
.
683a
		if(md == 0)
			error(Eio);
.
681,682c
	if(f->finger < offset && f->fbno != Notabno){
		sofar = f->finger;
		bno = f->fbno;
	} else {
		sofar = 0;
		bno = f->dbno;
	}
	for(; sofar + Dlen < offset; sofar += Dlen){
.
676a

	qlock(fs);
	if(waserror()){
		qunlock(fs);
		nexterror();
	}
.
673c
	fs = &tinyfs.fs[c->dev];
.
664c
	int sofar, i, off;
.
656c
	qunlock(fs);
.
654c
		fs->c = 0;
.
644,652c
		if(fs->f)
			free(fs->f);
		fs->f = 0;
		fs->nf = 0;
		fs->fsize = 0;
		if(fs->map)
			free(fs->map);
		fs->map = 0;
.
641,642d
636a
		poperror();
.
634,635d
632d
630a
					f->flag &= ~Fcreating;
.
615,629c
	if(!waserror()){
		if(c->qid.path != CHDIR){
			f = &fs->f[c->qid.path];
			f->r--;
			if(f->r == 0){
				if(f->flag & Frmonclose)
					freefile(fs, f, Notabno);
				else if(f->flag & Fcreating){
					/* remove all other files with this name */
					for(i = 0; i < fs->fsize; i++){
						nf = &fs->f[i];
						if(f == nf)
							continue;
						if(strcmp(nf->name, f->name) == 0){
							if(nf->r)
								nf->flag |= Frmonclose;
							else
								freefile(fs, nf, Notabno);
						}
.
606c
	Tfs *fs;
.
592,593c
	Tfs *fs;
	Tfile *f;

	if(c->qid.path == CHDIR)
		error(Eperm);
	fs = &tinyfs.fs[c->dev];
	f = &fs->f[c->qid.path];
	qlock(fs);
	freefile(fs, f, Notabno);
	qunlock(fs);
.
582a
	poperror();
.
580a
	if(waserror()){
		qunlock(fs);
		nexterror();
	}
.
575,576c
	USED(perm);
.
563a
		poperror();
.
559,560c
			break;
		case OREAD:
			break;
		default:
.
557a
			fs->f[c->qid.path].r--;
.
556c
		if(waserror()){
			qunlock(fs);
			nexterror();
		}
		switch(omode){
		case OTRUNC|ORDWR:
		case OTRUNC|OWRITE:
.
494d
492c
		qunlock(fs);
.
490a
		fs->f = 0;
		fs->nf = 0;
		fs->fsize = 0;
.
487,488d
485c
		for(fs = tinyfs.fs; fs < &tinyfs.fs[Maxfs]; fs++){
			qlock(fs);
			if(fs->r == 0)
				break;
			qunlock(fs);
		}
		if(fs == &tinyfs.fs[Maxfs])
.
479,480c
	if(i < Maxfs){
.
477a
		qunlock(fs);
.
476c
		qlock(fs);
		if(fs->r && eqchan(cc, fs->c, 0))
.
474c
	for(i = 0; i < Maxfs; i++){
.
472d
468d
465c
	p = 0;
	if(strcmp(spec, "hd0") == 0)
		p = "#H/hd0nvram";
	else
		error("bad spec");

	cc = namec(p, Aopen, ORDWR, 0);
.
463a
	char *p;
.
439a
	if(f->name[0] == 0)
		return 0;
.
321a
	f->fbno = Notabno;
	f->r = 1;
.
314a
		}
.
313c
		if(i < fs->fsize){
			if(i >= fs->nf)
				fs->nf = i+1;
.
291,292c
	if(fs->f){
		memmove(f, fs->f, fs->nf*sizeof(*f));
		free(fs->f);
	}
.
276a
		mapclr(fs, f->bno);
.
272,273c
		if(devtab[fs->c->type].read(fs->c, buf, Blen, Blen*f->bno) != Blen)
.
269a
	poperror();
}

static void
freefile(Tfs *fs, Tfile *f, ulong bend)
{
	uchar buf[Blen];

	/* remove blocks from map */
	freeblocks(fs, f->dbno, bend);

.
259,260c
		if(devtab[fs->c->type].read(fs->c, buf, Blen, Blen*bno) != Blen)
.
255,256c
	if(waserror())
		return;

.
251,252d
248c
freeblocks(Tfs *fs, ulong bno, ulong bend)
.
141,142c

	return Notabno;
.
137d
128d
83d
65a

	/* hint to avoid egregious reading */
	ushort	fbno;
	ulong	finger;
.
52c
	uchar	data[Dlen];
.
## diffname port/devtinyfs.c 1996/0221
## diff -e /n/fornaxdump/1996/0220/sys/src/brazil/port/devtinyfs.c /n/fornaxdump/1996/0221/sys/src/brazil/port/devtinyfs.c
487a
	else if(strncmp(spec, "hd1") == 0)
		p = "#H/hd1nvram";
	else if(strncmp(spec, "sd0") == 0)
		p = "#H/sd0nvram";
	else if(strncmp(spec, "sd1") == 0)
		p = "#H/sd1nvram";
.
486c
	if(strncmp(spec, "hd0") == 0)
.
## diffname port/devtinyfs.c 1996/0223
## diff -e /n/fornaxdump/1996/0221/sys/src/brazil/port/devtinyfs.c /n/fornaxdump/1996/0223/sys/src/brazil/port/devtinyfs.c
12d
## diffname port/devtinyfs.c 1996/0226
## diff -e /n/fornaxdump/1996/0223/sys/src/brazil/port/devtinyfs.c /n/fornaxdump/1996/0226/sys/src/brazil/port/devtinyfs.c
889c
	qunlock(&fs->ql);
.
823c
		qunlock(&fs->ql);
.
819c
	qlock(&fs->ql);
.
779c
	qunlock(&fs->ql);
.
738c
		qunlock(&fs->ql);
.
736c
	qlock(&fs->ql);
.
714c
	qunlock(&fs->ql);
.
670c
	qlock(&fs->ql);
.
651c
	qunlock(&fs->ql);
.
649c
	qlock(&fs->ql);
.
631c
	qunlock(&fs->ql);
.
627c
		qunlock(&fs->ql);
.
625c
	qlock(&fs->ql);
.
608c
		qunlock(&fs->ql);
.
593c
			qunlock(&fs->ql);
.
591c
		qlock(&fs->ql);
.
569c
	qunlock(&fs->ql);
.
563c
	qlock(&fs->ql);
.
550c
	qunlock(&fs->ql);
.
548c
	qlock(&fs->ql);
.
529c
		qunlock(&fs->ql);
.
519c
			qunlock(&fs->ql);
.
516c
			qlock(&fs->ql);
.
512c
		qunlock(&fs->ql);
.
508c
		qunlock(&fs->ql);
.
505c
		qlock(&fs->ql);
.
485,492c
	if(strncmp(spec, "hd0", 3) == 0)
		p = "/dev/hd0nvram";
	else if(strncmp(spec, "hd1", 3) == 0)
		p = "/dev/hd1nvram";
	else if(strncmp(spec, "sd0", 3) == 0)
		p = "/dev/sd0nvram";
	else if(strncmp(spec, "sd1", 3) == 0)
		p = "/dev/sd1nvram";
.
84d
73c
	QLock	ql;
.
57d
## diffname port/devtinyfs.c 1997/0327
## diff -e /n/fornaxdump/1996/0226/sys/src/brazil/port/devtinyfs.c /n/emeliedump/1997/0327/sys/src/brazil/port/devtinyfs.c
892,896c
Dev tinyfsdevtab = {
	tinyfsreset,
	devinit,
	tinyfsattach,
	tinyfsclone,
	tinyfswalk,
	tinyfsstat,
	tinyfsopen,
	tinyfscreate,
	tinyfsclose,
	tinyfsread,
	devbread,
	tinyfswrite,
	devbwrite,
	tinyfsremove,
	devwstat,
};
.
793c
static long
.
783,788d
715c
static long
.
709c
		cclose(fs->c);
.
652,659c
static void
.
637c
static void
.
613c
static void
.
577c
static Chan*
.
571c
static void
.
553c
static int
.
539c
static Chan*
.
511c
		cclose(cc);
.
496c
		cclose(cc);
.
469,474c
static Chan*
.
462c
static void
.
411c
			n = devtab[fs->c->type]->read(fs->c, buf, Blen, Blen*bno);
.
382c
		n = devtab[fs->c->type]->read(fs->c, buf, Blen, Blen*bno);
.
367c
	devtab[fs->c->type]->stat(fs->c, dbuf);
.
282c
		devtab[fs->c->type]->write(fs->c, buf, Blen, Blen*f->bno);
.
279c
		if(devtab[fs->c->type]->read(fs->c, buf, Blen, Blen*f->bno) != Blen)
.
256c
		if(devtab[fs->c->type]->read(fs->c, buf, Blen, Blen*bno) != Blen)
.
241c
	if(devtab[fs->c->type]->write(fs->c, buf, Blen, Blen*f->bno) != Blen)
.
220c
	if(devtab[fs->c->type]->write(fs->c, &md, Blen, Blen*bno) != Blen)
.
193c
	if(devtab[fs->c->type]->read(fs->c, buf, Blen, Blen*bno) != Blen)
.
## diffname port/devtinyfs.c 1997/0408
## diff -e /n/emeliedump/1997/0327/sys/src/brazil/port/devtinyfs.c /n/emeliedump/1997/0408/sys/src/brazil/port/devtinyfs.c
874a
	'U',
	"tinyfs",

.
## diffname port/devtinyfs.c 1999/0612
## diff -e /n/emeliedump/1997/0408/sys/src/brazil/port/devtinyfs.c /n/emeliedump/1999/0612/sys/src/brazil/port/devtinyfs.c
878,879c
	devreset,
	tinyfsinit,
.
875c
	'F',
.
869c
	qunlock(&rock.fs->ql);
.
859c
		writedata(rock.fs, bno, rock.dbno, md->data, used, last == n+offset);
.
857c
			memmove(md->data + used, p, i);
			used += i;
.
854d
852a
		/* updating a current block */
.
850,851c
		/* first block in a file */
		f->dbno = rock.dbno;
		writedir(rock.fs, f);
.
844a
		}
		next += Dlen;
		if(next > offset)
			panic("devtinyfs1");
.
843c
		if(md->type == Tagend){
			if(next + Dlen < offset)
				panic("devtinyfs1");
.
839,840c

	used = 0;
	while(bno != Notabno){
		md = readdata(rock.fs, bno, buf, &used);
.
832c
	if(0 && f->finger < offset && f->fbno != Notabno){
.
824,826c
		} else {
			writedata(rock.fs, bno, rock.dbno, p, i, 0);
		}
		rock.dbno = bno;
.
821c
			writedata(rock.fs, bno, rock.dbno, p, i, 1);
.
817d
813,815c
	off = offset; /* so we have something signed to compare against */
	for(next = ((last-1)/Dlen)*Dlen; next >= off; next -= Dlen){
		bno = mapalloc(rock.fs);
		if(bno == Notabno)
.
810d
806a
	/* files are append only, anything else is illegal */
	if(offset != f->length)
		error("append only");

.
802,803c
		freeblocks(rock.fs, rock.dbno, Notabno);
		qunlock(&rock.fs->ql);
.
795,800c
	qlock(&rock.fs->ql);
	rock.dbno = Notabno;
.
792,793c
	p = a;
	rock.fs = &tinyfs.fs[c->dev];
	f = &rock.fs->f[c->qid.path];
.
784c
	uchar *p;
	volatile struct {
		Tfs *fs;
		ulong dbno;
	} rock;
.
780,781c
	int last, next, i, finger, off, used;
	ulong bno, fbno;
.
778d
776c
tinyfswrite(Chan *c, void *a, long n, vlong offset)
.
765c
	qunlock(&rock.fs->ql);
.
758,760c
		if(i > n - sofar)
			i = n - sofar;
		memmove(p, md->data+off, i);
.
755a
		offset += Dlen;
.
754c
		f->finger = offset;
.
749c
		md = readdata(rock.fs, bno, buf, &i);
.
738,739c
	for(; sofar + Dlen <= offset; sofar += Dlen){
		md = readdata(rock.fs, bno, buf, 0);
.
731c
	if(0 && f->finger <= offset && f->fbno != Notabno){
.
724c
		qunlock(&rock.fs->ql);
.
722c
	qlock(&rock.fs->ql);
.
717,718c
	p = a;
	rock.fs = &tinyfs.fs[c->dev];
	f = &rock.fs->f[c->qid.path];
.
712c
	uchar *p;
.
706c
	volatile struct { Tfs *fs; } rock;
.
704c
tinyfsread(Chan *c, void *a, long n, vlong offset)
.
700c
	qunlock(&rock.fs->ql);
.
686,698c
	/* dereference rock.fs and remove on zero refs */
	rock.fs->r--;
	if(rock.fs->r == 0){
		if(rock.fs->f)
			free(rock.fs->f);
		rock.fs->f = 0;
		rock.fs->nf = 0;
		rock.fs->fsize = 0;
		if(rock.fs->map)
			free(rock.fs->map);
		rock.fs->map = 0;
		cclose(rock.fs->c);
		rock.fs->c = 0;
.
676c
								freefile(rock.fs, nf, Notabno);
.
668,669c
					for(i = 0; i < rock.fs->fsize; i++){
						nf = &rock.fs->f[i];
.
665c
					freefile(rock.fs, f, Notabno);
.
661c
			f = &rock.fs->f[c->qid.path];
.
656c
	qlock(&rock.fs->ql);
.
654c
	rock.fs = &tinyfs.fs[c->dev];
.
650c
	volatile struct { Tfs *fs; } rock;
.
627c
	c->qid.path = f - rock.fs->f;
.
623,624c
	f = newfile(rock.fs, name);
	qunlock(&rock.fs->ql);
.
620c
		qunlock(&rock.fs->ql);
.
618c
	qlock(&rock.fs->ql);
.
616c
	rock.fs = &tinyfs.fs[c->dev];
.
611c
	volatile struct { Tfs *fs; } rock;
.
601c
		qunlock(&rock.fs->ql);
.
592,594c
			f = newfile(rock.fs, rock.fs->f[c->qid.path].name);
			rock.fs->f[c->qid.path].r--;
			c->qid.path = f - rock.fs->f;
.
586c
			qunlock(&rock.fs->ql);
.
584c
		qlock(&rock.fs->ql);
.
578c
	rock.fs = &tinyfs.fs[c->dev];
.
576a
	volatile struct { Tfs *fs; } rock;
.
575d
526c
	c = devattach('F', spec);
.
521c
		tfsinit(fs);
.
516c
		fs->c = rock.cc;
.
506c
		cclose(rock.cc);
.
499c
		if(fs->r && eqchan(rock.cc, fs->c, 1))
.
491c
		cclose(rock.cc);
.
489c
	rock.cc = fdtochan(fd, ORDWR, 0, 1);
.
477,487c
	fd = atoi(spec);
	if(fd < 0)
		error("bad specifier");
.
473,475c
	Chan *c;
	volatile struct { Chan *cc; } rock;
	int i, fd;
.
470c
tinyfsattach(void *spec)
.
468a
/*
 *  specifier is an open file descriptor
 */
.
466c
		panic("tinyfsinit");
.
463c
tinyfsinit(void)
.
448c
	USED(ntab);
	USED(tab);
.
400a
		f->fbno = Notabno;
.
375c
	fs->map = malloc(x);
.
356c
tfsinit(Tfs *fs)
.
347c
	return rock.f;
.
344c
	writedir(rock.fs, rock.f);
.
342c
	if(rock.f->bno == Notabno)
.
339c
		freefile(rock.fs, rock.f, Notabno);
.
331,335c
	rock.f->flag = Fcreating;
	rock.f->dbno = Notabno;
	rock.f->bno = mapalloc(rock.fs);
	rock.f->fbno = Notabno;
	rock.f->r = 1;
	rock.f->pin = Notapin;  // what is a pin??
.
328c
		expand(rock.fs);
.
322,324c
		if(i < rock.fs->fsize){
			if(i >= rock.fs->nf)
				rock.fs->nf = i+1;
.
314,317c
		for(i = 0; i < rock.fs->fsize; i++){
			rock.f = &rock.fs->f[i];
			if(rock.f->name[0] == 0){
				strncpy(rock.f->name, name, sizeof(rock.f->name)-1);
.
312c
	rock.f = 0;
	rock.fs = fs;
.
309c
	volatile struct {
		Tfile *f;
		Tfs *fs;
	} rock;
.
296c
	f = malloc(fs->fsize*sizeof(*f));
.
279,281c
		memset(buf, 0x55, Blen);
.
240c
	
.
183a
	default:
		return 0;
.
32c
	Frmonclose=	2
.
5,12d
3a
#include "u.h"
#include "../port/lib.h"
#include "../port/error.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
.
## diffname port/devtinyfs.c 1999/0618
## diff -e /n/emeliedump/1999/0612/sys/src/brazil/port/devtinyfs.c /n/emeliedump/1999/0618/sys/src/brazil/port/devtinyfs.c
596a
		case OEXEC:
.
489d
485,487c
	snprint(buf, sizeof(buf), "/dev/%s", spec);
	rock.cc = namec(buf, Aopen, ORDWR, 0);
.
483c
	int i;
	char buf[NAMELEN*2];
.
463c
	devdir(c, qid, f->name, f->length, eve, 0775, dp);
.
## diffname port/devtinyfs.c 1999/0623
## diff -e /n/emeliedump/1999/0618/sys/src/brazil/port/devtinyfs.c /n/emeliedump/1999/0623/sys/src/brazil/port/devtinyfs.c
478c
tinyfsattach(char *spec)
.
## diffname port/devtinyfs.c 1999/1230
## diff -e /n/emeliedump/1999/0623/sys/src/brazil/port/devtinyfs.c /n/emeliedump/1999/1230/sys/src/9/port/devtinyfs.c
462d
457a
	if(i == DEVDOTDOT){
		qid.path = CHDIR;
		devdir(c, qid, ".", 0, eve, 0555, dp);
		return 1;
	}
.
454a
	qid.vers = 0;
.

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.