From c62bf5a258a49b36cd677c1866b74c354566614c Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sun, 18 Feb 1996 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1996-02-18 --- port/devtinyfs.c | 176 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 122 insertions(+), 54 deletions(-) diff --git a/port/devtinyfs.c b/port/devtinyfs.c index beef848d9d46adbc59796ad5d7a9a521da405b80..770f2e4903765814994eece3a98fb68012030dd5 100644 --- a/port/devtinyfs.c +++ b/port/devtinyfs.c @@ -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; }