## 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<map[i] = x|(1<>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; .