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