plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

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 }