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