summaryrefslogtreecommitdiff
path: root/sys/src/cmd/cwfs/fworm.c
blob: 5cc20a36c1f434af2a879d808e94c4b2514489e9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include "all.h"

#define	FDEV(d)		((d)->fw.fw)

Devsize
fwormsize(Device *d)
{
	Devsize l;

	l = devsize(FDEV(d));
	l -= l/(BUFSIZE*8) + 1;
	return l;
}

void
fwormream(Device *d)
{
	Iobuf *p;
	Device *fdev;
	Off a, b;

	if(chatty)
		print("fworm ream\n");
	devinit(d);
	fdev = FDEV(d);
	a = fwormsize(d);
	b = devsize(fdev);
	if(chatty){
		print("\tfwsize = %lld\n", (Wideoff)a);
		print("\tbwsize = %lld\n", (Wideoff)b-a);
	}
	for(; a < b; a++) {
		p = getbuf(fdev, a, Bmod|Bres);
		if(!p)
			panic("fworm: init");
		memset(p->iobuf, 0, RBUFSIZE);
		settag(p, Tvirgo, a);
		putbuf(p);
	}
}

void
fworminit(Device *d)
{
	print("fworm init\n");
	devinit(FDEV(d));
}

int
fwormread(Device *d, Off b, void *c)
{
	Iobuf *p;
	Device *fdev;
	Devsize l;

	if(chatty > 1)
		fprint(2, "fworm read  %lld\n", (Wideoff)b);
	fdev = FDEV(d);
	l = devsize(fdev);
	l -= l/(BUFSIZE*8) + 1;
	if(b >= l)
		panic("fworm: rbounds %lld", (Wideoff)b);
	l += b/(BUFSIZE*8);

	p = getbuf(fdev, l, Brd|Bres);
	if(!p || checktag(p, Tvirgo, l))
		panic("fworm: checktag %lld", (Wideoff)l);
	l = b % (BUFSIZE*8);
	if(!(p->iobuf[l/8] & (1<<(l%8)))) {
		putbuf(p);
		fprint(2, "fworm: read %lld\n", (Wideoff)b);
		return 1;
	}
	putbuf(p);
	return devread(fdev, b, c);
}

int
fwormwrite(Device *d, Off b, void *c)
{
	Iobuf *p;
	Device *fdev;
	Devsize l;

	if(chatty > 1)
		fprint(2, "fworm write %lld\n", (Wideoff)b);
	fdev = FDEV(d);
	l = devsize(fdev);
	l -= l/(BUFSIZE*8) + 1;
	if(b >= l)
		panic("fworm: wbounds %lld", (Wideoff)b);
	l += b/(BUFSIZE*8);

	p = getbuf(fdev, l, Brd|Bmod|Bres);
	if(!p || checktag(p, Tvirgo, l))
		panic("fworm: checktag %lld", (Wideoff)l);
	l = b % (BUFSIZE*8);
	if((p->iobuf[l/8] & (1<<(l%8)))) {
		putbuf(p);
		fprint(2, "fworm: write %lld\n", (Wideoff)b);
		return 1;
	}
	p->iobuf[l/8] |= 1<<(l%8);
	putbuf(p);
	return devwrite(fdev, b, c);
}