| plan 9 kernel history: overview | file list | diff list |
1996/0206/port/devtinyfs.c (diff list | history)
| 1996/0116/sys/src/9/port/devtinyfs.c:13,21 – 1996/0120/sys/src/9/port/devtinyfs.c:13,20 (short | long) | ||
| 1996/0116 | enum{ Qdir, | |
| 1996/0120 | Qmedium, | |
| 1996/0116 | }; | |
| 1996/0116/sys/src/9/port/devtinyfs.c:22,28 – 1996/0120/sys/src/9/port/devtinyfs.c:21,27 | ||
| 1996/0116 | struct { QLock; Chan *c; | |
| 1996/0120 | Dirtab file[Nfile+1]; | |
| 1996/0116 | int nfile; } tinyfs; | |
| 1996/0116/sys/src/9/port/devtinyfs.c:34,41 – 1996/0120/sys/src/9/port/devtinyfs.c:33,41 | ||
| 1996/0116 | d = tinyfs.file; memmove(d->name, "medium"); d->qid.vers = 0; | |
| 1996/0120 | d->qid.path = Qmedium; | |
| 1996/0116 | d->perm = 0666; | |
| 1996/0120 | tinyfs.nfile = 1; | |
| 1996/0116 | } void | |
| 1996/0116/sys/src/9/port/devtinyfs.c:46,51 – 1996/0120/sys/src/9/port/devtinyfs.c:46,53 | ||
| 1996/0116 | Chan * tinyfsattach(char *spec) { | |
| 1996/0120 | c = namec((char*)arg[0], Aopen, arg[1], 0); | |
| 1996/0116 | return devattach('E', spec); } | |
| 1996/0116/sys/src/9/port/devtinyfs.c:97,103 – 1996/0120/sys/src/9/port/devtinyfs.c:99,105 | ||
| 1996/0116 | d->qid.vers = 0; d->qid.path = tinyfs.high++; tinyfs.nfile++; | |
| 1996/0120 | ||
| 1996/0116 | qunlock(&tinyfs); c->mode = openmode(omode); | |
| 1996/0120/sys/src/9/port/devtinyfs.c:17,28 – 1996/0122/sys/src/9/port/devtinyfs.c:17,39 (short | long) | ||
| 1996/0120 | Qmedium, | |
| 1996/0116 | }; | |
| 1996/0122 | typedef struct FS FS; | |
| 1996/0116 |
| |
| 1996/0122 | struct FS { | |
| 1996/0116 | QLock; | |
| 1996/0122 | Ref r; int dev; FS *next; | |
| 1996/0116 | Chan *c; | |
| 1996/0120 |
| |
| 1996/0122 | Dirtab *file; | |
| 1996/0116 | int nfile; | |
| 1996/0122 | int maxfile; }; struct { QLock; FS *l; int hidev; | |
| 1996/0116 | } tinyfs; void | |
| 1996/0120/sys/src/9/port/devtinyfs.c:46,54 – 1996/0122/sys/src/9/port/devtinyfs.c:57,90 | ||
| 1996/0116 | Chan * tinyfsattach(char *spec) { | |
| 1996/0120 |
| |
| 1996/0122 | FS *fs, **l; Chan *c, *cc; | |
| 1996/0120 | ||
| 1996/0116 |
| |
| 1996/0122 | 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; | |
| 1996/0116 | } Chan * | |
| 1996/0122/sys/src/9/port/devtinyfs.c:13,20 – 1996/0123/sys/src/9/port/devtinyfs.c:13,23 (short | long) | ||
| 1996/0116 | enum{ Qdir, | |
| 1996/0123 | Nfile= 32, | |
| 1996/0120 | Qmedium, | |
| 1996/0123 | Magic= 0xfeedbeef, Superlen= 64, | |
| 1996/0116 | }; | |
| 1996/0122 | typedef struct FS FS; | |
| 1996/0122/sys/src/9/port/devtinyfs.c:25,33 – 1996/0123/sys/src/9/port/devtinyfs.c:28,36 | ||
| 1996/0122 | int dev; FS *next; | |
| 1996/0116 | Chan *c; | |
| 1996/0122 |
| |
| 1996/0116 |
| |
| 1996/0122 |
| |
| 1996/0123 | uchar *fat; ulong nclust; ulong clustsize; | |
| 1996/0122 | }; struct { | |
| 1996/0122/sys/src/9/port/devtinyfs.c:39,52 – 1996/0123/sys/src/9/port/devtinyfs.c:42,47 | ||
| 1996/0116 | void tinyfsreset(void) { | |
| 1996/0120 |
| |
| 1996/0116 |
| |
| 1996/0120 |
| |
| 1996/0116 | } void | |
| 1996/0122/sys/src/9/port/devtinyfs.c:54,59 – 1996/0123/sys/src/9/port/devtinyfs.c:49,123 | ||
| 1996/0116 | { } | |
| 1996/0123 | #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); } | |
| 1996/0116 | Chan * tinyfsattach(char *spec) { | |
| 1996/0122/sys/src/9/port/devtinyfs.c:61,66 – 1996/0123/sys/src/9/port/devtinyfs.c:125,135 | ||
| 1996/0122 | Chan *c, *cc; | |
| 1996/0120 | ||
| 1996/0122 | cc = namec((char*)arg[0], Aopen, arg[1], 0); | |
| 1996/0123 | if(waserror()){ close(cc); unlock(&fs); nexterror(); } | |
| 1996/0122 | qlock(&tinyfs); l = &tinyfs.l; for(fs = tinyfs.l; fs != 0; fs = fs->next){ | |
| 1996/0122/sys/src/9/port/devtinyfs.c:74,84 – 1996/0123/sys/src/9/port/devtinyfs.c:143,161 | ||
| 1996/0122 | close(cc); } else { fs = smalloc(sizeof(*fs)); | |
| 1996/0123 | if(waserror()){ free(fs); nexterror(); } if(fsinit(fs) < 0) fssetup(fs); poperror(); *l = fs; | |
| 1996/0122 | qunlock(&tinyfs); } | |
| 1996/0123 | poperror(); | |
| 1996/0122 | c = devattach('E', spec); c->aux = fs; | |
| 1996/0122/sys/src/9/port/devtinyfs.c:123,143 – 1996/0123/sys/src/9/port/devtinyfs.c:200,205 | ||
| 1996/0116 | qunlock(&tinyfs); nexterror(); } | |
| 1996/0120 | ||
| 1996/0116 |
| |
| 1996/0123/sys/src/9/port/devtinyfs.c:13,27 – 1996/0131/sys/src/9/port/devtinyfs.c:13,28 (short | long) | ||
| 1996/0116 | enum{ Qdir, | |
| 1996/0123 |
| |
| 1996/0120 | Qmedium, | |
| 1996/0123 |
| |
| 1996/0131 | Blen= 48, Tdir= 0, Tdata, Tend, | |
| 1996/0116 | }; | |
| 1996/0122 | typedef struct FS FS; | |
| 1996/0116 | ||
| 1996/0122 | struct FS { | |
| 1996/0116 | QLock; | |
| 1996/0122 | Ref r; | |
| 1996/0123/sys/src/9/port/devtinyfs.c:28,36 – 1996/0131/sys/src/9/port/devtinyfs.c:29,36 | ||
| 1996/0122 | int dev; FS *next; | |
| 1996/0116 | Chan *c; | |
| 1996/0123 |
| |
| 1996/0131 | uchar *map; int nblocks; | |
| 1996/0122 | }; struct { | |
| 1996/0123/sys/src/9/port/devtinyfs.c:39,44 – 1996/0131/sys/src/9/port/devtinyfs.c:39,50 | ||
| 1996/0122 | int hidev; | |
| 1996/0116 | } tinyfs; | |
| 1996/0131 | #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)}; | |
| 1996/0116 | void tinyfsreset(void) { | |
| 1996/0123/sys/src/9/port/devtinyfs.c:49,60 – 1996/0131/sys/src/9/port/devtinyfs.c:55,106 | ||
| 1996/0116 | { } | |
| 1996/0123 |
| |
| 1996/0131 | static uchar checksum(uchar *p) { uchar *e; uchar s; | |
| 1996/0123 |
| |
| 1996/0131 | s = 0; for(e = p + Blen; p < e; p++) s += *p; } | |
| 1996/0123 | ||
| 1996/0131 | 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; } | |
| 1996/0123 | /* * see if we have a reasonable fat/root directory */ | |
| 1996/0123/sys/src/9/port/devtinyfs.c:61,97 – 1996/0131/sys/src/9/port/devtinyfs.c:107,141 | ||
| 1996/0123 | static int fsinit(FS *fs) { | |
| 1996/0131 | uchar buf[Blen+DIRLEN]; | |
| 1996/0123 | Dir d; | |
| 1996/0131 | ulong x, bno; | |
| 1996/0123 |
| |
| 1996/0131 | fs->nblocks = d.length/Blen; if(fs->nblocks < 3) | |
| 1996/0123 | error("tinyfs medium too small"); | |
| 1996/0131 | /* 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); | |
| 1996/0123 |
| |
| 1996/0131 | 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; } } | |
| 1996/0123 | } /* | |
| 1996/0131/sys/src/9/port/devtinyfs.c:15,42 – 1996/0201/sys/src/9/port/devtinyfs.c:15,79 (short | long) | ||
| 1996/0116 | Qdir, | |
| 1996/0120 | Qmedium, | |
| 1996/0123 | ||
| 1996/0131 |
| |
| 1996/0201 | Maxfs= 10, /* max file systems */ | |
| 1996/0131 |
| |
| 1996/0201 | Blen= 48, /* block length */ Nlen= 28, /* name length */ Dlen= Blen - 4, Tagdir= 'd', Tagdata= 'D', Tagend= 'e', Tagfree= 'f', Nopin= 0xffff; | |
| 1996/0116 | }; | |
| 1996/0122 |
| |
| 1996/0116 |
| |
| 1996/0122 |
| |
| 1996/0201 | /* 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; | |
| 1996/0116 | Chan *c; | |
| 1996/0131 | uchar *map; int nblocks; | |
| 1996/0201 | Tfile *f; int nf; int fsize; | |
| 1996/0122 | }; struct { QLock; | |
| 1996/0201 | Tfs fs[Maxfs]; short nfs; | |
| 1996/0116 | } tinyfs; | |
| 1996/0131 | #define GETS(x) ((x)[0]|((x)[1]<<8)) | |
| 1996/0131/sys/src/9/port/devtinyfs.c:45,60 – 1996/0201/sys/src/9/port/devtinyfs.c:82,87 | ||
| 1996/0131 | #define GETL(x) (GETS(x)|(GETS(x+2)<<16)) #define PUTL(x, v) {PUTS(x, v);PUTS(x+2, (v)>>16)}; | |
| 1996/0116 |
| |
| 1996/0131 | static uchar checksum(uchar *p) { | |
| 1996/0131/sys/src/9/port/devtinyfs.c:67,86 – 1996/0201/sys/src/9/port/devtinyfs.c:94,119 | ||
| 1996/0131 | } | |
| 1996/0123 | ||
| 1996/0131 | static void | |
| 1996/0201 | mapclr(Tfs *fs, ulong bno) | |
| 1996/0131 | { fs->map[bno>>3] &= ~(1<<(bno&7)); } static void | |
| 1996/0201 | mapset(Tfs *fs, ulong bno) | |
| 1996/0131 | { fs->map[bno>>3] |= 1<<(bno&7); } static int | |
| 1996/0201 | isalloced(Tfs *fs, ulong bno) | |
| 1996/0131 | { | |
| 1996/0201 | return fs->map[bno>>3] & (1<<(bno&7)); } static int mapalloc(Tfs *fs) { | |
| 1996/0131 | int i, j, lim; uchar x; | |
| 1996/0131/sys/src/9/port/devtinyfs.c:101,115 – 1996/0201/sys/src/9/port/devtinyfs.c:134,242 | ||
| 1996/0131 | return -1; } | |
| 1996/0201 | 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); } | |
| 1996/0123 | /* * see if we have a reasonable fat/root directory */ | |
| 1996/0201 | static void fsinit(Tfs *fs) | |
| 1996/0123 | { | |
| 1996/0131 | uchar buf[Blen+DIRLEN]; | |
| 1996/0123 | Dir d; | |
| 1996/0131 | ulong x, bno; | |
| 1996/0201 | int n; Tfile *f; Mdir *mdir; Mdata *mdat; | |
| 1996/0123 | devtab[fs->c->type].stat(fs->c, buf); convM2D(buf, &d); | |
| 1996/0131/sys/src/9/port/devtinyfs.c:119,209 – 1996/0201/sys/src/9/port/devtinyfs.c:246,381 | ||
| 1996/0123 | ||
| 1996/0131 | /* bitmap for block usage */ x = (fs->nblocks + 8 - 1)/8; | |
| 1996/0201 | fs->map = smalloc(x); | |
| 1996/0131 | memset(fs->map, 0x0, x); for(bno = fs->nblocks; bno < x*8; bno++) mapset(fs, bno); | |
| 1996/0123 | ||
| 1996/0201 | /* find files */ | |
| 1996/0131 | for(bno = 0; bno < fs->nblocks; bno++){ n = devtab[fs->c->type].read(fs->c, buf, Blen, Blen*bno); if(n != Blen) break; | |
| 1996/0201 | mdir = validdir(buf); if(mdir == 0) | |
| 1996/0131 | continue; | |
| 1996/0201 | 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; } | |
| 1996/0131 | mapset(fs, bno); | |
| 1996/0201 | switch(mdata->type){ case Tagdata: bno = GETS(mdata->bno); f->len += Dlen; break; case Tagend: f->len += GETS(mdata->bno); break; } | |
| 1996/0131 | } } | |
| 1996/0123 | } | |
| 1996/0201 | static int tinyfsgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp) | |
| 1996/0123 | { | |
| 1996/0201 | Tfs *fs; Tfile *f; Qid qid; | |
| 1996/0123 |
| |
| 1996/0201 | 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; | |
| 1996/0123 | } | |
| 1996/0201 | void tinyfsreset(void) { if(Nlen > NAMELEN) panic("tinyfsreset"); } void tinyfsinit(void) { } | |
| 1996/0116 | Chan * tinyfsattach(char *spec) { | |
| 1996/0122 |
| |
| 1996/0201 | Tfs *fs; | |
| 1996/0122 | Chan *c, *cc; | |
| 1996/0201 | int i; | |
| 1996/0120 | ||
| 1996/0122 | cc = namec((char*)arg[0], Aopen, arg[1], 0); | |
| 1996/0123 | if(waserror()){ close(cc); | |
| 1996/0201 | qunlock(&tinyfs); | |
| 1996/0123 | nexterror(); } | |
| 1996/0201 | ||
| 1996/0122 | qlock(&tinyfs); | |
| 1996/0201 | for(i = 0; i < tinyfs.nfs; i++){ fs = &tinyfs.fs[i]; if(fs && eqchan(c, fs->c)) | |
| 1996/0122 | break; | |
| 1996/0201 | if(i < tinyfs.nfs){ lock(fs); fs->r++; unlock(fs); | |
| 1996/0122 | close(cc); } else { | |
| 1996/0201 | if(tinyfs.nfs >= Maxfs) error("too many tinyfs's"); fs = &tinyfs.fs[tinyfs.nfs]; memset(fs, 0, sizeof(*fs)); | |
| 1996/0122 | fs->c = cc; | |
| 1996/0123 |
| |
| 1996/0122 |
| |
| 1996/0201 | fs->r = 1; fsinit(fs); tinyfs.nfs++; | |
| 1996/0122 | } | |
| 1996/0201 | qunlock(&tinyfs); | |
| 1996/0123 | poperror(); | |
| 1996/0122 |
| |
| 1996/0201 | c = devattach('U', spec); c->dev = fs - tinyfs.fs; c->qid.path = CHDIR; c->qid.vers = 0; | |
| 1996/0122 | return c; | |
| 1996/0116 | } | |
| 1996/0131/sys/src/9/port/devtinyfs.c:217,252 – 1996/0201/sys/src/9/port/devtinyfs.c:389,462 | ||
| 1996/0116 | int tinyfswalk(Chan *c, char *name) { | |
| 1996/0201 | return devwalk(c, name, 0, 0, tinyfsgen); | |
| 1996/0116 | } void tinyfsstat(Chan *c, char *db) { | |
| 1996/0201 | devstat(c, db, 0, 0, tinyfsgen); | |
| 1996/0116 | } Chan * tinyfsopen(Chan *c, int omode) { | |
| 1996/0201 | 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); | |
| 1996/0116 | } void tinyfscreate(Chan *c, char *name, int omode, ulong perm) { | |
| 1996/0201 | Tfs *fs; Tfile *f; | |
| 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; unlock(fs); expand(fs); | |
| 1996/0116 | } | |
| 1996/0201 | unlock(fs); c->qid.path = f - fs->f; c->qid.vers = 1; /* creating */ | |
| 1996/0116 | c->mode = openmode(omode); c->flag |= COPEN; | |
| 1996/0131/sys/src/9/port/devtinyfs.c:266,271 – 1996/0201/sys/src/9/port/devtinyfs.c:476,512 | ||
| 1996/0116 | void tinyfsclose(Chan *c) { | |
| 1996/0201 | 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); | |
| 1996/0116 | } long | |
| 1996/0131/sys/src/9/port/devtinyfs.c:273,279 – 1996/0201/sys/src/9/port/devtinyfs.c:514,520 | ||
| 1996/0116 | { switch(c->qid.path & ~CHDIR){ case Qdir: | |
| 1996/0201 | return devdirread(c, a, n, tinyfstab, Ntinyfstab, tinyfsgen); | |
| 1996/0116 | case Qdata: break; default: | |
| 1996/0201/sys/src/9/port/devtinyfs.c:1,5 – 1996/0202/sys/src/9/port/devtinyfs.c:1,5 (short | long) | ||
| 1996/0116 | /* | |
| 1996/0202 | * a pity the code isn't also tiny... | |
| 1996/0116 | */ #include "u.h" | |
| 1996/0201/sys/src/9/port/devtinyfs.c:26,35 – 1996/0202/sys/src/9/port/devtinyfs.c:26,36 | ||
| 1996/0201 | Tagend= 'e', Tagfree= 'f', | |
| 1996/0202 | Notapin= 0xffff, Notabno= 0xffff, | |
| 1996/0116 | }; | |
| 1996/0201 |
| |
| 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,46 – 1996/0202/sys/src/9/port/devtinyfs.c:41,47 | ||
| 1996/0201 | uchar sum; }; | |
| 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,66 – 1996/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 { | |
| 1996/0202 | QLock; | |
| 1996/0201 | int r; | |
| 1996/0116 | Chan *c; | |
| 1996/0131 | uchar *map; | |
| 1996/0201/sys/src/9/port/devtinyfs.c:91,96 – 1996/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,180 – 1996/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,191 – 1996/0202/sys/src/9/port/devtinyfs.c:210,216 | ||
| 1996/0201 | /* remove blocks from map */ bno = f->dbno; | |
| 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,209 – 1996/0202/sys/src/9/port/devtinyfs.c:224,236 | ||
| 1996/0201 | } /* change file type to free on medium */ | |
| 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,231 – 1996/0202/sys/src/9/port/devtinyfs.c:244,296 | ||
| 1996/0201 | fs->fsize += 8; f = smalloc(fs->fsize*sizeof(*f)); | |
| 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 | /* | |
| 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,268 – 1996/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,310 – 1996/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,324 – 1996/0202/sys/src/9/port/devtinyfs.c:387,393 | ||
| 1996/0201 | f = &fs->f[i]; qid.path = i; qid.vers = 0; | |
| 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,363 – 1996/0202/sys/src/9/port/devtinyfs.c:424,432 | ||
| 1996/0122 | break; } | |
| 1996/0201 | if(i < tinyfs.nfs){ | |
| 1996/0202 | qlock(fs); | |
| 1996/0201 | fs->r++; | |
| 1996/0202 | qunlock(fs); | |
| 1996/0122 | close(cc); } else { | |
| 1996/0201 | if(tinyfs.nfs >= Maxfs) | |
| 1996/0201/sys/src/9/port/devtinyfs.c:383,388 – 1996/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,395 – 1996/0202/sys/src/9/port/devtinyfs.c:462,477 | ||
| 1996/0116 | int tinyfswalk(Chan *c, char *name) { | |
| 1996/0201 |
| |
| 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,426 – 1996/0202/sys/src/9/port/devtinyfs.c:492,506 | ||
| 1996/0201 | if(omode != OREAD) error(Eperm); } else { | |
| 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,462 – 1996/0202/sys/src/9/port/devtinyfs.c:515,527 | ||
| 1996/0116 | if(perm & CHDIR) error("directory creation illegal"); | |
| 1996/0201 |
| |
| 1996/0202 | qlock(fs); f = newfile(fs, name); qunlock(fs); | |
| 1996/0201 |
| |
| 1996/0116 |
| |
| 1996/0201 |
| |
| 1996/0202 | c->qid.vers = 0; | |
| 1996/0116 | c->mode = openmode(omode); | |
| 1996/0201/sys/src/9/port/devtinyfs.c:478,494 – 1996/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; | |
| 1996/0202 | qlock(fs); | |
| 1996/0201 |
| |
| 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){ | |
| 1996/0202/sys/src/9/port/devtinyfs.c:28,33 – 1996/0203/sys/src/9/port/devtinyfs.c:28,36 (short | long) | ||
| 1996/0201 | ||
| 1996/0202 | Notapin= 0xffff, Notabno= 0xffff, | |
| 1996/0203 | Fcreating= 1, Frmonclose= 2, | |
| 1996/0116 | }; | |
| 1996/0202 | /* representation of a Tdir on medium */ | |
| 1996/0202/sys/src/9/port/devtinyfs.c:57,63 – 1996/0203/sys/src/9/port/devtinyfs.c:60,66 | ||
| 1996/0201 | ushort bno; ushort dbno; ushort pin; | |
| 1996/0202 |
| |
| 1996/0203 | uchar flag; | |
| 1996/0201 | ulong length; }; | |
| 1996/0202/sys/src/9/port/devtinyfs.c:271,277 – 1996/0203/sys/src/9/port/devtinyfs.c:274,280 | ||
| 1996/0202 | expand(fs); } | |
| 1996/0203 | f->flag = Fcreating; | |
| 1996/0202 | f->dbno = Notabno; f->bno = mapalloc(fs); | |
| 1996/0202/sys/src/9/port/devtinyfs.c:553,572 – 1996/0203/sys/src/9/port/devtinyfs.c:556,586 | ||
| 1996/0202 | if(c->qid.path != CHDIR){ f = &fs->f[c->qid.path]; f->r--; | |
| 1996/0203 | 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); | |
| 1996/0202 | } | |
| 1996/0203 | if(f->flag & Frmonclose){ freefile(fs, f, Notabno); | |
| 1996/0202 | } } /* dereference fs and remove on zero refs */ fs->r--; | |
| 1996/0203 | unlock(fs); qlock(&tinyfs); | |
| 1996/0201 | if(fs->ref == 0){ for(l = &fs->l; *l;){ if(*l == fs){ | |
| 1996/0202/sys/src/9/port/devtinyfs.c:575,589 – 1996/0203/sys/src/9/port/devtinyfs.c:589,599 | ||
| 1996/0201 | } l = &(*l)->next; } | |
| 1996/0203 | free(fs-f); | |
| 1996/0201 | free(fs->map); close(fs->c); | |
| 1996/0203 | memset(fs, 0, sizeof(*fs)); | |
| 1996/0201 | } | |
| 1996/0116 | } | |
| 1996/0202/sys/src/9/port/devtinyfs.c:590,604 – 1996/0203/sys/src/9/port/devtinyfs.c:600,619 | ||
| 1996/0116 | long tinyfsread(Chan *c, void *a, long n, ulong offset) { | |
| 1996/0203 | Tfs *fs; Tfile *f; int sofar, i; if(c->qid.path & CHDIR) | |
| 1996/0201 | return devdirread(c, a, n, tinyfstab, Ntinyfstab, tinyfsgen); | |
| 1996/0116 |
| |
| 1996/0203 | 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; | |
| 1996/0116 | return n; } | |
| 1996/0203/sys/src/9/port/devtinyfs.c:55,60 – 1996/0206/sys/src/9/port/devtinyfs.c:55,61 (short | long) | ||
| 1996/0201 | typedef struct Tfile Tfile; struct Tfile { | |
| 1996/0206 | Lock; | |
| 1996/0202 | int r; | |
| 1996/0201 | char name[NAMELEN]; ushort bno; | |
| 1996/0203/sys/src/9/port/devtinyfs.c:182,187 – 1996/0206/sys/src/9/port/devtinyfs.c:183,199 | ||
| 1996/0201 | return md; } | |
| 1996/0206 | 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); } | |
| 1996/0202 | static int writedir(Tfs *fs, Tfile *f) { | |
| 1996/0203/sys/src/9/port/devtinyfs.c:603,608 – 1996/0206/sys/src/9/port/devtinyfs.c:615,623 | ||
| 1996/0203 | Tfs *fs; Tfile *f; int sofar, i; | |
| 1996/0206 | ulong bno, tbno; Mdata *md; uchar buf[Blen]; | |
| 1996/0203 | if(c->qid.path & CHDIR) | |
| 1996/0201 | return devdirread(c, a, n, tinyfstab, Ntinyfstab, tinyfsgen); | |
| 1996/0203/sys/src/9/port/devtinyfs.c:613,618 – 1996/0206/sys/src/9/port/devtinyfs.c:628,649 | ||
| 1996/0203 | return 0; if(n + offset >= f->length) n = f->length - offset; | |
| 1996/0206 | /* 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){ | |
| 1996/0203 | ||
| 1996/0116 | return n; } | |
| 1996/0206/sys/src/9/port/devtinyfs.c:160,166 – 1996/0217/sys/src/9/port/devtinyfs.c:160,166 (short | long) | ||
| 1996/0201 | } static Mdata* | |
| 1996/0217 | validdata(Tfs *fs, uchar *p, int *lenp) | |
| 1996/0201 | { Mdata *md; ulong x; | |
| 1996/0206/sys/src/9/port/devtinyfs.c:173,183 – 1996/0217/sys/src/9/port/devtinyfs.c:173,187 | ||
| 1996/0201 | x = GETS(md->bno); if(x >= fs->nblocks) return 0; | |
| 1996/0217 | if(lenp) *lenp = Dlen; | |
| 1996/0201 | break; case Tagend: x = GETS(md->bno); | |
| 1996/0217 | if(x > Dlen) | |
| 1996/0201 | return 0; | |
| 1996/0217 | if(lenp) *lenp = x; | |
| 1996/0201 | break; } return md; | |
| 1996/0206/sys/src/9/port/devtinyfs.c:184,197 – 1996/0217/sys/src/9/port/devtinyfs.c:188,203 | ||
| 1996/0201 | } | |
| 1996/0206 | static Mdata* | |
| 1996/0217 | readdata(Tfs *fs, ulong bno, uchar *buf, int *lenp) | |
| 1996/0206 | { | |
| 1996/0217 | Mdata *md; | |
| 1996/0206 | if(bno >= fs->nblocks) return 0; n = devtab[fs->c->type].read(fs->c, buf, Blen, Blen*bno); if(n != Blen) return 0; | |
| 1996/0217 | return validdata(fs, buf, lenp); | |
| 1996/0206 | } | |
| 1996/0202 | static int | |
| 1996/0206/sys/src/9/port/devtinyfs.c:230,236 – 1996/0217/sys/src/9/port/devtinyfs.c:236,242 | ||
| 1996/0201 | n = devtab[fs->c->type].read(fs->c, buf, Blen, Blen*bno); if(n != Blen) break; | |
| 1996/0217 | md = validdata(fs, buf, 0); | |
| 1996/0201 | if(md == 0) break; if(md->type == Tagend) | |
| 1996/0206/sys/src/9/port/devtinyfs.c:259,265 – 1996/0217/sys/src/9/port/devtinyfs.c:265,271 | ||
| 1996/0201 | fs->fsize += 8; f = smalloc(fs->fsize*sizeof(*f)); | |
| 1996/0217 | memmove(f, fs->f, fs->nf*sizeof(f)); | |
| 1996/0201 | free(fs->f); fs->f = f; } | |
| 1996/0206/sys/src/9/port/devtinyfs.c:305,311 – 1996/0217/sys/src/9/port/devtinyfs.c:311,318 | ||
| 1996/0202 | ||
| 1996/0123 | /* | |
| 1996/0202 | * Read the whole medium and build a file table and used | |
| 1996/0217 | * block bitmap. Inconsistent files are purged. The medium * had better be small or this could take a while. | |
| 1996/0123 | */ | |
| 1996/0201 | static void fsinit(Tfs *fs) | |
| 1996/0206/sys/src/9/port/devtinyfs.c:313,319 – 1996/0217/sys/src/9/port/devtinyfs.c:320,326 | ||
| 1996/0131 | uchar buf[Blen+DIRLEN]; | |
| 1996/0123 | Dir d; | |
| 1996/0131 | ulong x, bno; | |
| 1996/0201 |
| |
| 1996/0217 | int n, done; | |
| 1996/0201 | Tfile *f; Mdir *mdir; Mdata *mdat; | |
| 1996/0206/sys/src/9/port/devtinyfs.c:341,347 – 1996/0217/sys/src/9/port/devtinyfs.c:348,354 | ||
| 1996/0201 | if(mdir == 0) | |
| 1996/0131 | continue; | |
| 1996/0201 |
| |
| 1996/0217 | if(fs->nfs >= fs->fsize) | |
| 1996/0201 | expand(fs); | |
| 1996/0202 | ||
| 1996/0201 | f = &fs->f[fs->nf++]; | |
| 1996/0206/sys/src/9/port/devtinyfs.c:355,363 – 1996/0217/sys/src/9/port/devtinyfs.c:362,370 | ||
| 1996/0201 | } /* follow files */ | |
| 1996/0217 | for(f = fs->f; f < &(fs->f[fs->nf]); f++){ | |
| 1996/0201 | bno = fs->dbno; | |
| 1996/0217 | for(done = 0; !done;) { | |
| 1996/0201 | if(isalloced(fs, bno)){ freefile(f, bno); break; | |
| 1996/0206/sys/src/9/port/devtinyfs.c:367,373 – 1996/0217/sys/src/9/port/devtinyfs.c:374,380 | ||
| 1996/0201 | freefile(fs, f, bno); break; } | |
| 1996/0217 | mdata = validdata(fs, buf, 0); | |
| 1996/0201 | if(mdata == 0){ freefile(fs, f, bno); break; | |
| 1996/0206/sys/src/9/port/devtinyfs.c:380,387 – 1996/0217/sys/src/9/port/devtinyfs.c:387,397 | ||
| 1996/0201 | break; case Tagend: f->len += GETS(mdata->bno); | |
| 1996/0217 | done = 1; | |
| 1996/0201 | break; } | |
| 1996/0217 | if(done) f->flag &= ~Fcreating; | |
| 1996/0131 | } } | |
| 1996/0123 | } | |
| 1996/0206/sys/src/9/port/devtinyfs.c:569,575 – 1996/0217/sys/src/9/port/devtinyfs.c:579,585 | ||
| 1996/0202 | f = &fs->f[c->qid.path]; f->r--; | |
| 1996/0203 | if(f->r == 0){ | |
| 1996/0217 | if(f->flag & Fcreating){ | |
| 1996/0203 | /* remove all other files with this name */ for(i = 0; i < fs->fsize; i++){ nf = &fs->f[i]; | |
| 1996/0206/sys/src/9/port/devtinyfs.c:601,607 – 1996/0217/sys/src/9/port/devtinyfs.c:611,617 | ||
| 1996/0201 | } l = &(*l)->next; } | |
| 1996/0203 |
| |
| 1996/0217 | free(fs->f); | |
| 1996/0201 | free(fs->map); close(fs->c); | |
| 1996/0203 | memset(fs, 0, sizeof(*fs)); | |
| 1996/0206/sys/src/9/port/devtinyfs.c:618,626 – 1996/0217/sys/src/9/port/devtinyfs.c:628,637 | ||
| 1996/0206 | ulong bno, tbno; Mdata *md; uchar buf[Blen]; | |
| 1996/0217 | uchar *p = a; | |
| 1996/0203 | if(c->qid.path & CHDIR) | |
| 1996/0201 |
| |
| 1996/0217 | return devdirread(c, a, n, 0, 0, tinyfsgen); | |
| 1996/0203 | fs = tinyfs.fs[c->dev]; f = &fs->f[c->qid.path]; | |
| 1996/0206/sys/src/9/port/devtinyfs.c:629,651 – 1996/0217/sys/src/9/port/devtinyfs.c:640,672 | ||
| 1996/0203 | if(n + offset >= f->length) n = f->length - offset; | |
| 1996/0206 |
| |
| 1996/0217 | /* walk to starting data block */ | |
| 1996/0206 | bno = f->dbno; | |
| 1996/0217 | for(sofar = 0; sofar + Blen < offset; sofar += Blen){ md = readdata(fs, bno, buf, 0); | |
| 1996/0206 | if(md == 0) error(Eio); bno = GETS(md->bno); } | |
| 1996/0217 | 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; } | |
| 1996/0203 | ||
| 1996/0116 |
| |
| 1996/0217 | return sofar; | |
| 1996/0116 | } Block* | |
| 1996/0206/sys/src/9/port/devtinyfs.c:657,676 – 1996/0217/sys/src/9/port/devtinyfs.c:678,721 | ||
| 1996/0116 | long tinyfswrite(Chan *c, char *a, long n, ulong offset) { | |
| 1996/0217 | 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); | |
| 1996/0116 | } | |
| 1996/0217 | /* 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; | |
| 1996/0116 | } | |
| 1996/0217 | return sofar; | |
| 1996/0116 | } long | |
| 1996/0217/sys/src/9/port/devtinyfs.c:150,156 – 1996/0218/sys/src/9/port/devtinyfs.c:150,156 (short | long) | ||
| 1996/0201 | if(checksum(p) != 0) return 0; | |
| 1996/0218 | if(p[0] != Tagdir) | |
| 1996/0201 | return 0; md = (Mdir*)p; x = GETS(md->bno); | |
| 1996/0217/sys/src/9/port/devtinyfs.c:167,174 – 1996/0218/sys/src/9/port/devtinyfs.c:167,174 | ||
| 1996/0201 | if(checksum(p) != 0) return 0; | |
| 1996/0218 | md = (Mdata*)p; switch(md->type){ | |
| 1996/0201 | case Tagdata: x = GETS(md->bno); if(x >= fs->nblocks) | |
| 1996/0217/sys/src/9/port/devtinyfs.c:190,214 – 1996/0218/sys/src/9/port/devtinyfs.c:190,236 | ||
| 1996/0206 | static Mdata* | |
| 1996/0217 | readdata(Tfs *fs, ulong bno, uchar *buf, int *lenp) | |
| 1996/0206 | { | |
| 1996/0217 |
| |
| 1996/0206 | if(bno >= fs->nblocks) return 0; | |
| 1996/0218 | if(devtab[fs->c->type].read(fs->c, buf, Blen, Blen*bno) != Blen) error(Eio); | |
| 1996/0217 | return validdata(fs, buf, lenp); | |
| 1996/0206 | } | |
| 1996/0202 |
| |
| 1996/0218 | 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 | |
| 1996/0202 | writedir(Tfs *fs, Tfile *f) { Mdir *md; | |
| 1996/0218 | return; | |
| 1996/0202 | md = (Mdir*)buf; memset(buf, 0, Blen); | |
| 1996/0217/sys/src/9/port/devtinyfs.c:216,224 – 1996/0218/sys/src/9/port/devtinyfs.c:238,247 | ||
| 1996/0202 | strncpy(md->name, f->name, sizeof(md->name)-1); PUTS(md->bno, f->dbno); PUTS(md->pin, f->pin); | |
| 1996/0218 | md->sum = 0 - checksum(buf); | |
| 1996/0202 |
| |
| 1996/0218 | if(devtab[fs->c->type].write(fs->c, buf, Blen, Blen*f->bno) != Blen) error(Eio); | |
| 1996/0202 | } | |
| 1996/0201 | static void | |
| 1996/0217/sys/src/9/port/devtinyfs.c:277,282 – 1996/0218/sys/src/9/port/devtinyfs.c:300,306 | ||
| 1996/0202 | Tfile *f; /* find free entry in file table */ | |
| 1996/0218 | f = 0; | |
| 1996/0202 | for(;;) { for(i = 0; i < fs->fsize; i++){ f = &fs->f[i]; | |
| 1996/0217/sys/src/9/port/devtinyfs.c:298,307 – 1996/0218/sys/src/9/port/devtinyfs.c:322,331 | ||
| 1996/0202 | /* write directory block */ if(waserror()){ | |
| 1996/0218 | freefile(fs, f, Notabno); | |
| 1996/0202 | nexterror(); } | |
| 1996/0218 | if(f->bno == Notabno) | |
| 1996/0202 | error("out of space"); writedir(fs, f); poperror(); | |
| 1996/0217/sys/src/9/port/devtinyfs.c:317,332 – 1996/0218/sys/src/9/port/devtinyfs.c:341,357 | ||
| 1996/0201 | static void fsinit(Tfs *fs) | |
| 1996/0123 | { | |
| 1996/0131 |
| |
| 1996/0218 | char dbuf[DIRLEN]; | |
| 1996/0123 | Dir d; | |
| 1996/0218 | uchar buf[Blen]; | |
| 1996/0131 | ulong x, bno; | |
| 1996/0217 | int n, done; | |
| 1996/0201 | Tfile *f; Mdir *mdir; | |
| 1996/0218 | Mdata *mdata; | |
| 1996/0123 |
| |
| 1996/0218 | devtab[fs->c->type].stat(fs->c, dbuf); convM2D(dbuf, &d); | |
| 1996/0131 | fs->nblocks = d.length/Blen; if(fs->nblocks < 3) | |
| 1996/0123 | error("tinyfs medium too small"); | |
| 1996/0217/sys/src/9/port/devtinyfs.c:344,354 – 1996/0218/sys/src/9/port/devtinyfs.c:369,379 | ||
| 1996/0131 | if(n != Blen) break; | |
| 1996/0201 |
| |
| 1996/0218 | mdir = validdir(fs, buf); | |
| 1996/0201 | if(mdir == 0) | |
| 1996/0131 | continue; | |
| 1996/0201 | ||
| 1996/0217 |
| |
| 1996/0218 | if(fs->nf >= fs->fsize) | |
| 1996/0201 | expand(fs); | |
| 1996/0202 | ||
| 1996/0201 | f = &fs->f[fs->nf++]; | |
| 1996/0217/sys/src/9/port/devtinyfs.c:363,372 – 1996/0218/sys/src/9/port/devtinyfs.c:388,397 | ||
| 1996/0201 | /* follow files */ | |
| 1996/0217 | for(f = fs->f; f < &(fs->f[fs->nf]); f++){ | |
| 1996/0201 |
| |
| 1996/0218 | bno = f->dbno; | |
| 1996/0217 | for(done = 0; !done;) { | |
| 1996/0201 | if(isalloced(fs, bno)){ | |
| 1996/0218 | freefile(fs, f, bno); | |
| 1996/0201 | break; } n = devtab[fs->c->type].read(fs->c, buf, Blen, Blen*bno); | |
| 1996/0217/sys/src/9/port/devtinyfs.c:383,392 – 1996/0218/sys/src/9/port/devtinyfs.c:408,417 | ||
| 1996/0201 | switch(mdata->type){ case Tagdata: bno = GETS(mdata->bno); | |
| 1996/0218 | f->length += Dlen; | |
| 1996/0201 | break; case Tagend: | |
| 1996/0218 | f->length += GETS(mdata->bno); | |
| 1996/0217 | done = 1; | |
| 1996/0201 | break; } | |
| 1996/0217/sys/src/9/port/devtinyfs.c:406,411 – 1996/0218/sys/src/9/port/devtinyfs.c:431,438 | ||
| 1996/0201 | Tfile *f; Qid qid; | |
| 1996/0123 | ||
| 1996/0218 | USED(ntab, tab); | |
| 1996/0201 | fs = &tinyfs.fs[c->dev]; if(i >= fs->nf) return -1; | |
| 1996/0217/sys/src/9/port/devtinyfs.c:435,441 – 1996/0218/sys/src/9/port/devtinyfs.c:462,468 | ||
| 1996/0122 | Chan *c, *cc; | |
| 1996/0201 | int i; | |
| 1996/0120 | ||
| 1996/0122 |
| |
| 1996/0218 | cc = namec(spec, Aopen, ORDWR, 0); | |
| 1996/0123 | if(waserror()){ close(cc); | |
| 1996/0201 | qunlock(&tinyfs); | |
| 1996/0217/sys/src/9/port/devtinyfs.c:443,451 – 1996/0218/sys/src/9/port/devtinyfs.c:470,479 | ||
| 1996/0123 | } | |
| 1996/0201 | ||
| 1996/0122 | qlock(&tinyfs); | |
| 1996/0218 | fs = 0; | |
| 1996/0201 | for(i = 0; i < tinyfs.nfs; i++){ fs = &tinyfs.fs[i]; | |
| 1996/0218 | if(fs && eqchan(cc, fs->c, 0)) | |
| 1996/0122 | break; } | |
| 1996/0201 | if(i < tinyfs.nfs){ | |
| 1996/0217/sys/src/9/port/devtinyfs.c:477,482 – 1996/0218/sys/src/9/port/devtinyfs.c:505,514 | ||
| 1996/0116 | Chan * tinyfsclone(Chan *c, Chan *nc) { | |
| 1996/0218 | Tfs *fs; fs = &tinyfs.fs[c->dev]; | |
| 1996/0202 | qlock(fs); fs->r++; qunlock(fs); | |
| 1996/0217/sys/src/9/port/devtinyfs.c:488,494 – 1996/0218/sys/src/9/port/devtinyfs.c:520,529 | ||
| 1996/0116 | tinyfswalk(Chan *c, char *name) { | |
| 1996/0202 | int n; | |
| 1996/0218 | Tfs *fs; | |
| 1996/0202 | ||
| 1996/0218 | fs = &tinyfs.fs[c->dev]; | |
| 1996/0202 | qlock(fs); n = devwalk(c, name, 0, 0, tinyfsgen); if(n != 0 && c->qid.path != CHDIR){ | |
| 1996/0217/sys/src/9/port/devtinyfs.c:513,525 – 1996/0218/sys/src/9/port/devtinyfs.c:548,560 | ||
| 1996/0201 | fs = &tinyfs.fs[c->dev]; | |
| 1996/0218 | if(c->qid.path & CHDIR){ | |
| 1996/0201 | if(omode != OREAD) error(Eperm); } else { | |
| 1996/0202 | qlock(fs); if(omode == (OTRUNC|ORDWR)){ | |
| 1996/0218 | f = newfile(fs, fs->f[c->qid.path].name); | |
| 1996/0202 | c->qid.path = f - fs->f; } else if(omode != OREAD){ qunlock(fs); | |
| 1996/0217/sys/src/9/port/devtinyfs.c:540,545 – 1996/0218/sys/src/9/port/devtinyfs.c:575,582 | ||
| 1996/0116 | if(perm & CHDIR) error("directory creation illegal"); | |
| 1996/0218 | fs = &tinyfs.fs[c->dev]; | |
| 1996/0202 | qlock(fs); f = newfile(fs, name); qunlock(fs); | |
| 1996/0217/sys/src/9/port/devtinyfs.c:570,576 – 1996/0218/sys/src/9/port/devtinyfs.c:607,613 | ||
| 1996/0201 | Tfile *f, *nf; | |
| 1996/0202 | int i; | |
| 1996/0201 |
| |
| 1996/0218 | fs = &tinyfs.fs[c->dev]; | |
| 1996/0201 | ||
| 1996/0202 | qlock(fs); | |
| 1996/0201 | ||
| 1996/0217/sys/src/9/port/devtinyfs.c:594,600 – 1996/0218/sys/src/9/port/devtinyfs.c:631,637 | ||
| 1996/0203 | } f->flag &= ~(Frmonclose|Fcreating); | |
| 1996/0202 | } | |
| 1996/0203 |
| |
| 1996/0218 | if(f->flag & Frmonclose) | |
| 1996/0203 | freefile(fs, f, Notabno); | |
| 1996/0202 | } } | |
| 1996/0217/sys/src/9/port/devtinyfs.c:601,609 – 1996/0218/sys/src/9/port/devtinyfs.c:638,646 | ||
| 1996/0202 | /* dereference fs and remove on zero refs */ fs->r--; | |
| 1996/0203 |
| |
| 1996/0218 | qunlock(fs); | |
| 1996/0203 | qlock(&tinyfs); | |
| 1996/0201 |
| |
| 1996/0218 | if(fs->r == 0){ | |
| 1996/0201 | for(l = &fs->l; *l;){ if(*l == fs){ *l = fs->next; | |
| 1996/0217/sys/src/9/port/devtinyfs.c:625,631 – 1996/0218/sys/src/9/port/devtinyfs.c:662,668 | ||
| 1996/0203 | Tfs *fs; Tfile *f; int sofar, i; | |
| 1996/0206 |
| |
| 1996/0218 | ulong bno; | |
| 1996/0206 | Mdata *md; uchar buf[Blen]; | |
| 1996/0217 | uchar *p = a; | |
| 1996/0217/sys/src/9/port/devtinyfs.c:644,651 – 1996/0218/sys/src/9/port/devtinyfs.c:681,686 | ||
| 1996/0206 | bno = f->dbno; | |
| 1996/0217 | for(sofar = 0; sofar + Blen < offset; sofar += Blen){ md = readdata(fs, bno, buf, 0); | |
| 1996/0206 |
| |
| 1996/0217/sys/src/9/port/devtinyfs.c:653,660 – 1996/0218/sys/src/9/port/devtinyfs.c:688,693 | ||
| 1996/0217 | offset = offset%Blen; for(sofar = 0; sofar < n; sofar += i){ md = readdata(fs, bno, buf, &i); | |
| 1996/0217/sys/src/9/port/devtinyfs.c:680,686 – 1996/0218/sys/src/9/port/devtinyfs.c:713,719 | ||
| 1996/0116 | { | |
| 1996/0217 | Tfs *fs; Tfile *f; | |
| 1996/0218 | int sofar, i, x; | |
| 1996/0217 | ulong bno, tbno; Mdata *md; uchar buf[Blen]; | |
| 1996/0217/sys/src/9/port/devtinyfs.c:689,719 – 1996/0218/sys/src/9/port/devtinyfs.c:722,787 | ||
| 1996/0217 | if(c->qid.path & CHDIR) error(Eperm); | |
| 1996/0218 | if(n == 0) return 0; | |
| 1996/0217 | fs = tinyfs.fs[c->dev]; f = &fs->f[c->qid.path]; | |
| 1996/0218 | /* 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 */ | |
| 1996/0217 | bno = f->dbno; for(sofar = 0; sofar + Blen < offset; sofar += Blen){ md = readdata(fs, bno, buf, 0); | |
| 1996/0218 | if(md->type == Tagend) break; | |
| 1996/0217 | bno = GETS(md->bno); | |
| 1996/0116 | } | |
| 1996/0217 |
| |
| 1996/0218 | 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; | |
| 1996/0116 | } | |
| 1996/0218 | 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); | |
| 1996/0217 | return sofar; | |
| 1996/0116 | } | |
| 1996/0218/sys/src/9/port/devtinyfs.c:49,55 – 1996/0220/sys/src/9/port/devtinyfs.c:49,55 (short | long) | ||
| 1996/0201 | struct Mdata { uchar type; uchar bno[2]; | |
| 1996/0220 | uchar data[Dlen]; | |
| 1996/0201 | uchar sum; }; | |
| 1996/0218/sys/src/9/port/devtinyfs.c:63,68 – 1996/0220/sys/src/9/port/devtinyfs.c:63,72 | ||
| 1996/0201 | ushort pin; | |
| 1996/0203 | uchar flag; | |
| 1996/0201 | ulong length; | |
| 1996/0220 | /* hint to avoid egregious reading */ ushort fbno; ulong finger; | |
| 1996/0201 | }; typedef struct Tfs Tfs; | |
| 1996/0218/sys/src/9/port/devtinyfs.c:80,86 – 1996/0220/sys/src/9/port/devtinyfs.c:84,89 | ||
| 1996/0122 | struct { QLock; | |
| 1996/0201 | Tfs fs[Maxfs]; | |
| 1996/0116 | } tinyfs; | |
| 1996/0131 | #define GETS(x) ((x)[0]|((x)[1]<<8)) | |
| 1996/0218/sys/src/9/port/devtinyfs.c:125,131 – 1996/0220/sys/src/9/port/devtinyfs.c:128,133 | ||
| 1996/0131 | int i, j, lim; uchar x; | |
| 1996/0218/sys/src/9/port/devtinyfs.c:134,145 – 1996/0220/sys/src/9/port/devtinyfs.c:136,146 | ||
| 1996/0131 | for(j = 0; j < 8; j++) if((x & (1<<j)) == 0){ fs->map[i] = x|(1<<j); | |
| 1996/0220 | return Notabno; | |
| 1996/0131 | } | |
| 1996/0201 | static Mdir* | |
| 1996/0218/sys/src/9/port/devtinyfs.c:245,263 – 1996/0220/sys/src/9/port/devtinyfs.c:246,262 | ||
| 1996/0202 | } | |
| 1996/0201 | static void | |
| 1996/0220 | freeblocks(Tfs *fs, ulong bno, ulong bend) | |
| 1996/0201 | { uchar buf[Blen]; | |
| 1996/0220 | if(waserror()) return; | |
| 1996/0202 | while(bno != bend && bno != Notabno){ | |
| 1996/0201 | mapclr(fs, bno); | |
| 1996/0220 | if(devtab[fs->c->type].read(fs->c, buf, Blen, Blen*bno) != Blen) | |
| 1996/0201 | break; | |
| 1996/0217 | md = validdata(fs, buf, 0); | |
| 1996/0201 | if(md == 0) | |
| 1996/0218/sys/src/9/port/devtinyfs.c:267,279 – 1996/0220/sys/src/9/port/devtinyfs.c:266,289 | ||
| 1996/0201 | bno = GETS(md->bno); } | |
| 1996/0220 | poperror(); } static void freefile(Tfs *fs, Tfile *f, ulong bend) { uchar buf[Blen]; /* remove blocks from map */ freeblocks(fs, f->dbno, bend); | |
| 1996/0201 | /* change file type to free on medium */ | |
| 1996/0202 | if(f->bno != Notabno){ | |
| 1996/0220 | if(devtab[fs->c->type].read(fs->c, buf, Blen, Blen*f->bno) != Blen) | |
| 1996/0202 | return; buf[0] = Tagfree; devtab[fs->c->type].write(fs->c, buf, Blen, Blen*f->bno); | |
| 1996/0220 | mapclr(fs, f->bno); | |
| 1996/0202 | } | |
| 1996/0201 | /* forget we ever knew about it */ | |
| 1996/0218/sys/src/9/port/devtinyfs.c:288,295 – 1996/0220/sys/src/9/port/devtinyfs.c:298,307 | ||
| 1996/0201 | fs->fsize += 8; f = smalloc(fs->fsize*sizeof(*f)); | |
| 1996/0217 |
| |
| 1996/0201 |
| |
| 1996/0220 | if(fs->f){ memmove(f, fs->f, fs->nf*sizeof(*f)); free(fs->f); } | |
| 1996/0201 | fs->f = f; } | |
| 1996/0218/sys/src/9/port/devtinyfs.c:310,317 – 1996/0220/sys/src/9/port/devtinyfs.c:322,332 | ||
| 1996/0202 | } } | |
| 1996/0220 | if(i < fs->fsize){ if(i >= fs->nf) fs->nf = i+1; | |
| 1996/0202 | break; | |
| 1996/0220 | } | |
| 1996/0202 | expand(fs); } | |
| 1996/0218/sys/src/9/port/devtinyfs.c:319,324 – 1996/0220/sys/src/9/port/devtinyfs.c:334,341 | ||
| 1996/0203 | f->flag = Fcreating; | |
| 1996/0202 | f->dbno = Notabno; f->bno = mapalloc(fs); | |
| 1996/0220 | f->fbno = Notabno; f->r = 1; | |
| 1996/0202 | /* write directory block */ if(waserror()){ | |
| 1996/0218/sys/src/9/port/devtinyfs.c:437,442 – 1996/0220/sys/src/9/port/devtinyfs.c:454,461 | ||
| 1996/0201 | if(i >= fs->nf) return -1; f = &fs->f[i]; | |
| 1996/0220 | if(f->name[0] == 0) return 0; | |
| 1996/0201 | qid.path = i; qid.vers = 0; | |
| 1996/0202 | devdir(c, qid, f->name, f->length, eve, 0664, dp); | |
| 1996/0218/sys/src/9/port/devtinyfs.c:461,497 – 1996/0220/sys/src/9/port/devtinyfs.c:480,528 | ||
| 1996/0201 | Tfs *fs; | |
| 1996/0122 | Chan *c, *cc; | |
| 1996/0201 | int i; | |
| 1996/0220 | char *p; | |
| 1996/0120 | ||
| 1996/0218 |
| |
| 1996/0220 | p = 0; if(strcmp(spec, "hd0") == 0) p = "#H/hd0nvram"; else error("bad spec"); cc = namec(p, Aopen, ORDWR, 0); | |
| 1996/0123 | if(waserror()){ close(cc); | |
| 1996/0201 |
| |
| 1996/0123 | nexterror(); } | |
| 1996/0201 | ||
| 1996/0122 |
| |
| 1996/0218 | fs = 0; | |
| 1996/0201 |
| |
| 1996/0220 | for(i = 0; i < Maxfs; i++){ | |
| 1996/0201 | fs = &tinyfs.fs[i]; | |
| 1996/0218 |
| |
| 1996/0220 | qlock(fs); if(fs->r && eqchan(cc, fs->c, 0)) | |
| 1996/0122 | break; | |
| 1996/0220 | qunlock(fs); | |
| 1996/0122 | } | |
| 1996/0201 |
| |
| 1996/0202 |
| |
| 1996/0220 | if(i < Maxfs){ | |
| 1996/0201 | fs->r++; | |
| 1996/0202 | qunlock(fs); | |
| 1996/0122 | close(cc); } else { | |
| 1996/0201 |
| |
| 1996/0220 | for(fs = tinyfs.fs; fs < &tinyfs.fs[Maxfs]; fs++){ qlock(fs); if(fs->r == 0) break; qunlock(fs); } if(fs == &tinyfs.fs[Maxfs]) | |
| 1996/0201 | error("too many tinyfs's"); | |
| 1996/0122 | fs->c = cc; | |
| 1996/0201 | fs->r = 1; | |
| 1996/0220 | fs->f = 0; fs->nf = 0; fs->fsize = 0; | |
| 1996/0201 | fsinit(fs); | |
| 1996/0220 | qunlock(fs); | |
| 1996/0122 | } | |
| 1996/0201 |
| |
| 1996/0123 | poperror(); | |
| 1996/0122 | ||
| 1996/0201 | c = devattach('U', spec); | |
| 1996/0218/sys/src/9/port/devtinyfs.c:553,566 – 1996/0220/sys/src/9/port/devtinyfs.c:584,607 | ||
| 1996/0201 | error(Eperm); } else { | |
| 1996/0202 | qlock(fs); | |
| 1996/0220 | if(waserror()){ qunlock(fs); nexterror(); } switch(omode){ case OTRUNC|ORDWR: case OTRUNC|OWRITE: | |
| 1996/0218 | f = newfile(fs, fs->f[c->qid.path].name); | |
| 1996/0220 | fs->f[c->qid.path].r--; | |
| 1996/0202 | c->qid.path = f - fs->f; | |
| 1996/0220 | break; case OREAD: break; default: | |
| 1996/0202 | error(Eperm); | |
| 1996/0201 | } | |
| 1996/0202 | qunlock(fs); | |
| 1996/0220 | poperror(); | |
| 1996/0201 | } return devopen(c, omode, 0, 0, tinyfsgen); | |
| 1996/0218/sys/src/9/port/devtinyfs.c:572,585 – 1996/0220/sys/src/9/port/devtinyfs.c:613,630 | ||
| 1996/0201 | Tfs *fs; Tfile *f; | |
| 1996/0116 |
| |
| 1996/0220 | USED(perm); | |
| 1996/0116 | ||
| 1996/0218 | fs = &tinyfs.fs[c->dev]; | |
| 1996/0202 | qlock(fs); | |
| 1996/0220 | if(waserror()){ qunlock(fs); nexterror(); } | |
| 1996/0202 | f = newfile(fs, name); qunlock(fs); | |
| 1996/0220 | poperror(); | |
| 1996/0201 | c->qid.path = f - fs->f; | |
| 1996/0202 | c->qid.vers = 0; | |
| 1996/0218/sys/src/9/port/devtinyfs.c:589,596 – 1996/0220/sys/src/9/port/devtinyfs.c:634,649 | ||
| 1996/0116 | void tinyfsremove(Chan *c) { | |
| 1996/0220 | 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); | |
| 1996/0116 | } void | |
| 1996/0218/sys/src/9/port/devtinyfs.c:603,609 – 1996/0220/sys/src/9/port/devtinyfs.c:656,662 | ||
| 1996/0116 | void tinyfsclose(Chan *c) { | |
| 1996/0201 |
| |
| 1996/0220 | Tfs *fs; | |
| 1996/0201 | Tfile *f, *nf; | |
| 1996/0202 | int i; | |
| 1996/0201 | ||
| 1996/0218/sys/src/9/port/devtinyfs.c:612,659 – 1996/0220/sys/src/9/port/devtinyfs.c:665,712 | ||
| 1996/0202 | qlock(fs); | |
| 1996/0201 | ||
| 1996/0202 | /* dereference file and remove old versions */ | |
| 1996/0203 |
| |
| 1996/0217 |
| |
| 1996/0203 |
| |
| 1996/0220 | 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); } | |
| 1996/0203 | } | |
| 1996/0220 | f->flag &= ~Fcreating; | |
| 1996/0203 | } | |
| 1996/0202 | } | |
| 1996/0218 |
| |
| 1996/0203 |
| |
| 1996/0202 | } | |
| 1996/0220 | poperror(); | |
| 1996/0202 | } /* dereference fs and remove on zero refs */ fs->r--; | |
| 1996/0218 |
| |
| 1996/0203 |
| |
| 1996/0218 | if(fs->r == 0){ | |
| 1996/0201 |
| |
| 1996/0217 |
| |
| 1996/0201 |
| |
| 1996/0220 | if(fs->f) free(fs->f); fs->f = 0; fs->nf = 0; fs->fsize = 0; if(fs->map) free(fs->map); fs->map = 0; | |
| 1996/0201 | close(fs->c); | |
| 1996/0203 |
| |
| 1996/0220 | fs->c = 0; | |
| 1996/0201 | } | |
| 1996/0220 | qunlock(fs); | |
| 1996/0116 | } long | |
| 1996/0218/sys/src/9/port/devtinyfs.c:661,667 – 1996/0220/sys/src/9/port/devtinyfs.c:714,720 | ||
| 1996/0116 | { | |
| 1996/0203 | Tfs *fs; Tfile *f; | |
| 1996/0220 | int sofar, i, off; | |
| 1996/0218 | ulong bno; | |
| 1996/0206 | Mdata *md; uchar buf[Blen]; | |
| 1996/0218/sys/src/9/port/devtinyfs.c:670,703 – 1996/0220/sys/src/9/port/devtinyfs.c:723,778 | ||
| 1996/0203 | if(c->qid.path & CHDIR) | |
| 1996/0217 | return devdirread(c, a, n, 0, 0, tinyfsgen); | |
| 1996/0203 |
| |
| 1996/0220 | fs = &tinyfs.fs[c->dev]; | |
| 1996/0203 | f = &fs->f[c->qid.path]; if(offset >= f->length) return 0; | |
| 1996/0220 | qlock(fs); if(waserror()){ qunlock(fs); nexterror(); } | |
| 1996/0203 | if(n + offset >= f->length) n = f->length - offset; | |
| 1996/0206 | ||
| 1996/0217 | /* walk to starting data block */ | |
| 1996/0206 |
| |
| 1996/0217 |
| |
| 1996/0220 | 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){ | |
| 1996/0217 | md = readdata(fs, bno, buf, 0); | |
| 1996/0220 | if(md == 0) error(Eio); | |
| 1996/0206 | bno = GETS(md->bno); } /* read data */ | |
| 1996/0217 |
| |
| 1996/0220 | off = offset%Dlen; offset -= off; | |
| 1996/0217 | for(sofar = 0; sofar < n; sofar += i){ md = readdata(fs, bno, buf, &i); | |
| 1996/0220 | if(md == 0) error(Eio); /* update finger for successful read */ f->finger = offset + sofar; f->fbno = bno; i -= off; | |
| 1996/0217 | if(i > n) i = n; | |
| 1996/0220 | off = 0; | |
| 1996/0217 | } | |
| 1996/0220 | qunlock(fs); poperror(); | |
| 1996/0203 | ||
| 1996/0217 | return sofar; | |
| 1996/0116 | } | |
| 1996/0218/sys/src/9/port/devtinyfs.c:708,720 – 1996/0220/sys/src/9/port/devtinyfs.c:783,799 | ||
| 1996/0116 | return devbread(c, n, offset); } | |
| 1996/0220 | /* * if we get a write error in this routine, blocks will * be lost. They should be recovered next fsinit. */ | |
| 1996/0116 | long | |
| 1996/0220 | tinyfswrite(Chan *c, void *a, long n, ulong offset) | |
| 1996/0116 | { | |
| 1996/0217 | Tfs *fs; Tfile *f; | |
| 1996/0218 |
| |
| 1996/0217 |
| |
| 1996/0220 | int last, next, i, off, finger; ulong bno, dbno, fbno; | |
| 1996/0217 | Mdata *md; uchar buf[Blen]; uchar *p = a; | |
| 1996/0218/sys/src/9/port/devtinyfs.c:725,731 – 1996/0220/sys/src/9/port/devtinyfs.c:804,810 | ||
| 1996/0218 | if(n == 0) return 0; | |
| 1996/0217 |
| |
| 1996/0220 | fs = &tinyfs.fs[c->dev]; | |
| 1996/0217 | f = &fs->f[c->qid.path]; | |
| 1996/0218 | /* files are append only, anything else is illegal */ | |
| 1996/0218/sys/src/9/port/devtinyfs.c:733,789 – 1996/0220/sys/src/9/port/devtinyfs.c:812,889 | ||
| 1996/0218 | error("append only"); qlock(fs); | |
| 1996/0220 | dbno = Notabno; | |
| 1996/0218 | if(waserror()){ | |
| 1996/0220 | freeblocks(fs, dbno, Notabno); | |
| 1996/0218 | qunlock(fs); nexterror(); } | |
| 1996/0220 | /* 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; } | |
| 1996/0218 | /* walk to last data block */ | |
| 1996/0217 |
| |
| 1996/0220 | 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){ | |
| 1996/0217 | md = readdata(fs, bno, buf, 0); | |
| 1996/0220 | if(md == 0) error(Eio); | |
| 1996/0218 | if(md->type == Tagend) break; | |
| 1996/0217 | bno = GETS(md->bno); | |
| 1996/0116 | } | |
| 1996/0218 |
| |
| 1996/0116 |
| |
| 1996/0218 |
| |
| 1996/0220 | /* 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); | |
| 1996/0218 | } | |
| 1996/0220 | writedata(fs, bno, dbno, md->data, i+next, last == n+offset); | |
| 1996/0218 | } | |
| 1996/0220 | f->length += n; | |
| 1996/0218 |
| |
| 1996/0220 | /* update finger */ if(fbno != Notabno){ f->finger = finger; f->fbno = fbno; } | |
| 1996/0218 | poperror(); qunlock(fs); | |
| 1996/0217 |
| |
| 1996/0220 | return n; | |
| 1996/0116 | } long | |
| 1996/0220/sys/src/9/port/devtinyfs.c:483,490 – 1996/0221/sys/src/9/port/devtinyfs.c:483,496 (short | long) | ||
| 1996/0220 | char *p; | |
| 1996/0120 | ||
| 1996/0220 | p = 0; | |
| 1996/0221 | if(strncmp(spec, "hd0") == 0) | |
| 1996/0220 | p = "#H/hd0nvram"; | |
| 1996/0221 | 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"; | |
| 1996/0220 | else error("bad spec"); | |
| 1996/0221/sys/src/9/port/devtinyfs.c:9,15 – 1996/0223/sys/src/9/port/devtinyfs.c:9,14 (short | long) | ||
| 1996/0116 | #include "fns.h" #include "../port/error.h" | |
| 1996/0223/sys/src/9/port/devtinyfs.c:54,60 – 1996/0226/sys/src/9/port/devtinyfs.c:54,59 (short | long) | ||
| 1996/0201 | typedef struct Tfile Tfile; struct Tfile { | |
| 1996/0206 |
| |
| 1996/0202 | int r; | |
| 1996/0201 | char name[NAMELEN]; ushort bno; | |
| 1996/0223/sys/src/9/port/devtinyfs.c:70,76 – 1996/0226/sys/src/9/port/devtinyfs.c:69,75 | ||
| 1996/0201 | typedef struct Tfs Tfs; struct Tfs { | |
| 1996/0202 |
| |
| 1996/0226 | QLock ql; | |
| 1996/0201 | int r; | |
| 1996/0116 | Chan *c; | |
| 1996/0131 | uchar *map; | |
| 1996/0223/sys/src/9/port/devtinyfs.c:81,87 – 1996/0226/sys/src/9/port/devtinyfs.c:80,85 | ||
| 1996/0122 | }; struct { | |
| 1996/0201 | Tfs fs[Maxfs]; | |
| 1996/0116 | } tinyfs; | |
| 1996/0223/sys/src/9/port/devtinyfs.c:482,495 – 1996/0226/sys/src/9/port/devtinyfs.c:480,493 | ||
| 1996/0220 | char *p; | |
| 1996/0120 | ||
| 1996/0220 | p = 0; | |
| 1996/0221 |
| |
| 1996/0220 |
| |
| 1996/0221 |
| |
| 1996/0226 | 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"; | |
| 1996/0220 | else error("bad spec"); | |
| 1996/0223/sys/src/9/port/devtinyfs.c:502,522 – 1996/0226/sys/src/9/port/devtinyfs.c:500,520 | ||
| 1996/0218 | fs = 0; | |
| 1996/0220 | for(i = 0; i < Maxfs; i++){ | |
| 1996/0201 | fs = &tinyfs.fs[i]; | |
| 1996/0220 |
| |
| 1996/0226 | qlock(&fs->ql); | |
| 1996/0220 | if(fs->r && eqchan(cc, fs->c, 0)) | |
| 1996/0122 | break; | |
| 1996/0220 |
| |
| 1996/0226 | qunlock(&fs->ql); | |
| 1996/0122 | } | |
| 1996/0220 | if(i < Maxfs){ | |
| 1996/0201 | fs->r++; | |
| 1996/0202 |
| |
| 1996/0226 | qunlock(&fs->ql); | |
| 1996/0122 | close(cc); } else { | |
| 1996/0220 | for(fs = tinyfs.fs; fs < &tinyfs.fs[Maxfs]; fs++){ | |
| 1996/0226 | qlock(&fs->ql); | |
| 1996/0220 | if(fs->r == 0) break; | |
| 1996/0226 | qunlock(&fs->ql); | |
| 1996/0220 | } if(fs == &tinyfs.fs[Maxfs]) | |
| 1996/0201 | error("too many tinyfs's"); | |
| 1996/0223/sys/src/9/port/devtinyfs.c:526,532 – 1996/0226/sys/src/9/port/devtinyfs.c:524,530 | ||
| 1996/0220 | fs->nf = 0; fs->fsize = 0; | |
| 1996/0201 | fsinit(fs); | |
| 1996/0220 |
| |
| 1996/0226 | qunlock(&fs->ql); | |
| 1996/0122 | } | |
| 1996/0123 | poperror(); | |
| 1996/0122 | ||
| 1996/0223/sys/src/9/port/devtinyfs.c:545,553 – 1996/0226/sys/src/9/port/devtinyfs.c:543,551 | ||
| 1996/0218 | fs = &tinyfs.fs[c->dev]; | |
| 1996/0202 |
| |
| 1996/0226 | qlock(&fs->ql); | |
| 1996/0202 | fs->r++; | |
| 1996/0226 | qunlock(&fs->ql); | |
| 1996/0202 | ||
| 1996/0116 | return devclone(c, nc); } | |
| 1996/0223/sys/src/9/port/devtinyfs.c:560,572 – 1996/0226/sys/src/9/port/devtinyfs.c:558,570 | ||
| 1996/0202 | ||
| 1996/0218 | fs = &tinyfs.fs[c->dev]; | |
| 1996/0202 |
| |
| 1996/0226 | qlock(&fs->ql); | |
| 1996/0202 | 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++; } | |
| 1996/0226 | qunlock(&fs->ql); | |
| 1996/0202 | return n; | |
| 1996/0116 | } | |
| 1996/0223/sys/src/9/port/devtinyfs.c:588,596 – 1996/0226/sys/src/9/port/devtinyfs.c:586,594 | ||
| 1996/0201 | if(omode != OREAD) error(Eperm); } else { | |
| 1996/0202 |
| |
| 1996/0226 | qlock(&fs->ql); | |
| 1996/0220 | if(waserror()){ | |
| 1996/0226 | qunlock(&fs->ql); | |
| 1996/0220 | nexterror(); } switch(omode){ | |
| 1996/0223/sys/src/9/port/devtinyfs.c:605,611 – 1996/0226/sys/src/9/port/devtinyfs.c:603,609 | ||
| 1996/0220 | default: | |
| 1996/0202 | error(Eperm); | |
| 1996/0201 | } | |
| 1996/0202 |
| |
| 1996/0226 | qunlock(&fs->ql); | |
| 1996/0220 | poperror(); | |
| 1996/0201 | } | |
| 1996/0223/sys/src/9/port/devtinyfs.c:622,634 – 1996/0226/sys/src/9/port/devtinyfs.c:620,632 | ||
| 1996/0116 | ||
| 1996/0218 | fs = &tinyfs.fs[c->dev]; | |
| 1996/0202 |
| |
| 1996/0226 | qlock(&fs->ql); | |
| 1996/0220 | if(waserror()){ | |
| 1996/0226 | qunlock(&fs->ql); | |
| 1996/0220 | nexterror(); } | |
| 1996/0202 | f = newfile(fs, name); | |
| 1996/0226 | qunlock(&fs->ql); | |
| 1996/0220 | poperror(); | |
| 1996/0201 | c->qid.path = f - fs->f; | |
| 1996/0223/sys/src/9/port/devtinyfs.c:646,654 – 1996/0226/sys/src/9/port/devtinyfs.c:644,652 | ||
| 1996/0220 | error(Eperm); fs = &tinyfs.fs[c->dev]; f = &fs->f[c->qid.path]; | |
| 1996/0226 | qlock(&fs->ql); | |
| 1996/0220 | freefile(fs, f, Notabno); | |
| 1996/0226 | qunlock(&fs->ql); | |
| 1996/0116 | } void | |
| 1996/0223/sys/src/9/port/devtinyfs.c:667,673 – 1996/0226/sys/src/9/port/devtinyfs.c:665,671 | ||
| 1996/0201 | ||
| 1996/0218 | fs = &tinyfs.fs[c->dev]; | |
| 1996/0201 | ||
| 1996/0202 |
| |
| 1996/0226 | qlock(&fs->ql); | |
| 1996/0201 | ||
| 1996/0202 | /* dereference file and remove old versions */ | |
| 1996/0220 | if(!waserror()){ | |
| 1996/0223/sys/src/9/port/devtinyfs.c:711,717 – 1996/0226/sys/src/9/port/devtinyfs.c:709,715 | ||
| 1996/0201 | close(fs->c); | |
| 1996/0220 | fs->c = 0; | |
| 1996/0201 | } | |
| 1996/0220 |
| |
| 1996/0226 | qunlock(&fs->ql); | |
| 1996/0116 | } long | |
| 1996/0223/sys/src/9/port/devtinyfs.c:733,741 – 1996/0226/sys/src/9/port/devtinyfs.c:731,739 | ||
| 1996/0203 | if(offset >= f->length) return 0; | |
| 1996/0220 |
| |
| 1996/0226 | qlock(&fs->ql); | |
| 1996/0220 | if(waserror()){ | |
| 1996/0226 | qunlock(&fs->ql); | |
| 1996/0220 | nexterror(); } | |
| 1996/0203 | if(n + offset >= f->length) | |
| 1996/0223/sys/src/9/port/devtinyfs.c:776,782 – 1996/0226/sys/src/9/port/devtinyfs.c:774,780 | ||
| 1996/0217 | bno = GETS(md->bno); | |
| 1996/0220 | off = 0; | |
| 1996/0217 | } | |
| 1996/0220 |
| |
| 1996/0226 | qunlock(&fs->ql); | |
| 1996/0220 | poperror(); | |
| 1996/0203 | ||
| 1996/0217 | return sofar; | |
| 1996/0223/sys/src/9/port/devtinyfs.c:816,826 – 1996/0226/sys/src/9/port/devtinyfs.c:814,824 | ||
| 1996/0218 | if(offset != f->length) error("append only"); | |
| 1996/0226 | qlock(&fs->ql); | |
| 1996/0220 | dbno = Notabno; | |
| 1996/0218 | if(waserror()){ | |
| 1996/0220 | freeblocks(fs, dbno, Notabno); | |
| 1996/0218 |
| |
| 1996/0226 | qunlock(&fs->ql); | |
| 1996/0218 | nexterror(); } | |
| 1996/0223/sys/src/9/port/devtinyfs.c:886,892 – 1996/0226/sys/src/9/port/devtinyfs.c:884,890 | ||
| 1996/0220 | f->fbno = fbno; } | |
| 1996/0218 | poperror(); | |
| 1996/0226 | qunlock(&fs->ql); | |
| 1996/0217 | ||
| 1996/0220 | return n; | |
| 1996/0116 | } | |
| 1996/0226/sys/src/9/port/devtinyfs.c:190,196 – 1997/0327/sys/src/9/port/devtinyfs.c:190,196 (short | long) | ||
| 1996/0206 | { if(bno >= fs->nblocks) return 0; | |
| 1996/0218 |
| |
| 1997/0327 | if(devtab[fs->c->type]->read(fs->c, buf, Blen, Blen*bno) != Blen) | |
| 1996/0218 | error(Eio); | |
| 1996/0217 | return validdata(fs, buf, lenp); | |
| 1996/0206 | } | |
| 1996/0226/sys/src/9/port/devtinyfs.c:217,223 – 1997/0327/sys/src/9/port/devtinyfs.c:217,223 | ||
| 1996/0218 | memmove(md.data, buf, len); md.sum = 0 - checksum((uchar*)&md); | |
| 1997/0327 | if(devtab[fs->c->type]->write(fs->c, &md, Blen, Blen*bno) != Blen) | |
| 1996/0218 | error(Eio); } | |
| 1996/0226/sys/src/9/port/devtinyfs.c:238,244 – 1997/0327/sys/src/9/port/devtinyfs.c:238,244 | ||
| 1996/0202 | PUTS(md->pin, f->pin); | |
| 1996/0218 | md->sum = 0 - checksum(buf); | |
| 1996/0202 | ||
| 1996/0218 |
| |
| 1997/0327 | if(devtab[fs->c->type]->write(fs->c, buf, Blen, Blen*f->bno) != Blen) | |
| 1996/0218 | error(Eio); | |
| 1996/0202 | } | |
| 1996/0226/sys/src/9/port/devtinyfs.c:253,259 – 1997/0327/sys/src/9/port/devtinyfs.c:253,259 | ||
| 1996/0220 | ||
| 1996/0202 | while(bno != bend && bno != Notabno){ | |
| 1996/0201 | mapclr(fs, bno); | |
| 1996/0220 |
| |
| 1997/0327 | if(devtab[fs->c->type]->read(fs->c, buf, Blen, Blen*bno) != Blen) | |
| 1996/0201 | break; | |
| 1996/0217 | md = validdata(fs, buf, 0); | |
| 1996/0201 | if(md == 0) | |
| 1996/0226/sys/src/9/port/devtinyfs.c:276,285 – 1997/0327/sys/src/9/port/devtinyfs.c:276,285 | ||
| 1996/0220 | ||
| 1996/0201 | /* change file type to free on medium */ | |
| 1996/0202 | if(f->bno != Notabno){ | |
| 1996/0220 |
| |
| 1997/0327 | if(devtab[fs->c->type]->read(fs->c, buf, Blen, Blen*f->bno) != Blen) | |
| 1996/0202 | return; buf[0] = Tagfree; | |
| 1997/0327 | devtab[fs->c->type]->write(fs->c, buf, Blen, Blen*f->bno); | |
| 1996/0220 | mapclr(fs, f->bno); | |
| 1996/0202 | } | |
| 1996/0201 | ||
| 1996/0226/sys/src/9/port/devtinyfs.c:364,370 – 1997/0327/sys/src/9/port/devtinyfs.c:364,370 | ||
| 1996/0201 | Mdir *mdir; | |
| 1996/0218 | Mdata *mdata; | |
| 1996/0123 | ||
| 1996/0218 |
| |
| 1997/0327 | devtab[fs->c->type]->stat(fs->c, dbuf); | |
| 1996/0218 | convM2D(dbuf, &d); | |
| 1996/0131 | fs->nblocks = d.length/Blen; if(fs->nblocks < 3) | |
| 1996/0226/sys/src/9/port/devtinyfs.c:379,385 – 1997/0327/sys/src/9/port/devtinyfs.c:379,385 | ||
| 1996/0123 | ||
| 1996/0201 | /* find files */ | |
| 1996/0131 | for(bno = 0; bno < fs->nblocks; bno++){ | |
| 1997/0327 | n = devtab[fs->c->type]->read(fs->c, buf, Blen, Blen*bno); | |
| 1996/0131 | if(n != Blen) break; | |
| 1996/0201 | ||
| 1996/0226/sys/src/9/port/devtinyfs.c:408,414 – 1997/0327/sys/src/9/port/devtinyfs.c:408,414 | ||
| 1996/0218 | freefile(fs, f, bno); | |
| 1996/0201 | break; } | |
| 1997/0327 | n = devtab[fs->c->type]->read(fs->c, buf, Blen, Blen*bno); | |
| 1996/0201 | if(n != Blen){ freefile(fs, f, bno); break; | |
| 1996/0226/sys/src/9/port/devtinyfs.c:459,465 – 1997/0327/sys/src/9/port/devtinyfs.c:459,465 | ||
| 1996/0201 | return 1; | |
| 1996/0123 | } | |
| 1996/0201 |
| |
| 1997/0327 | static void | |
| 1996/0201 | tinyfsreset(void) { if(Nlen > NAMELEN) | |
| 1996/0226/sys/src/9/port/devtinyfs.c:466,477 – 1997/0327/sys/src/9/port/devtinyfs.c:466,472 | ||
| 1996/0201 | panic("tinyfsreset"); } | |
| 1996/0116 |
| |
| 1997/0327 | static Chan* | |
| 1996/0116 | tinyfsattach(char *spec) { | |
| 1996/0201 | Tfs *fs; | |
| 1996/0226/sys/src/9/port/devtinyfs.c:493,499 – 1997/0327/sys/src/9/port/devtinyfs.c:488,494 | ||
| 1996/0220 | cc = namec(p, Aopen, ORDWR, 0); | |
| 1996/0123 | if(waserror()){ | |
| 1997/0327 | cclose(cc); | |
| 1996/0123 | nexterror(); } | |
| 1996/0201 | ||
| 1996/0226/sys/src/9/port/devtinyfs.c:508,514 – 1997/0327/sys/src/9/port/devtinyfs.c:503,509 | ||
| 1996/0220 | if(i < Maxfs){ | |
| 1996/0201 | fs->r++; | |
| 1996/0226 | qunlock(&fs->ql); | |
| 1996/0122 |
| |
| 1997/0327 | cclose(cc); | |
| 1996/0122 | } else { | |
| 1996/0220 | for(fs = tinyfs.fs; fs < &tinyfs.fs[Maxfs]; fs++){ | |
| 1996/0226 | qlock(&fs->ql); | |
| 1996/0226/sys/src/9/port/devtinyfs.c:536,542 – 1997/0327/sys/src/9/port/devtinyfs.c:531,537 | ||
| 1996/0122 | return c; | |
| 1996/0116 | } | |
| 1997/0327 | static Chan* | |
| 1996/0116 | tinyfsclone(Chan *c, Chan *nc) { | |
| 1996/0218 | Tfs *fs; | |
| 1996/0226/sys/src/9/port/devtinyfs.c:550,556 – 1997/0327/sys/src/9/port/devtinyfs.c:545,551 | ||
| 1996/0116 | return devclone(c, nc); } | |
| 1997/0327 | static int | |
| 1996/0116 | tinyfswalk(Chan *c, char *name) { | |
| 1996/0202 | int n; | |
| 1996/0226/sys/src/9/port/devtinyfs.c:568,580 – 1997/0327/sys/src/9/port/devtinyfs.c:563,575 | ||
| 1996/0202 | return n; | |
| 1996/0116 | } | |
| 1997/0327 | static void | |
| 1996/0116 | tinyfsstat(Chan *c, char *db) { | |
| 1996/0201 | devstat(c, db, 0, 0, tinyfsgen); | |
| 1996/0116 | } | |
| 1997/0327 | static Chan* | |
| 1996/0116 | tinyfsopen(Chan *c, int omode) { | |
| 1996/0201 | Tfs *fs; | |
| 1996/0226/sys/src/9/port/devtinyfs.c:610,616 – 1997/0327/sys/src/9/port/devtinyfs.c:605,611 | ||
| 1996/0201 | return devopen(c, omode, 0, 0, tinyfsgen); | |
| 1996/0116 | } | |
| 1997/0327 | static void | |
| 1996/0116 | tinyfscreate(Chan *c, char *name, int omode, ulong perm) { | |
| 1996/0201 | Tfs *fs; | |
| 1996/0226/sys/src/9/port/devtinyfs.c:634,640 – 1997/0327/sys/src/9/port/devtinyfs.c:629,635 | ||
| 1996/0116 | c->mode = openmode(omode); } | |
| 1997/0327 | static void | |
| 1996/0116 | tinyfsremove(Chan *c) { | |
| 1996/0220 | Tfs *fs; | |
| 1996/0226/sys/src/9/port/devtinyfs.c:649,662 – 1997/0327/sys/src/9/port/devtinyfs.c:644,650 | ||
| 1996/0226 | qunlock(&fs->ql); | |
| 1996/0116 | } | |
| 1997/0327 | static void | |
| 1996/0116 | tinyfsclose(Chan *c) { | |
| 1996/0220 | Tfs *fs; | |
| 1996/0226/sys/src/9/port/devtinyfs.c:706,718 – 1997/0327/sys/src/9/port/devtinyfs.c:694,706 | ||
| 1996/0220 | if(fs->map) free(fs->map); fs->map = 0; | |
| 1996/0201 |
| |
| 1997/0327 | cclose(fs->c); | |
| 1996/0220 | fs->c = 0; | |
| 1996/0201 | } | |
| 1996/0226 | qunlock(&fs->ql); | |
| 1996/0116 | } | |
| 1997/0327 | static long | |
| 1996/0116 | tinyfsread(Chan *c, void *a, long n, ulong offset) { | |
| 1996/0203 | Tfs *fs; | |
| 1996/0226/sys/src/9/port/devtinyfs.c:780,796 – 1997/0327/sys/src/9/port/devtinyfs.c:768,778 | ||
| 1996/0217 | return sofar; | |
| 1996/0116 | } | |
| 1996/0220 | /* * if we get a write error in this routine, blocks will * be lost. They should be recovered next fsinit. */ | |
| 1996/0116 |
| |
| 1997/0327 | static long | |
| 1996/0220 | tinyfswrite(Chan *c, void *a, long n, ulong offset) | |
| 1996/0116 | { | |
| 1996/0217 | Tfs *fs; | |
| 1996/0226/sys/src/9/port/devtinyfs.c:889,896 – 1997/0327/sys/src/9/port/devtinyfs.c:871,890 | ||
| 1996/0220 | return n; | |
| 1996/0116 | } | |
| 1997/0327 | Dev tinyfsdevtab = { tinyfsreset, devinit, tinyfsattach, tinyfsclone, tinyfswalk, tinyfsstat, tinyfsopen, tinyfscreate, tinyfsclose, tinyfsread, devbread, tinyfswrite, devbwrite, tinyfsremove, devwstat, }; | |
| 1997/0327/sys/src/9/port/devtinyfs.c:872,877 – 1997/0408/sys/src/9/port/devtinyfs.c:872,880 (short | long) | ||
| 1996/0116 | } | |
| 1997/0327 | Dev tinyfsdevtab = { | |
| 1997/0408 | 'U', "tinyfs", | |
| 1997/0327 | tinyfsreset, devinit, tinyfsattach, | |
| 1997/0408/sys/src/9/port/devtinyfs.c:1,15 – 1999/0612/sys/src/9/port/devtinyfs.c:1,13 (short | long) | ||
| 1996/0116 | /* | |
| 1996/0202 | * a pity the code isn't also tiny... | |
| 1996/0116 | */ | |
| 1999/0612 | #include "u.h" #include "../port/lib.h" #include "../port/error.h" #include "mem.h" #include "dat.h" #include "fns.h" | |
| 1996/0116 |
| |
| 1996/0120 | Qmedium, | |
| 1997/0408/sys/src/9/port/devtinyfs.c:29,35 – 1999/0612/sys/src/9/port/devtinyfs.c:27,33 | ||
| 1996/0202 | Notabno= 0xffff, | |
| 1996/0203 | Fcreating= 1, | |
| 1999/0612 | Frmonclose= 2 | |
| 1996/0116 | }; | |
| 1996/0202 | /* representation of a Tdir on medium */ | |
| 1997/0408/sys/src/9/port/devtinyfs.c:181,186 – 1999/0612/sys/src/9/port/devtinyfs.c:179,186 | ||
| 1996/0217 | if(lenp) *lenp = x; | |
| 1996/0201 | break; | |
| 1999/0612 | default: return 0; | |
| 1996/0201 | } return md; } | |
| 1997/0408/sys/src/9/port/devtinyfs.c:237,243 – 1999/0612/sys/src/9/port/devtinyfs.c:237,243 | ||
| 1996/0202 | PUTS(md->bno, f->dbno); PUTS(md->pin, f->pin); | |
| 1996/0218 | md->sum = 0 - checksum(buf); | |
| 1996/0202 | ||
| 1999/0612 | ||
| 1997/0327 | if(devtab[fs->c->type]->write(fs->c, buf, Blen, Blen*f->bno) != Blen) | |
| 1996/0218 | error(Eio); | |
| 1996/0202 | } | |
| 1997/0408/sys/src/9/port/devtinyfs.c:276,284 – 1999/0612/sys/src/9/port/devtinyfs.c:276,282 | ||
| 1996/0220 | ||
| 1996/0201 | /* change file type to free on medium */ | |
| 1996/0202 | if(f->bno != Notabno){ | |
| 1997/0327 |
| |
| 1996/0202 |
| |
| 1999/0612 | memset(buf, 0x55, Blen); | |
| 1997/0327 | devtab[fs->c->type]->write(fs->c, buf, Blen, Blen*f->bno); | |
| 1996/0220 | mapclr(fs, f->bno); | |
| 1996/0202 | } | |
| 1997/0408/sys/src/9/port/devtinyfs.c:293,299 – 1999/0612/sys/src/9/port/devtinyfs.c:291,297 | ||
| 1996/0201 | Tfile *f; fs->fsize += 8; | |
| 1999/0612 | f = malloc(fs->fsize*sizeof(*f)); | |
| 1996/0201 | ||
| 1996/0220 | if(fs->f){ memmove(f, fs->f, fs->nf*sizeof(*f)); | |
| 1997/0408/sys/src/9/port/devtinyfs.c:306,350 – 1999/0612/sys/src/9/port/devtinyfs.c:304,353 | ||
| 1996/0202 | newfile(Tfs *fs, char *name) { int i; | |
| 1999/0612 | volatile struct { Tfile *f; Tfs *fs; } rock; | |
| 1996/0202 | /* find free entry in file table */ | |
| 1996/0218 |
| |
| 1999/0612 | rock.f = 0; rock.fs = fs; | |
| 1996/0202 | for(;;) { | |
| 1999/0612 | 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); | |
| 1996/0202 | break; } } | |
| 1996/0220 |
| |
| 1999/0612 | if(i < rock.fs->fsize){ if(i >= rock.fs->nf) rock.fs->nf = i+1; | |
| 1996/0202 | break; | |
| 1996/0220 | } | |
| 1996/0202 |
| |
| 1999/0612 | expand(rock.fs); | |
| 1996/0202 | } | |
| 1996/0203 |
| |
| 1996/0202 |
| |
| 1996/0220 |
| |
| 1999/0612 | 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?? | |
| 1996/0202 | /* write directory block */ if(waserror()){ | |
| 1996/0218 |
| |
| 1999/0612 | freefile(rock.fs, rock.f, Notabno); | |
| 1996/0202 | nexterror(); } | |
| 1996/0218 |
| |
| 1999/0612 | if(rock.f->bno == Notabno) | |
| 1996/0202 | error("out of space"); | |
| 1999/0612 | writedir(rock.fs, rock.f); | |
| 1996/0202 | poperror(); | |
| 1999/0612 | return rock.f; | |
| 1996/0202 | } | |
| 1996/0123 | /* | |
| 1997/0408/sys/src/9/port/devtinyfs.c:353,359 – 1999/0612/sys/src/9/port/devtinyfs.c:356,362 | ||
| 1996/0217 | * had better be small or this could take a while. | |
| 1996/0123 | */ | |
| 1996/0201 | static void | |
| 1999/0612 | tfsinit(Tfs *fs) | |
| 1996/0123 | { | |
| 1996/0218 | char dbuf[DIRLEN]; | |
| 1996/0123 | Dir d; | |
| 1997/0408/sys/src/9/port/devtinyfs.c:372,378 – 1999/0612/sys/src/9/port/devtinyfs.c:375,381 | ||
| 1996/0123 | ||
| 1996/0131 | /* bitmap for block usage */ x = (fs->nblocks + 8 - 1)/8; | |
| 1996/0201 |
| |
| 1999/0612 | fs->map = malloc(x); | |
| 1996/0131 | memset(fs->map, 0x0, x); for(bno = fs->nblocks; bno < x*8; bno++) mapset(fs, bno); | |
| 1997/0408/sys/src/9/port/devtinyfs.c:398,403 – 1999/0612/sys/src/9/port/devtinyfs.c:401,407 | ||
| 1996/0201 | f->pin = GETS(mdir->pin); f->bno = bno; f->dbno = x; | |
| 1999/0612 | f->fbno = Notabno; | |
| 1996/0201 | } /* follow files */ | |
| 1997/0408/sys/src/9/port/devtinyfs.c:445,451 – 1999/0612/sys/src/9/port/devtinyfs.c:449,456 | ||
| 1996/0201 | Tfile *f; Qid qid; | |
| 1996/0123 | ||
| 1996/0218 |
| |
| 1999/0612 | USED(ntab); USED(tab); | |
| 1996/0218 | ||
| 1996/0201 | fs = &tinyfs.fs[c->dev]; if(i >= fs->nf) | |
| 1997/0408/sys/src/9/port/devtinyfs.c:460,494 – 1999/0612/sys/src/9/port/devtinyfs.c:465,494 | ||
| 1996/0123 | } | |
| 1997/0327 | static void | |
| 1996/0201 |
| |
| 1999/0612 | tinyfsinit(void) | |
| 1996/0201 | { if(Nlen > NAMELEN) | |
| 1999/0612 | panic("tinyfsinit"); | |
| 1996/0201 | } | |
| 1999/0612 | /* * specifier is an open file descriptor */ | |
| 1997/0327 | static Chan* | |
| 1996/0116 |
| |
| 1999/0612 | tinyfsattach(void *spec) | |
| 1996/0116 | { | |
| 1996/0201 | Tfs *fs; | |
| 1996/0122 |
| |
| 1996/0201 |
| |
| 1996/0220 |
| |
| 1999/0612 | Chan *c; volatile struct { Chan *cc; } rock; int i, fd; | |
| 1996/0120 | ||
| 1996/0220 |
| |
| 1996/0226 |
| |
| 1996/0220 |
| |
| 1999/0612 | fd = atoi(spec); if(fd < 0) error("bad specifier"); | |
| 1996/0220 |
| |
| 1999/0612 | rock.cc = fdtochan(fd, ORDWR, 0, 1); | |
| 1996/0123 | if(waserror()){ | |
| 1997/0327 |
| |
| 1999/0612 | cclose(rock.cc); | |
| 1996/0123 | nexterror(); } | |
| 1996/0201 | ||
| 1997/0408/sys/src/9/port/devtinyfs.c:496,502 – 1999/0612/sys/src/9/port/devtinyfs.c:496,502 | ||
| 1996/0220 | for(i = 0; i < Maxfs; i++){ | |
| 1996/0201 | fs = &tinyfs.fs[i]; | |
| 1996/0226 | qlock(&fs->ql); | |
| 1996/0220 |
| |
| 1999/0612 | if(fs->r && eqchan(rock.cc, fs->c, 1)) | |
| 1996/0122 | break; | |
| 1996/0226 | qunlock(&fs->ql); | |
| 1996/0122 | } | |
| 1997/0408/sys/src/9/port/devtinyfs.c:503,509 – 1999/0612/sys/src/9/port/devtinyfs.c:503,509 | ||
| 1996/0220 | if(i < Maxfs){ | |
| 1996/0201 | fs->r++; | |
| 1996/0226 | qunlock(&fs->ql); | |
| 1997/0327 |
| |
| 1999/0612 | cclose(rock.cc); | |
| 1996/0122 | } else { | |
| 1996/0220 | for(fs = tinyfs.fs; fs < &tinyfs.fs[Maxfs]; fs++){ | |
| 1996/0226 | qlock(&fs->ql); | |
| 1997/0408/sys/src/9/port/devtinyfs.c:513,529 – 1999/0612/sys/src/9/port/devtinyfs.c:513,529 | ||
| 1996/0220 | } if(fs == &tinyfs.fs[Maxfs]) | |
| 1996/0201 | error("too many tinyfs's"); | |
| 1996/0122 |
| |
| 1999/0612 | fs->c = rock.cc; | |
| 1996/0201 | fs->r = 1; | |
| 1996/0220 | fs->f = 0; fs->nf = 0; fs->fsize = 0; | |
| 1996/0201 |
| |
| 1999/0612 | tfsinit(fs); | |
| 1996/0226 | qunlock(&fs->ql); | |
| 1996/0122 | } | |
| 1996/0123 | poperror(); | |
| 1996/0122 | ||
| 1996/0201 |
| |
| 1999/0612 | c = devattach('F', spec); | |
| 1996/0201 | c->dev = fs - tinyfs.fs; c->qid.path = CHDIR; c->qid.vers = 0; | |
| 1997/0408/sys/src/9/port/devtinyfs.c:572,597 – 1999/0612/sys/src/9/port/devtinyfs.c:572,597 | ||
| 1997/0327 | static Chan* | |
| 1996/0116 | tinyfsopen(Chan *c, int omode) { | |
| 1996/0201 |
| |
| 1999/0612 | volatile struct { Tfs *fs; } rock; | |
| 1996/0201 |
| |
| 1999/0612 | rock.fs = &tinyfs.fs[c->dev]; | |
| 1996/0201 | ||
| 1996/0218 | if(c->qid.path & CHDIR){ | |
| 1996/0201 | if(omode != OREAD) error(Eperm); } else { | |
| 1996/0226 |
| |
| 1999/0612 | qlock(&rock.fs->ql); | |
| 1996/0220 | if(waserror()){ | |
| 1996/0226 |
| |
| 1999/0612 | qunlock(&rock.fs->ql); | |
| 1996/0220 | nexterror(); } switch(omode){ case OTRUNC|ORDWR: case OTRUNC|OWRITE: | |
| 1996/0218 |
| |
| 1996/0220 |
| |
| 1996/0202 |
| |
| 1999/0612 | 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; | |
| 1996/0220 | break; case OREAD: break; | |
| 1997/0408/sys/src/9/port/devtinyfs.c:598,604 – 1999/0612/sys/src/9/port/devtinyfs.c:598,604 | ||
| 1996/0220 | default: | |
| 1996/0202 | error(Eperm); | |
| 1996/0201 | } | |
| 1996/0226 |
| |
| 1999/0612 | qunlock(&rock.fs->ql); | |
| 1996/0220 | poperror(); | |
| 1996/0201 | } | |
| 1997/0408/sys/src/9/port/devtinyfs.c:608,630 – 1999/0612/sys/src/9/port/devtinyfs.c:608,630 | ||
| 1997/0327 | static void | |
| 1996/0116 | tinyfscreate(Chan *c, char *name, int omode, ulong perm) { | |
| 1996/0201 |
| |
| 1999/0612 | volatile struct { Tfs *fs; } rock; | |
| 1996/0201 | Tfile *f; | |
| 1996/0116 | ||
| 1996/0220 | USED(perm); | |
| 1996/0116 | ||
| 1996/0218 |
| |
| 1999/0612 | rock.fs = &tinyfs.fs[c->dev]; | |
| 1996/0218 | ||
| 1996/0226 |
| |
| 1999/0612 | qlock(&rock.fs->ql); | |
| 1996/0220 | if(waserror()){ | |
| 1996/0226 |
| |
| 1999/0612 | qunlock(&rock.fs->ql); | |
| 1996/0220 | nexterror(); } | |
| 1996/0202 |
| |
| 1996/0226 |
| |
| 1999/0612 | f = newfile(rock.fs, name); qunlock(&rock.fs->ql); | |
| 1996/0220 | poperror(); | |
| 1996/0201 |
| |
| 1999/0612 | c->qid.path = f - rock.fs->f; | |
| 1996/0202 | c->qid.vers = 0; | |
| 1996/0116 | c->mode = openmode(omode); } | |
| 1997/0408/sys/src/9/port/devtinyfs.c:647,672 – 1999/0612/sys/src/9/port/devtinyfs.c:647,672 | ||
| 1997/0327 | static void | |
| 1996/0116 | tinyfsclose(Chan *c) { | |
| 1996/0220 |
| |
| 1999/0612 | volatile struct { Tfs *fs; } rock; | |
| 1996/0201 | Tfile *f, *nf; | |
| 1996/0202 | int i; | |
| 1996/0201 | ||
| 1996/0218 |
| |
| 1999/0612 | rock.fs = &tinyfs.fs[c->dev]; | |
| 1996/0201 | ||
| 1996/0226 |
| |
| 1999/0612 | qlock(&rock.fs->ql); | |
| 1996/0201 | ||
| 1996/0202 | /* dereference file and remove old versions */ | |
| 1996/0220 | if(!waserror()){ if(c->qid.path != CHDIR){ | |
| 1999/0612 | f = &rock.fs->f[c->qid.path]; | |
| 1996/0220 | f->r--; if(f->r == 0){ if(f->flag & Frmonclose) | |
| 1999/0612 | freefile(rock.fs, f, Notabno); | |
| 1996/0220 | else if(f->flag & Fcreating){ /* remove all other files with this name */ | |
| 1999/0612 | for(i = 0; i < rock.fs->fsize; i++){ nf = &rock.fs->f[i]; | |
| 1996/0220 | if(f == nf) continue; if(strcmp(nf->name, f->name) == 0){ | |
| 1997/0408/sys/src/9/port/devtinyfs.c:673,679 – 1999/0612/sys/src/9/port/devtinyfs.c:673,679 | ||
| 1996/0220 | if(nf->r) nf->flag |= Frmonclose; else | |
| 1999/0612 | freefile(rock.fs, nf, Notabno); | |
| 1996/0220 | } | |
| 1996/0203 | } | |
| 1996/0220 | f->flag &= ~Fcreating; | |
| 1997/0408/sys/src/9/port/devtinyfs.c:683,727 – 1999/0612/sys/src/9/port/devtinyfs.c:683,728 | ||
| 1996/0220 | poperror(); | |
| 1996/0202 | } | |
| 1996/0218 |
| |
| 1996/0220 |
| |
| 1997/0327 |
| |
| 1996/0220 |
| |
| 1999/0612 | /* 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; | |
| 1996/0201 | } | |
| 1996/0226 |
| |
| 1999/0612 | qunlock(&rock.fs->ql); | |
| 1996/0116 | } | |
| 1997/0327 | static long | |
| 1996/0116 |
| |
| 1999/0612 | tinyfsread(Chan *c, void *a, long n, vlong offset) | |
| 1996/0116 | { | |
| 1996/0203 |
| |
| 1999/0612 | volatile struct { Tfs *fs; } rock; | |
| 1996/0203 | Tfile *f; | |
| 1996/0220 | int sofar, i, off; | |
| 1996/0218 | ulong bno; | |
| 1996/0206 | Mdata *md; uchar buf[Blen]; | |
| 1996/0217 |
| |
| 1999/0612 | uchar *p; | |
| 1996/0203 | if(c->qid.path & CHDIR) | |
| 1996/0217 | return devdirread(c, a, n, 0, 0, tinyfsgen); | |
| 1996/0203 | ||
| 1996/0220 |
| |
| 1996/0203 |
| |
| 1999/0612 | p = a; rock.fs = &tinyfs.fs[c->dev]; f = &rock.fs->f[c->qid.path]; | |
| 1996/0203 | if(offset >= f->length) return 0; | |
| 1996/0220 | ||
| 1996/0226 |
| |
| 1999/0612 | qlock(&rock.fs->ql); | |
| 1996/0220 | if(waserror()){ | |
| 1996/0226 |
| |
| 1999/0612 | qunlock(&rock.fs->ql); | |
| 1996/0220 | nexterror(); } | |
| 1996/0203 | if(n + offset >= f->length) | |
| 1997/0408/sys/src/9/port/devtinyfs.c:728,734 – 1999/0612/sys/src/9/port/devtinyfs.c:729,735 | ||
| 1996/0203 | n = f->length - offset; | |
| 1996/0206 | ||
| 1996/0217 | /* walk to starting data block */ | |
| 1996/0220 |
| |
| 1999/0612 | if(0 && f->finger <= offset && f->fbno != Notabno){ | |
| 1996/0220 | sofar = f->finger; bno = f->fbno; } else { | |
| 1997/0408/sys/src/9/port/devtinyfs.c:735,742 – 1999/0612/sys/src/9/port/devtinyfs.c:736,743 | ||
| 1996/0220 | sofar = 0; bno = f->dbno; } | |
| 1996/0217 |
| |
| 1999/0612 | for(; sofar + Dlen <= offset; sofar += Dlen){ md = readdata(rock.fs, bno, buf, 0); | |
| 1996/0220 | if(md == 0) error(Eio); | |
| 1996/0206 | bno = GETS(md->bno); | |
| 1997/0408/sys/src/9/port/devtinyfs.c:746,768 – 1999/0612/sys/src/9/port/devtinyfs.c:747,770 | ||
| 1996/0220 | off = offset%Dlen; offset -= off; | |
| 1996/0217 | for(sofar = 0; sofar < n; sofar += i){ | |
| 1999/0612 | md = readdata(rock.fs, bno, buf, &i); | |
| 1996/0220 | if(md == 0) error(Eio); /* update finger for successful read */ | |
| 1999/0612 | f->finger = offset; | |
| 1996/0220 | f->fbno = bno; | |
| 1999/0612 | offset += Dlen; | |
| 1996/0220 | i -= off; | |
| 1996/0217 |
| |
| 1999/0612 | if(i > n - sofar) i = n - sofar; memmove(p, md->data+off, i); | |
| 1996/0217 | p += i; bno = GETS(md->bno); | |
| 1996/0220 | off = 0; | |
| 1996/0217 | } | |
| 1996/0226 |
| |
| 1999/0612 | qunlock(&rock.fs->ql); | |
| 1996/0220 | poperror(); | |
| 1996/0203 | ||
| 1996/0217 | return sofar; | |
| 1997/0408/sys/src/9/port/devtinyfs.c:773,787 – 1999/0612/sys/src/9/port/devtinyfs.c:775,792 | ||
| 1996/0220 | * be lost. They should be recovered next fsinit. */ | |
| 1997/0327 | static long | |
| 1996/0220 |
| |
| 1999/0612 | tinyfswrite(Chan *c, void *a, long n, vlong offset) | |
| 1996/0116 | { | |
| 1996/0217 |
| |
| 1996/0220 |
| |
| 1999/0612 | int last, next, i, finger, off, used; ulong bno, fbno; | |
| 1996/0217 | Mdata *md; uchar buf[Blen]; | |
| 1999/0612 | uchar *p; volatile struct { Tfs *fs; ulong dbno; } rock; | |
| 1996/0217 | if(c->qid.path & CHDIR) error(Eperm); | |
| 1997/0408/sys/src/9/port/devtinyfs.c:789,835 – 1999/0612/sys/src/9/port/devtinyfs.c:794,841 | ||
| 1996/0218 | if(n == 0) return 0; | |
| 1996/0220 |
| |
| 1996/0217 |
| |
| 1999/0612 | p = a; rock.fs = &tinyfs.fs[c->dev]; f = &rock.fs->f[c->qid.path]; | |
| 1996/0217 | ||
| 1996/0218 |
| |
| 1996/0226 |
| |
| 1996/0220 |
| |
| 1999/0612 | qlock(&rock.fs->ql); rock.dbno = Notabno; | |
| 1996/0218 | if(waserror()){ | |
| 1996/0220 |
| |
| 1996/0226 |
| |
| 1999/0612 | freeblocks(rock.fs, rock.dbno, Notabno); qunlock(&rock.fs->ql); | |
| 1996/0218 | nexterror(); } | |
| 1999/0612 | /* files are append only, anything else is illegal */ if(offset != f->length) error("append only"); | |
| 1996/0220 | /* write blocks backwards */ p += n; last = offset + n; | |
| 1999/0612 | 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) | |
| 1996/0220 | error("out of space"); | |
| 1999/0612 | writedata(rock.fs, bno, rock.dbno, p, i, 1); | |
| 1996/0220 | finger = next; /* remember for later */ fbno = bno; | |
| 1999/0612 | } else { writedata(rock.fs, bno, rock.dbno, p, i, 0); } rock.dbno = bno; | |
| 1996/0220 | last = next; } | |
| 1996/0218 | /* walk to last data block */ | |
| 1996/0220 | md = (Mdata*)buf; | |
| 1999/0612 | if(0 && f->finger < offset && f->fbno != Notabno){ | |
| 1996/0220 | next = f->finger; bno = f->fbno; } else { | |
| 1997/0408/sys/src/9/port/devtinyfs.c:836,862 – 1999/0612/sys/src/9/port/devtinyfs.c:842,878 | ||
| 1996/0220 | next = 0; bno = f->dbno; } | |
| 1996/0217 |
| |
| 1999/0612 | used = 0; while(bno != Notabno){ md = readdata(rock.fs, bno, buf, &used); | |
| 1996/0220 | if(md == 0) error(Eio); | |
| 1996/0218 |
| |
| 1999/0612 | if(md->type == Tagend){ if(next + Dlen < offset) panic("devtinyfs1"); | |
| 1996/0218 | break; | |
| 1999/0612 | } next += Dlen; if(next > offset) panic("devtinyfs1"); | |
| 1996/0217 | bno = GETS(md->bno); | |
| 1996/0116 | } | |
| 1996/0220 | /* point to new blocks */ if(offset == 0){ | |
| 1999/0612 | /* first block in a file */ f->dbno = rock.dbno; writedir(rock.fs, f); | |
| 1996/0220 | } else { | |
| 1999/0612 | /* updating a current block */ | |
| 1996/0220 | i = last - offset; | |
| 1999/0612 | memmove(md->data + used, p, i); used += i; | |
| 1996/0218 | } | |
| 1996/0220 |
| |
| 1999/0612 | writedata(rock.fs, bno, rock.dbno, md->data, used, last == n+offset); | |
| 1996/0218 | } | |
| 1996/0220 | f->length += n; | |
| 1996/0218 | ||
| 1997/0408/sys/src/9/port/devtinyfs.c:866,882 – 1999/0612/sys/src/9/port/devtinyfs.c:882,898 | ||
| 1996/0220 | f->fbno = fbno; } | |
| 1996/0218 | poperror(); | |
| 1996/0226 |
| |
| 1999/0612 | qunlock(&rock.fs->ql); | |
| 1996/0217 | ||
| 1996/0220 | return n; | |
| 1996/0116 | } | |
| 1997/0327 | Dev tinyfsdevtab = { | |
| 1997/0408 |
| |
| 1999/0612 | 'F', | |
| 1997/0408 | "tinyfs", | |
| 1997/0327 |
| |
| 1999/0612 | devreset, tinyfsinit, | |
| 1997/0327 | tinyfsattach, tinyfsclone, tinyfswalk, | |
| 1999/0612/sys/src/9/port/devtinyfs.c:460,466 – 1999/0618/sys/src/9/port/devtinyfs.c:460,466 (short | long) | ||
| 1996/0220 | return 0; | |
| 1996/0201 | qid.path = i; qid.vers = 0; | |
| 1996/0202 |
| |
| 1999/0618 | devdir(c, qid, f->name, f->length, eve, 0775, dp); | |
| 1996/0201 | return 1; | |
| 1996/0123 | } | |
| 1999/0612/sys/src/9/port/devtinyfs.c:480,492 – 1999/0618/sys/src/9/port/devtinyfs.c:480,491 | ||
| 1996/0201 | Tfs *fs; | |
| 1999/0612 | Chan *c; volatile struct { Chan *cc; } rock; | |
| 1999/0618 | int i; char buf[NAMELEN*2]; | |
| 1996/0120 | ||
| 1999/0612 |
| |
| 1999/0618 | snprint(buf, sizeof(buf), "/dev/%s", spec); rock.cc = namec(buf, Aopen, ORDWR, 0); | |
| 1996/0220 | ||
| 1999/0612 |
| |
| 1996/0123 | if(waserror()){ | |
| 1999/0612 | cclose(rock.cc); | |
| 1996/0123 | nexterror(); | |
| 1999/0612/sys/src/9/port/devtinyfs.c:594,599 – 1999/0618/sys/src/9/port/devtinyfs.c:593,599 | ||
| 1999/0612 | c->qid.path = f - rock.fs->f; | |
| 1996/0220 | break; case OREAD: | |
| 1999/0618 | case OEXEC: | |
| 1996/0220 | break; default: | |
| 1996/0202 | error(Eperm); | |
| 1999/0618/sys/src/9/port/devtinyfs.c:475,481 – 1999/0623/sys/src/9/port/devtinyfs.c:475,481 (short | long) | ||
| 1999/0612 | * specifier is an open file descriptor */ | |
| 1997/0327 | static Chan* | |
| 1999/0612 |
| |
| 1999/0623 | tinyfsattach(char *spec) | |
| 1996/0116 | { | |
| 1996/0201 | Tfs *fs; | |
| 1999/0612 | Chan *c; | |
| 1999/0623/sys/src/9/port/devtinyfs.c:452,465 – 1999/1230/sys/src/9/port/devtinyfs.c:452,470 (short | long) | ||
| 1999/0612 | USED(ntab); USED(tab); | |
| 1996/0218 | ||
| 1999/1230 | qid.vers = 0; | |
| 1996/0201 | fs = &tinyfs.fs[c->dev]; if(i >= fs->nf) return -1; | |
| 1999/1230 | if(i == DEVDOTDOT){ qid.path = CHDIR; devdir(c, qid, ".", 0, eve, 0555, dp); return 1; } | |
| 1996/0201 | f = &fs->f[i]; | |
| 1996/0220 | if(f->name[0] == 0) return 0; | |
| 1996/0201 | qid.path = i; | |
| 1999/0618 | devdir(c, qid, f->name, f->length, eve, 0775, dp); | |
| 1996/0201 | return 1; | |
| 1996/0123 | } | |