32vfs.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 }