123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- /*
- * old (V6 and before) PDP-11 Unix filesystem
- */
- #include <u.h>
- #include <libc.h>
- #include <auth.h>
- #include <fcall.h>
- #include "tapefs.h"
- /*
- * v6 disk inode
- */
- #define V6NADDR 8
- #define V6FMT 0160000
- #define V6IFREG 0100000
- #define V6IFDIR 0140000
- #define V6IFCHR 0120000
- #define V6IFBLK 0160000
- #define V6MODE 0777
- #define V6LARGE 010000
- #define V6SUPERB 1
- #define V6ROOT 1 /* root inode */
- #define V6NAMELEN 14
- #define BLSIZE 512
- #define LINOPB (BLSIZE/sizeof(struct v6dinode))
- #define LNINDIR (BLSIZE/sizeof(unsigned short))
- struct v6dinode {
- unsigned char flags[2];
- unsigned char nlinks;
- unsigned char uid;
- unsigned char gid;
- unsigned char hisize;
- unsigned char losize[2];
- unsigned char addr[V6NADDR][2];
- unsigned char atime[4]; /* pdp-11 order */
- unsigned char mtime[4]; /* pdp-11 order */
- };
- struct v6dir {
- uchar ino[2];
- char name[V6NAMELEN];
- };
- int tapefile;
- Fileinf iget(int ino);
- long bmap(Ram *r, long bno);
- void getblk(Ram *r, long bno, char *buf);
- void
- populate(char *name)
- {
- Fileinf f;
- replete = 0;
- tapefile = open(name, OREAD);
- if (tapefile<0)
- error("Can't open argument file");
- f = iget(V6ROOT);
- ram->perm = f.mode;
- ram->mtime = f.mdate;
- ram->addr = f.addr;
- ram->data = f.data;
- ram->ndata = f.size;
- }
- void
- popdir(Ram *r)
- {
- int i, ino;
- char *cp;
- struct v6dir *dp;
- Fileinf f;
- char name[V6NAMELEN+1];
- cp = 0;
- for (i=0; i<r->ndata; i+=sizeof(struct v6dir)) {
- if (i%BLSIZE==0)
- cp = doread(r, i, BLSIZE);
- dp = (struct v6dir *)(cp+i%BLSIZE);
- ino = dp->ino[0] + (dp->ino[1]<<8);
- if (strcmp(dp->name, ".")==0 || strcmp(dp->name, "..")==0)
- continue;
- if (ino==0)
- continue;
- f = iget(ino);
- strncpy(name, dp->name, V6NAMELEN);
- name[V6NAMELEN] = '\0';
- f.name = name;
- popfile(r, f);
- }
- r->replete = 1;
- }
- void
- dotrunc(Ram *r)
- {
- USED(r);
- }
- void
- docreate(Ram *r)
- {
- USED(r);
- }
- char *
- doread(Ram *r, vlong off, long cnt)
- {
- static char buf[Maxbuf+BLSIZE];
- int bno, i;
- bno = off/BLSIZE;
- off -= bno*BLSIZE;
- if (cnt>Maxbuf)
- error("count too large");
- if (off)
- cnt += off;
- i = 0;
- while (cnt>0) {
- getblk(r, bno, &buf[i*BLSIZE]);
- cnt -= BLSIZE;
- bno++;
- i++;
- }
- return buf;
- }
- void
- dowrite(Ram *r, char *buf, long off, long cnt)
- {
- USED(r); USED(buf); USED(off); USED(cnt);
- }
- int
- dopermw(Ram *r)
- {
- USED(r);
- return 0;
- }
- /*
- * fetch an i-node
- * -- no sanity check for now
- * -- magic inode-to-disk-block stuff here
- */
- Fileinf
- iget(int ino)
- {
- char buf[BLSIZE];
- struct v6dinode *dp;
- long flags, i;
- Fileinf f;
- seek(tapefile, BLSIZE*((ino-1)/LINOPB + V6SUPERB + 1), 0);
- if (read(tapefile, buf, BLSIZE) != BLSIZE)
- error("Can't read inode");
- dp = ((struct v6dinode *)buf) + ((ino-1)%LINOPB);
- flags = (dp->flags[1]<<8) + dp->flags[0];
- f.size = (dp->hisize << 16) + (dp->losize[1]<<8) + dp->losize[0];
- if ((flags&V6FMT)==V6IFCHR || (flags&V6FMT)==V6IFBLK)
- f.size = 0;
- f.data = emalloc(V6NADDR*sizeof(ushort));
- for (i = 0; i < V6NADDR; i++)
- ((ushort*)f.data)[i] = (dp->addr[i][1]<<8) + dp->addr[i][0];
- f.mode = flags & V6MODE;
- if ((flags&V6FMT)==V6IFDIR)
- f.mode |= DMDIR;
- f.uid = dp->uid;
- f.gid = dp->gid;
- f.mdate = (dp->mtime[2]<<0) + (dp->mtime[3]<<8)
- +(dp->mtime[0]<<16) + (dp->mtime[1]<<24);
- return f;
- }
- void
- getblk(Ram *r, long bno, char *buf)
- {
- long dbno;
- if ((dbno = bmap(r, bno)) == 0) {
- memset(buf, 0, BLSIZE);
- return;
- }
- seek(tapefile, dbno*BLSIZE, 0);
- if (read(tapefile, buf, BLSIZE) != BLSIZE)
- error("bad read");
- }
- /*
- * logical to physical block
- * only singly-indirect files for now
- */
- long
- bmap(Ram *r, long bno)
- {
- unsigned char indbuf[LNINDIR][2];
- if (r->ndata <= V6NADDR*BLSIZE) { /* assume size predicts largeness of file */
- if (bno < V6NADDR)
- return ((ushort*)r->data)[bno];
- return 0;
- }
- if (bno < V6NADDR*LNINDIR) {
- seek(tapefile, ((ushort *)r->data)[bno/LNINDIR]*BLSIZE, 0);
- if (read(tapefile, (char *)indbuf, BLSIZE) != BLSIZE)
- return 0;
- return ((indbuf[bno%LNINDIR][1]<<8) + indbuf[bno%LNINDIR][0]);
- }
- return 0;
- }
|