URI:
       tv10fs.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tv10fs.c (3799B)
       ---
            1 /*
            2  * 10th edition 4K file system
            3  */
            4 #include <u.h>
            5 #include <libc.h>
            6 #include <auth.h>
            7 #include <fcall.h>
            8 #include "tapefs.h"
            9 
           10 /*
           11  * v10 disk inode
           12  */
           13 #define        VNADDR        13
           14 #define        VFMT        0160000
           15 #define        VIFREG        0100000
           16 #define        VIFDIR        0040000
           17 #define        VIFCHR        0120000
           18 #define        VIFBLK        0160000
           19 #define        VMODE        0777
           20 #define        VSUPERB        1
           21 #define        VROOT                2        /* root inode */
           22 #define        VNAMELEN        14
           23 #define        BLSIZE        4096
           24 #define        LINOPB        (BLSIZE/sizeof(struct v10dinode))
           25 #define        LNINDIR        (BLSIZE/sizeof(unsigned long))
           26 
           27 struct v10dinode {
           28         unsigned char flags[2];
           29         unsigned char nlinks[2];
           30         unsigned char uid[2];
           31         unsigned char gid[2];
           32         unsigned char size[4];
           33         unsigned char addr[40];
           34         unsigned char atime[4];
           35         unsigned char mtime[4];
           36         unsigned char ctime[4];
           37 };
           38 
           39 struct        v10dir {
           40         uchar        ino[2];
           41         char        name[VNAMELEN];
           42 };
           43 
           44 int        tapefile;
           45 Fileinf        iget(int ino);
           46 long        bmap(Ram *r, long bno);
           47 void        getblk(Ram *r, long bno, char *buf);
           48 
           49 void
           50 populate(char *name)
           51 {
           52         Fileinf f;
           53 
           54         replete = 0;
           55         tapefile = open(name, OREAD);
           56         if (tapefile<0)
           57                 error("Can't open argument file");
           58         f = iget(VROOT);
           59         ram->perm = f.mode;
           60         ram->mtime = f.mdate;
           61         ram->addr = f.addr;
           62         ram->data = f.data;
           63         ram->ndata = f.size;
           64 }
           65 
           66 void
           67 popdir(Ram *r)
           68 {
           69         int i, ino;
           70         char *cp;
           71         struct v10dir *dp;
           72         Fileinf f;
           73         char name[VNAMELEN+1];
           74 
           75         cp = 0;
           76         for (i=0; i<r->ndata; i+=sizeof(struct v10dir)) {
           77                 if (i%BLSIZE==0)
           78                         cp = doread(r, i, BLSIZE);
           79                 dp = (struct v10dir *)(cp+i%BLSIZE);
           80                 ino = g2byte(dp->ino);
           81                 if (strcmp(dp->name, ".")==0 || strcmp(dp->name, "..")==0)
           82                         continue;
           83                 if (ino==0)
           84                         continue;
           85                 f = iget(ino);
           86                 strncpy(name, dp->name, VNAMELEN);
           87                 name[VNAMELEN] = '\0';
           88                 f.name = name;
           89                 popfile(r, f);
           90         }
           91         r->replete = 1;
           92 }
           93 
           94 void
           95 dotrunc(Ram *r)
           96 {
           97         USED(r);
           98 }
           99 
          100 void
          101 docreate(Ram *r)
          102 {
          103         USED(r);
          104 }
          105 
          106 char *
          107 doread(Ram *r, vlong off, long cnt)
          108 {
          109         static char buf[Maxbuf+BLSIZE];
          110         int bno, i;
          111 
          112         bno = off/BLSIZE;
          113         off -= bno*BLSIZE;
          114         if (cnt>Maxbuf)
          115                 error("count too large");
          116         if (off)
          117                 cnt += off;
          118         i = 0;
          119         while (cnt>0) {
          120                 getblk(r, bno, &buf[i*BLSIZE]);
          121                 cnt -= BLSIZE;
          122                 bno++;
          123                 i++;
          124         }
          125         return buf+off;
          126 }
          127 
          128 void
          129 dowrite(Ram *r, char *buf, long off, long cnt)
          130 {
          131         USED(r); USED(buf); USED(off); USED(cnt);
          132 }
          133 
          134 int
          135 dopermw(Ram *r)
          136 {
          137         USED(r);
          138         return 0;
          139 }
          140 
          141 /*
          142  * fetch an i-node
          143  * -- no sanity check for now
          144  * -- magic inode-to-disk-block stuff here
          145  */
          146 
          147 Fileinf
          148 iget(int ino)
          149 {
          150         char buf[BLSIZE];
          151         struct v10dinode *dp;
          152         long flags, i;
          153         Fileinf f;
          154 
          155         memset(&f, 0, sizeof f);
          156         seek(tapefile, BLSIZE*((ino-1)/LINOPB + VSUPERB + 1), 0);
          157         if (read(tapefile, buf, BLSIZE) != BLSIZE)
          158                 error("Can't read inode");
          159         dp = ((struct v10dinode *)buf) + ((ino-1)%LINOPB);
          160         flags = g2byte(dp->flags);
          161         f.size = g4byte(dp->size);
          162         if ((flags&VFMT)==VIFCHR || (flags&VFMT)==VIFBLK)
          163                 f.size = 0;
          164         f.data = emalloc(VNADDR*sizeof(long));
          165         for (i = 0; i < VNADDR; i++)
          166                 ((long*)f.data)[i] = g3byte(dp->addr+3*i);
          167         f.mode = flags & VMODE;
          168         if ((flags&VFMT)==VIFDIR)
          169                 f.mode |= DMDIR;
          170         f.uid = g2byte(dp->uid);
          171         f.gid = g2byte(dp->gid);
          172         f.mdate = g4byte(dp->mtime);
          173         return f;
          174 }
          175 
          176 void
          177 getblk(Ram *r, long bno, char *buf)
          178 {
          179         long dbno;
          180 
          181         if ((dbno = bmap(r, bno)) == 0) {
          182                 memset(buf, 0, BLSIZE);
          183                 return;
          184         }
          185         seek(tapefile, dbno*BLSIZE, 0);
          186         if (read(tapefile, buf, BLSIZE) != BLSIZE)
          187                 error("bad read");
          188 }
          189 
          190 /*
          191  * logical to physical block
          192  * only singly-indirect files for now
          193  */
          194 
          195 long
          196 bmap(Ram *r, long bno)
          197 {
          198         unsigned char indbuf[LNINDIR][sizeof(long)];
          199 
          200         if (bno < VNADDR-3)
          201                 return ((long*)r->data)[bno];
          202         if (bno < VNADDR*LNINDIR) {
          203                 seek(tapefile, ((long *)r->data)[(bno-(VNADDR-3))/LNINDIR+(VNADDR-3)]*BLSIZE, 0);
          204                 if (read(tapefile, (char *)indbuf, BLSIZE) != BLSIZE)
          205                         return 0;
          206                 return ((indbuf[(bno-(VNADDR-3))%LNINDIR][2]<<16) + (indbuf[(bno-(VNADDR-3))%LNINDIR][1]<<8)
          207                         + indbuf[(bno-(VNADDR-3))%LNINDIR][0]);
          208         }
          209         return 0;
          210 }