code: 9ferno

Download patch

ref: 5dd326f865b4c1a3d02214ce81740e7cbf7f87a9
parent: c6cc8aa4a902899d25e485cce95c1cb01fb5cb06
author: 9ferno <gophone2015@gmail.com>
date: Thu Sep 9 05:02:28 EDT 2021

bug fixes

--- a/appl/cmd/disk/kfs64.b
+++ b/appl/cmd/disk/kfs64.b
@@ -138,14 +138,14 @@
 
 #
 # disc structure:
-#	Tag:	path[8] pad[2] tag[2] cksum[4]
-Tagsize: con 8+2+2+4;
+#	Tag:	unused[4] pad[2] tag[2] path[8]
+#	using unused[4] to align to 64 bits
+Tagsize: con 4+2+2+8;
 
 Tag: adt
 {
-	path:	big;
 	tag:	int;
-	cksum:	int;
+	path:	big;
 
 	unpack:	fn(a: array of byte): Tag;
 	pack:	fn(t: self Tag, a: array of byte);
@@ -1391,7 +1391,7 @@
 			# else create an empty block for the new Dentry
 			if(addr1 != big 0)
 				break;
-			p1 = d.putblk(addr, Tdir, 0, emptyblock);
+			p1 = d.putblk(addr, Tdir, 0, emptyblock[0:BUFSIZE]);
 		}
 		if(p1 == nil)
 			return ferr(f, Efull, file, p);
@@ -1399,9 +1399,10 @@
 			p1.put();
 			return ferr(f, Ephase, file, p);
 		}
+
 		for(slot := 0; slot < DIRPERBUF; slot++){
 			d1 := Dentry.get(p1, slot);
-			if(!(d1.mode & DALLOC)){
+		if(!(d1.mode & DALLOC)){
 				if(addr1 == big 0){
 					# use the first empty slot for creating
 					addr1 = p1.addr;
@@ -1479,10 +1480,12 @@
 		# if nil, out of tlock structures
 	}
 	d1.access(FWRITE, file.uid);
+	d1.size = big 0; # should not be needed as we start off with an emptyblock anyway
 	d1.change(~0);
 	d1.update();
 	qid := mkqid(path, 0, d1.mode);
 	p1.put();
+	d.size += big Dentrysize;
 	d.change(~0);
 	d.access(FWRITE, file.uid);
 	d.update();
@@ -1554,7 +1557,6 @@
 			break;
 		if(p1.checktag(Tdir, QPNONE))
 			return ferr(f, Ephase, file, p1);
-
 		for(; slot < DIRPERBUF; slot++){
 			d1 = Dentry.get(p1, slot);
 			if(!(d1.mode & DALLOC))
@@ -1702,8 +1704,6 @@
 	if(end > d.size){
 		if(end > MAXFILESIZE)
 			return ferr(f, Etoobig, file, nil);
-		d.size = end;
-		d.change(Usize);
 	}
 	d.update();
 
@@ -1731,6 +1731,11 @@
 		count -= n;
 		nwrite += n;
 		offset += big n;
+		if(d.size < offset){
+			d.size = offset;
+			d.change(Usize);
+		}
+		p1.put();
 	}
 	d.put();
 	file.unlock();
@@ -1737,6 +1742,8 @@
 	return ref Rmsg.Write(f.tag, nwrite);
 }
 
+# slots are not given back. They are reused on a create though.
+# Hence, the directory size does not decrease.
 doremove(f: ref File, iscon: int): string
 {
 	if(isro(f.fs) || f.cons == 0 && (writegroup && !ingroup(f.uid, writegroup)))
@@ -2146,17 +2153,14 @@
 
 Tag.unpack(a: array of byte): Tag
 {
-	return Tag(get8(a,0), get2(a,10), get4(a,12));
+	return Tag(get2(a,6), get8(a,8));
 }
 
 Tag.pack(t: self Tag, a: array of byte)
 {
+	put2(a, 6, t.tag);
 	if(t.path != QPNONE)
-		put8(a, 0, t.path & ~QPDIR);
-	put2(a, 8, 0);
-	put2(a, 10, t.tag);
-	put4(a, 12, t.cksum);
-
+		put8(a, 8, t.path & ~QPDIR);
 }
 
 Superb.get(dev: ref Device, flags: int): ref Superb
@@ -2256,7 +2260,7 @@
 	d.buf = buf;
 	return d;
 }
-
+# any Dentry at that addr and slot
 Dentry.geta(fs: ref Device, addr: big, slot: int, qpath: big, mode: int): (ref Dentry, string)
 {
 	p := Iobuf.get(fs, addr, mode);
@@ -2514,7 +2518,7 @@
 	}
 	if(putb)
 		d.release();
-	sys->print("Dentry.buf: trip indirect a %bd tag %d %s putb %d\n", a, tag, tagname(tag),putb);
+	sys->print("Dentry.rel2abs: trip indirect a %bd tag %d %s putb %d\n", a, tag, tagname(tag),putb);
 	return big 0;
 }
 
@@ -2533,6 +2537,7 @@
 		return big 0;
 	}
 	addr = get8(bp.iobuf, int a*8);
+	bp.put();
 	return addr;
 }
 
@@ -2554,40 +2559,33 @@
 	dev := p.dev;
 	if(a < big NDBLOCK){
 		p1 := putdata(dev, qpath, d.iob, data[Odblock:], a, tag, boffset, b);
-		d.release();
 		return p1;
 	}
 	a -= big NDBLOCK;
 	if(a < INDPERBUF){
 		p1 := indstore(dev, qpath, d.iob, data[Oiblock:], a, Tind1, tag, boffset, b);
-		d.release();
 		return p1;
 	}
 	a -= INDPERBUF;
 	if(a < INDPERBUF2){
 		p1 := indstore(dev, qpath, d.iob, data[Oiblock+1*8:], a, Tind2, tag, boffset, b);
-		d.release();
 		return p1;
 	}
 	a -= INDPERBUF2;
 	if(a < INDPERBUF3){
 		p1 := indstore(dev, qpath, d.iob, data[Oiblock+2*8:], a, Tind3, tag, boffset, b);
-		d.release();
 		return p1;
 	}
 	a -= INDPERBUF3;
 	if(a < INDPERBUF4){
 		p1 := indstore(dev, qpath, d.iob, data[Oiblock+3*8:], a, Tind4, tag, boffset, b);
-		d.release();
 		return p1;
 	}
 	a -= INDPERBUF4;
 	if(a < INDPERBUF5){
 		p1 := indstore(dev, qpath, d.iob, data[Oiblock+4*8:], a, Tind5, tag, boffset, b);
-		d.release();
 		return p1;
 	}
-	d.release();
 	sys->print("Dentry.buf: trip indirect a %bd tag %d %s\n", a, tag, tagname(tag));
 	return nil;
 }
@@ -2605,7 +2603,7 @@
 		p1.iobuf[boffset:] = b;
 		p1.flags |= Bmod;
 		p1.put();
-		return p1;
+		return Iobuf.get(thedevice, addr, Bread);
 }
 
 indoffset(tag: int): big
@@ -2627,8 +2625,6 @@
 #	if there is no indirect pointer yet to this data block, create one
 indstore(dev: ref Device, qpath: big, p: ref Iobuf, buf: array of byte, a: big, itag: int, tag: int, boffset: int, b: array of byte): ref Iobuf
 {
-	if(a == big 0)
-		return nil;
 	indoff := indoffset(itag);
 	addrloc := int (a/indoff)*8;
 	addr := get8(buf, addrloc);
@@ -2678,7 +2674,8 @@
 				}
 				sb.hwblock = end;
 				sb.touched();
-				sb.print();
+				if(debug)
+					sb.print();
 				sb.put();
 				return balloc(dev, tag, qpath);
 			}
@@ -2716,6 +2713,7 @@
 	return a;
 }
 # add a freed block to the list of free blocks
+#	recursively drills through indirect pointer blocks
 bfree(dev: ref Device, addr: big, d: int)
 {
 	if(addr == big 0)
@@ -2789,19 +2787,11 @@
 {
 	p := d.iob;
 	data := d.buf;
-	bfree(p.dev, get8(data, Oiblock+5*8), 6);
-	put8(data, Oiblock+5*8, big 0);
-	bfree(p.dev, get8(data, Oiblock+4*8), 5);
-	put8(data, Oiblock+4*8, big 0);
-	bfree(p.dev, get8(data, Oiblock+3*8), 4);
-	put8(data, Oiblock+3*8, big 0);
-	bfree(p.dev, get8(data, Oiblock+2*8), 3);
-	put8(data, Oiblock+2*8, big 0);
-	bfree(p.dev, get8(data, Oiblock+1*8), 2);
-	put8(data, Oiblock+1*8, big 0);
-	bfree(p.dev, get8(data, Oiblock), 1);
-	put8(data, Oiblock, big 0);
-	for(i:=NDBLOCK-1; i>=0; i--){
+	for(i:=NIBLOCK-1; i>=0; i--){
+		bfree(p.dev, get8(data, Oiblock+i*8), i+1);
+		put8(data, Odblock+i*8, big 0);
+	}
+	for(i=NDBLOCK-1; i>=0; i--){
 		bfree(p.dev, get8(data, Odblock+i*8), 0);
 		put8(data, Odblock+i*8, big 0);
 	}
@@ -2829,13 +2819,19 @@
 		msg, d.name, len d.name, len array of byte d.name, d.uid, d.gid, d.mode, d.qid.path, d.qid.vers, d.size);
 	p := d.iob;
 	if(p != nil && (data := p.iobuf) != nil){
-		sys->print("\tdblock=");
-		for(i := 0; i < NDBLOCK; i++)
-			sys->print(" %bd", get8(data, Odblock+i*8));
-		sys->print("\tiblock=");
-		for(i = 0; i < NIBLOCK; i++)
-			sys->print(" %bd", get8(data, Oiblock+i*8));
-		sys->print("\n");
+		for(slot:=0; slot<BUFSIZE/Dentrysize; slot++){
+			qid := get8(data, slot*Dentrysize+Opath);
+			qid &=  ~QPDIR;
+			if(qid!= big 0 && d.qid.path == qid){
+				sys->print("\tdblock=");
+				for(i := 0; i < NDBLOCK; i++)
+					sys->print(" %bd", get8(data, slot*Dentrysize+Odblock+i*8));
+				sys->print("\tiblock=");
+				for(i = 0; i < NIBLOCK; i++)
+					sys->print(" %bd", get8(data, slot*Dentrysize+Oiblock+i*8));
+				sys->print("\n");
+			}
+		}
 	}
 }
 
@@ -2988,12 +2984,6 @@
 			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;
 }
@@ -3005,8 +2995,6 @@
 	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
@@ -3115,54 +3103,9 @@
 	return 0;
 }
 
-# this checksum use is useless and slows down processing as
-#	the disks do the crc check at the block level anyway.
-#	Leaving it in as I cannot use the cksum[4] bytes for anything
-#	else and they would be wasted for padding.
-#	might as well use those 4 bytes for something, maybe help catch
-#	memory errors?
-#	check the inferno.notes on the relevant discussion about this too.
-# 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)
 {
-	# checksum on the tag and qpath too
-	cksum := checksum(p.iobuf);
-	Tag(qpath, tag, cksum).pack(p.iobuf[BUFSIZE:]);
+	Tag(tag, qpath).pack(p.iobuf[BUFSIZE:]);
 	p.flags |= Bmod;
 }