plan 9 kernel history: overview | file list | diff list

1996/0202/port/devtinyfs.c (diff list | history)

1996/0201/sys/src/9/port/devtinyfs.c:1,51996/0202/sys/src/9/port/devtinyfs.c:1,5 (short | long | prev | next)
1996/0116    
/* 
 *  template for making a new device 
1996/0202    
 *  a pity the code isn't also tiny... 
1996/0116    
 */ 
 
#include	"u.h" 
1996/0201/sys/src/9/port/devtinyfs.c:26,351996/0202/sys/src/9/port/devtinyfs.c:26,36
1996/0201    
	Tagend=		'e', 
	Tagfree=	'f', 
 
	Nopin=		0xffff; 
1996/0202    
	Notapin=		0xffff, 
	Notabno=		0xffff, 
1996/0116    
}; 
 
1996/0201    
/* medium representation of a Tdir */ 
1996/0202    
/* representation of a Tdir on medium */ 
1996/0201    
typedef struct Mdir Mdir; 
struct Mdir { 
	uchar	type; 
1996/0201/sys/src/9/port/devtinyfs.c:40,461996/0202/sys/src/9/port/devtinyfs.c:41,47
1996/0201    
	uchar	sum; 
}; 
 
/* medium representation of a Tdata/Tend */ 
1996/0202    
/* representation of a Tdata/Tend on medium */ 
1996/0201    
typedef struct Mdata Mdata; 
struct Mdata { 
	uchar	type; 
1996/0201/sys/src/9/port/devtinyfs.c:51,661996/0202/sys/src/9/port/devtinyfs.c:52,69
1996/0201    
 
typedef struct Tfile Tfile; 
struct Tfile { 
1996/0202    
	int	r; 
1996/0201    
	char	name[NAMELEN]; 
	ushort	bno; 
	ushort	dbno; 
	ushort	pin; 
1996/0202    
	char	creating; 
1996/0201    
	ulong	length; 
}; 
 
typedef struct Tfs Tfs; 
struct Tfs { 
	Lock; 
1996/0202    
	QLock; 
1996/0201    
	int	r; 
1996/0116    
	Chan	*c; 
1996/0131    
	uchar	*map; 
1996/0201/sys/src/9/port/devtinyfs.c:91,961996/0202/sys/src/9/port/devtinyfs.c:94,100
1996/0131    
	s = 0; 
	for(e = p + Blen; p < e; p++) 
		s += *p; 
1996/0202    
	return s; 
1996/0131    
} 
1996/0123    
 
1996/0131    
static void 
1996/0201/sys/src/9/port/devtinyfs.c:175,1801996/0202/sys/src/9/port/devtinyfs.c:179,205
1996/0201    
	return md; 
} 
 
1996/0202    
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); 
} 
 
1996/0201    
static void 
freefile(Tfs *fs, Tfile *f, ulong bend) 
{ 
1996/0201/sys/src/9/port/devtinyfs.c:185,1911996/0202/sys/src/9/port/devtinyfs.c:210,216
1996/0201    
 
	/* remove blocks from map */ 
	bno = f->dbno; 
	while(bend != bno){ 
1996/0202    
	while(bno != bend && bno != Notabno){ 
1996/0201    
		mapclr(fs, bno); 
		n = devtab[fs->c->type].read(fs->c, buf, Blen, Blen*bno); 
		if(n != Blen) 
1996/0201/sys/src/9/port/devtinyfs.c:199,2091996/0202/sys/src/9/port/devtinyfs.c:224,236
1996/0201    
	} 
 
	/* 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); 
1996/0202    
	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); 
	} 
1996/0201    
 
	/* forget we ever knew about it */ 
	memset(f, 0, sizeof(*f)); 
1996/0201/sys/src/9/port/devtinyfs.c:217,2311996/0202/sys/src/9/port/devtinyfs.c:244,296
1996/0201    
	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); 
} 
 
1996/0202    
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; 
} 
 
1996/0123    
/* 
 *  see if we have a reasonable fat/root directory 
1996/0202    
 *  Read the whole medium and build a file table and used 
 *  block bitmap.  Inconsistent files are purged. 
1996/0123    
 */ 
1996/0201    
static void 
fsinit(Tfs *fs) 
1996/0201/sys/src/9/port/devtinyfs.c:263,2681996/0202/sys/src/9/port/devtinyfs.c:328,334
1996/0201    
 
		if(fs->nfs <= fs->fsize) 
			expand(fs); 
