1 #include "all.h" 2 3 #define FDEV(d) ((d)->fw.fw) 4 5 enum { DEBUG = 0 }; 6 7 Devsize 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 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 42 fworminit(Device *d) 43 { 44 print("fworm init\n"); 45 devinit(FDEV(d)); 46 } 47 48 int 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 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