xref: /plan9/sys/src/cmd/cwfs/fworm.c (revision 01a344a29f2ff35133953eaef092a50fc8c3163b)
1 #include "all.h"
2 
3 #define	FDEV(d)		((d)->fw.fw)
4 
5 enum { DEBUG = 0 };
6 
7 Devsize
fwormsize(Device * d)8 fwormsize(Device *d)
9 {
10 	Devsize l;
11 
12 	l = devsize(FDEV(d));
13 	l -= l/(BUFSIZE*8) + 1;
14 	return l;
15 }
16 
17 void
fwormream(Device * d)18 fwormream(Device *d)
19 {
20 	Iobuf *p;
21 	Device *fdev;
22 	Off a, b;
23 
24 	print("fworm ream\n");
25 	devinit(d);
26 	fdev = FDEV(d);
27 	a = fwormsize(d);
28 	b = devsize(fdev);
29 	print("\tfwsize = %lld\n", (Wideoff)a);
30 	print("\tbwsize = %lld\n", (Wideoff)b-a);
31 	for(; a < b; a++) {
32 		p = getbuf(fdev, a, Bmod|Bres);
33 		if(!p)
34 			panic("fworm: init");
35 		memset(p->iobuf, 0, RBUFSIZE);
36 		settag(p, Tvirgo, a);
37 		putbuf(p);
38 	}
39 }
40 
41 void
fworminit(Device * d)42 fworminit(Device *d)
43 {
44 	print("fworm init\n");
45 	devinit(FDEV(d));
46 }
47 
48 int
fwormread(Device * d,Off b,void * c)49 fwormread(Device *d, Off b, void *c)
50 {
51 	Iobuf *p;
52 	Device *fdev;
53 	Devsize l;
54 
55 	if(DEBUG)
56 		print("fworm read  %lld\n", (Wideoff)b);
57 	fdev = FDEV(d);
58 	l = devsize(fdev);
59 	l -= l/(BUFSIZE*8) + 1;
60 	if(b >= l)
61 		panic("fworm: rbounds %lld", (Wideoff)b);
62 	l += b/(BUFSIZE*8);
63 
64 	p = getbuf(fdev, l, Brd|Bres);
65 	if(!p || checktag(p, Tvirgo, l))
66 		panic("fworm: checktag %lld", (Wideoff)l);
67 	l = b % (BUFSIZE*8);
68 	if(!(p->iobuf[l/8] & (1<<(l%8)))) {
69 		putbuf(p);
70 		print("fworm: read %lld\n", (Wideoff)b);
71 		return 1;
72 	}
73 	putbuf(p);
74 	return devread(fdev, b, c);
75 }
76 
77 int
fwormwrite(Device * d,Off b,void * c)78 fwormwrite(Device *d, Off b, void *c)
79 {
80 	Iobuf *p;
81 	Device *fdev;
82 	Devsize l;
83 
84 	if(DEBUG)
85 		print("fworm write %lld\n", (Wideoff)b);
86 	fdev = FDEV(d);
87 	l = devsize(fdev);
88 	l -= l/(BUFSIZE*8) + 1;
89 	if(b >= l)
90 		panic("fworm: wbounds %lld", (Wideoff)b);
91 	l += b/(BUFSIZE*8);
92 
93 	p = getbuf(fdev, l, Brd|Bmod|Bres);
94 	if(!p || checktag(p, Tvirgo, l))
95 		panic("fworm: checktag %lld", (Wideoff)l);
96 	l = b % (BUFSIZE*8);
97 	if((p->iobuf[l/8] & (1<<(l%8)))) {
98 		putbuf(p);
99 		print("fworm: write %lld\n", (Wideoff)b);
100 		return 1;
101 	}
102 	p->iobuf[l/8] |= 1<<(l%8);
103 	putbuf(p);
104 	return devwrite(fdev, b, c);
105 }
106