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