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