1996/0202    
 
1996/0201    
		f = &fs->f[fs->nf++]; 
 
		x = GETS(mdir->bno); 
1996/0201/sys/src/9/port/devtinyfs.c:305,3101996/0202/sys/src/9/port/devtinyfs.c:371,379
1996/0131    
	} 
1996/0123    
} 
 
1996/0202    
/* 
 *  single directory 
 */ 
1996/0201    
static int 
tinyfsgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp) 
1996/0123    
{ 
1996/0201/sys/src/9/port/devtinyfs.c:318,3241996/0202/sys/src/9/port/devtinyfs.c:387,393
1996/0201    
	f = &fs->f[i]; 
	qid.path = i; 
	qid.vers = 0; 
	devdir(c, qid, f->name, f->length, eve, f->pin==Nopin?0444:0666, dp); 
1996/0202    
	devdir(c, qid, f->name, f->length, eve, 0664, dp); 
1996/0201    
	return 1; 
1996/0123    
} 
 
1996/0201/sys/src/9/port/devtinyfs.c:355,3631996/0202/sys/src/9/port/devtinyfs.c:424,432
1996/0122    
			break; 
	} 
1996/0201    
	if(i < tinyfs.nfs){ 
		lock(fs); 
1996/0202    
		qlock(fs); 
1996/0201    
		fs->r++; 
		unlock(fs); 
1996/0202    
		qunlock(fs); 
1996/0122    
		close(cc); 
	} else { 
1996/0201    
		if(tinyfs.nfs >= Maxfs) 
1996/0201/sys/src/9/port/devtinyfs.c:383,3881996/0202/sys/src/9/port/devtinyfs.c:452,461
1996/0116    
Chan * 
tinyfsclone(Chan *c, Chan *nc) 
{ 
1996/0202    
	qlock(fs); 
	fs->r++; 
	qunlock(fs); 
 
1996/0116    
	return devclone(c, nc); 
} 
 
1996/0201/sys/src/9/port/devtinyfs.c:389,3951996/0202/sys/src/9/port/devtinyfs.c:462,477
1996/0116    
int 
tinyfswalk(Chan *c, char *name) 
{ 
1996/0201    
	return devwalk(c, name, 0, 0, tinyfsgen); 
1996/0202    
	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; 
1996/0116    
} 
 
void 
1996/0201/sys/src/9/port/devtinyfs.c:410,4261996/0202/sys/src/9/port/devtinyfs.c:492,506
1996/0201    
		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); 
1996/0202    
		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); 
1996/0201    
		} 
1996/0202    
		qunlock(fs); 
1996/0201    
	} 
 
	return devopen(c, omode, 0, 0, tinyfsgen); 
1996/0201/sys/src/9/port/devtinyfs.c:435,4621996/0202/sys/src/9/port/devtinyfs.c:515,527
1996/0116    
	if(perm & CHDIR) 
		error("directory creation illegal"); 
 
1996/0201    
	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; 
1996/0202    
	qlock(fs); 
	f = newfile(fs, name); 
	qunlock(fs); 
1996/0201    
 
		unlock(fs); 
		expand(fs); 
1996/0116    
	} 
1996/0201    
	unlock(fs); 
                 
	c->qid.path = f - fs->f; 
	c->qid.vers = 1;		/* creating */ 
1996/0202    
	c->qid.vers = 0; 
1996/0116    
	c->mode = openmode(omode); 
	c->flag |= COPEN; 
} 
 
void 
1996/0201/sys/src/9/port/devtinyfs.c:478,4941996/0202/sys/src/9/port/devtinyfs.c:543,572
1996/0116    
{ 
1996/0201    
	Tfs *fs, **l; 
	Tfile *f, *nf; 
1996/0202    
	int i; 
1996/0201    
 
	fs = c->aux; 
	lock(fs); 
	fs->ref--; 
	unlock(fs); 
 
	if(fs->ref) 
		return; 
1996/0202    
	qlock(fs); 
1996/0201    
 
	qlock(&tinyfs); 
	lock(fs); 
1996/0202    
	/* 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--; 
1996/0201    
	if(fs->ref == 0){ 
		for(l = &fs->l; *l;){ 
			if(*l == fs){ 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)