📄 v6fs.c
字号:
/* * 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);voidpopulate(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;}voidpopdir(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+1] = '\0'; f.name = name; popfile(r, f); } r->replete = 1;}voiddotrunc(Ram *r){ USED(r);}voiddocreate(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;}voiddowrite(Ram *r, char *buf, long off, long cnt){ USED(r); USED(buf); USED(off); USED(cnt);}intdopermw(Ram *r){ USED(r); return 0;}/* * fetch an i-node * -- no sanity check for now * -- magic inode-to-disk-block stuff here */Fileinfiget(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;}voidgetblk(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 */longbmap(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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -