code: 9ferno

Download patch

ref: c22d556f7fbaa24c0b3b8dd0ad31145d39768ce0
parent: 4929fd8ba60d5eadc4138caa1aefd96802ef9919
author: 9ferno <gophone2015@gmail.com>
date: Sun Sep 5 00:31:24 EDT 2021

kfs64 with block checksum

--- a/appl/cmd/disk/kfs64.b
+++ b/appl/cmd/disk/kfs64.b
@@ -136,13 +136,14 @@
 
 #
 # disc structure:
-#	Tag:	pad[2] tag[2] path[8] TODO change pad?
-Tagsize: con 2+2+8;
+#	Tag:	pad[2] tag[2] path[8] cksum[4]
+Tagsize: con 2+2+8+4;
 
 Tag: adt
 {
 	tag:	int;
 	path:	big;
+	cksum:	int;
 
 	unpack:	fn(a: array of byte): Tag;
 	pack:	fn(t: self Tag, a: array of byte);
@@ -2141,7 +2142,7 @@
 
 Tag.unpack(a: array of byte): Tag
 {
-	return Tag(get2(a,2), get8(a,4));
+	return Tag(get2(a,2), get8(a,4), get4(a,12));
 }
 
 Tag.pack(t: self Tag, a: array of byte)
@@ -2150,6 +2151,7 @@
 	put2(a, 2, t.tag);
 	if(t.path != QPNONE)
 		put8(a, 4, t.path & ~QPDIR);
+	put4(a, 12, t.cksum);
 }
 
 Superb.get(dev: ref Device, flags: int): ref Superb
@@ -2922,6 +2924,12 @@
 			p.unlock();
 			return nil;
 		}
+		cksum := checksum(p.iobuf);
+		ocksum := get4(p.iobuf, RBUFSIZE-4);
+		if(cksum != ocksum){
+			eprint(sys->sprint("block %bud: checksum failed cksum 0x%bux ocksum 0x%bux", addr, big cksum, big ocksum));
+			return nil;
+		}
 	}
 	return p;
 }
@@ -2933,6 +2941,8 @@
 	if(p.flags & Bimm){
 		if(!(p.flags & Bmod))
 			eprint(sys->sprint("imm and no mod (%bd)", p.addr));
+		cksum := checksum(p.iobuf);
+		put4(p.iobuf, RBUFSIZE-4, cksum);
 		if(!wrenwrite(p.dev.fd, p.addr, p.iobuf))
 			p.flags &= ~(Bmod|Bimm);
 		else
@@ -3042,9 +3052,47 @@
 	return 0;
 }
 
+# using an array of big instead of int to keep it fast
+#	ignoring the last 4 bytes before tag from the checksum calculation
+# using 1's complement addition from
+#	https://barrgroup.com/embedded-systems/how-to/additive-checksums
+#uint16_t
+#NetIpChecksum(uint16_t const ipHeader[], int nWords)
+#{
+#    uint32_t  sum = 0;
+#    /*
+#     * IP headers always contain an even number of bytes.
+#     */
+#    while (nWords-- > 0)
+#    {
+#        sum += *(ipHeader++);
+#    }
+#    /*
+#     * Use carries to compute 1's complement sum.
+#     */
+#    sum = (sum >> 16) + (sum & 0xFFFF);
+#    sum += sum >> 16;
+#    /*
+#     * Return the inverted 16-bit result.
+#     */
+#    return ((unsigned short) ~sum);
+#}   /* NetIpChecksum() */
+checksum(buf: array of byte): int
+{
+	cksum := big 0;
+	for(i := 0; i<(RBUFSIZE-4); i+=4){
+		cksum += big get4(buf,i);
+	}
+	cksum = (cksum >> 32) + (cksum & big 16rFFFFFFFF);
+	cksum += cksum >> 32;
+	return int (~cksum & big 16rFFFFFFFF);
+}
+
 Iobuf.settag(p: self ref Iobuf, tag: int, qpath: big)
 {
-	Tag(tag, qpath).pack(p.iobuf[BUFSIZE:]);
+	# checksum on the tag and qpath too
+	cksum := checksum(p.iobuf);
+	Tag(tag, qpath, cksum).pack(p.iobuf[BUFSIZE:]);
 	p.flags |= Bmod;
 }