Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "all.h"
2
 
3
enum{
4
	MAXWREN = 7,
5
};
6
 
7
#define WMAGIC	"kfs wren device\n"
8
 
9
typedef struct Wren	Wren;
10
 
11
struct Wren{
12
	QLock;
13
	Device	dev;
14
	uvlong	size;
15
	int	fd;
16
};
17
 
18
static Wren	*wrens;
19
static int	maxwren;
20
char		*wrenfile;
21
int		nwren;
22
int		badmagic;
23
 
24
static Wren *
25
wren(Device dev)
26
{
27
	int i;
28
 
29
	for(i = 0; i < maxwren; i++)
30
		if(devcmp(dev, wrens[i].dev) == 0)
31
			return &wrens[i];
32
	panic("can't find wren for %D", dev);
33
	return 0;
34
}
35
 
36
void
37
wreninit(Device dev)
38
{
39
	char buf[MAXBUFSIZE];
40
	Wren *w;
41
	Dir *d;
42
	int fd, i;
43
 
44
	if(wrens == 0)
45
		wrens = ialloc(MAXWREN * sizeof *wrens);
46
	w = &wrens[maxwren];
47
	fd = open(wrenfile, ORDWR);
48
	if(fd < 0)
49
		panic("can't open %s", wrenfile);
50
	if((d = dirfstat(fd)) == nil)
51
		panic("can't stat %s\n", wrenfile);
52
	seek(fd, 0, 0);
53
	i = read(fd, buf, sizeof buf);
54
	if(i < sizeof buf)
55
		panic("can't read %s", wrenfile);
56
	badmagic = 0;
57
	RBUFSIZE = 1024;
58
	if(strncmp(buf+256, WMAGIC, strlen(WMAGIC)) == 0){
59
		RBUFSIZE = atol(buf+256+strlen(WMAGIC));
60
		if(RBUFSIZE % 512){
61
			fprint(2, "kfs: bad buffersize(%d): assuming 1k blocks\n", RBUFSIZE);
62
			RBUFSIZE = 1024;
63
		}
64
	}else
65
		badmagic = 1;
66
	w->dev = dev;
67
	w->size = d->length;
68
	free(d);
69
	w->fd = fd;
70
	maxwren++;
71
}
72
 
73
void
74
wrenream(Device dev)
75
{
76
	Wren *w;
77
	char buf[MAXBUFSIZE];
78
	int fd, i;
79
 
80
	if(RBUFSIZE % 512)
81
		panic("kfs: bad buffersize(%d): restart a multiple of 512\n", RBUFSIZE);
82
	if(RBUFSIZE > sizeof(buf))
83
		panic("kfs: bad buffersize(%d): must be at most %d\n", RBUFSIZE, sizeof(buf));
84
 
85
	print("kfs: reaming the file system using %d byte blocks\n", RBUFSIZE);
86
	w = wren(dev);
87
	fd = w->fd;
88
	memset(buf, 0, sizeof buf);
89
	sprint(buf+256, "%s%d\n", WMAGIC, RBUFSIZE);
90
	qlock(w);
91
	i = seek(fd, 0, 0) < 0 || write(fd, buf, RBUFSIZE) != RBUFSIZE;
92
	qunlock(w);
93
	if(i < 0)
94
		panic("can't ream disk");
95
}
96
 
97
int
98
wrentag(char *p, int tag, long qpath)
99
{
100
	Tag *t;
101
 
102
	t = (Tag*)(p+BUFSIZE);
103
	return t->tag != tag || (qpath&~QPDIR) != t->path;
104
}
105
 
106
int
107
wrencheck(Device dev)
108
{
109
	char buf[MAXBUFSIZE];
110
 
111
	if(badmagic)
112
		return 1;
113
	if(RBUFSIZE > sizeof(buf))
114
		panic("kfs: bad buffersize(%d): must be at most %d\n", RBUFSIZE, sizeof(buf));
115
 
116
	if(wrenread(dev, wrensuper(dev), buf) || wrentag(buf, Tsuper, QPSUPER)
117
	|| wrenread(dev, wrenroot(dev), buf) || wrentag(buf, Tdir, QPROOT))
118
		return 1;
119
	if(((Dentry *)buf)[0].mode & DALLOC)
120
		return 0;
121
	return 1;
122
}
123
 
124
long
125
wrensize(Device dev)
126
{
127
	return wren(dev)->size / RBUFSIZE;
128
}
129
 
130
long
131
wrensuper(Device dev)
132
{
133
	USED(dev);
134
	return 1;
135
}
136
 
137
long
138
wrenroot(Device dev)
139
{
140
	USED(dev);
141
	return 2;
142
}
143
 
144
int
145
wrenread(Device dev, long addr, void *b)
146
{
147
	Wren *w;
148
	int fd, i;
149
 
150
	w = wren(dev);
151
	fd = w->fd;
152
	qlock(w);
153
	i = seek(fd, (vlong)addr*RBUFSIZE, 0) == -1 || read(fd, b, RBUFSIZE) != RBUFSIZE;
154
	qunlock(w);
155
	if(i)
156
		print("wrenread failed: %r\n");
157
	return i;
158
}
159
 
160
int
161
wrenwrite(Device dev, long addr, void *b)
162
{
163
	Wren *w;
164
	int fd, i;
165
 
166
	w = wren(dev);
167
	fd = w->fd;
168
	qlock(w);
169
	i = seek(fd, (vlong)addr*RBUFSIZE, 0) == -1 || write(fd, b, RBUFSIZE) != RBUFSIZE;
170
	qunlock(w);
171
	if(i)
172
		print("wrenwrite failed: %r\n");
173
	return i;
174
}