| tv6fs.c - plan9port - [fork] Plan 9 from user space | |
| git clone git://src.adamsgaard.dk/plan9port | |
| Log | |
| Files | |
| Refs | |
| README | |
| 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, "..")==… | |
| 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]… | |
| 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… | |
| 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, … | |
| 209 if (read(tapefile, (char *)indbuf, BLSIZE) != BLSIZE) | |
| 210 return 0; | |
| 211 return ((indbuf[bno%LNINDIR][1]<<8) + indbuf[bno%LNINDIR… | |
| 212 } | |
| 213 return 0; | |
| 214 } |