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