code: 9ferno

Download patch

ref: 44ce0097b612a1fefd754065bdf8d9d2e5ef60c8
parent: 099be971bd6e64a23911e1ab666a3f4eec48bcce
author: 9ferno <gophone2015@gmail.com>
date: Tue Aug 31 23:34:21 EDT 2021

avoid reaming all, ream as needed

--- a/appl/cmd/disk/kfs64.b
+++ b/appl/cmd/disk/kfs64.b
@@ -10,6 +10,10 @@
 #	triple, quadruple, quintiple and sextuple-indirect blocks
 #	filename size 102 bytes
 #	using a default bufsize of 512 bytes, small but not too small
+#	added halt to shutdown using disk/kfscmd
+#	using hwblock to represent the highest touched block number
+#		to avoid reaming all the free space at once
+#		only ream some more blocks after hwblock, when we need space
 
 include "sys.m";
 	sys: Sys;
@@ -41,8 +45,8 @@
 #
 #  fundamental constants
 #
-	# keeping Dentrysize to 512 and 128 bytes for data in Dentry leaves 228 bytes
-NAMELEN:	con 102; # ext2, ext3, ext4, zfs - 255 bytes
+	# keeps Dentrysize to 250
+NAMELEN:	con 102; # ext2, ext3, ext4, zfs - 255 bytes, kfs - 28, cwfs - 144
 NDBLOCK:	con 8;	# number of direct blocks in Dentry
 NIBLOCK:	con 6;	# max depth of indirect blocks in Dentry - sextuple-indirect blocks
 MAXFILESIZE:	con big 16r7FFFFFFFFFFFFFFF;	# Plan 9's limit (kfs's size is signed)
@@ -152,6 +156,7 @@
 	fsize:	big;	# size in blocks
 	tfree:	big;	# total number of free blocks
 	qidgen:	big;	# generator for unique ids
+	hwblock: big;	# highest touched block number, high water block number
 
 	fsok:	int;
 
@@ -824,8 +829,6 @@
 			if(t == nil)
 				break loop;
 			else{
-				if(debug)
-					sys->print("<- %s\n", t.text());
 				r := apply(cp, t);
 				pick m := r {
 				Error =>
@@ -2190,6 +2193,7 @@
 #	u64	fsize;		# total number of blocks on this device
 #	u64	tfree;		# total number of free blocks on this device
 #	u64	qidgen;		# generator for unique ids
+#	u64	hwblock;	# highest touched block number, high water block number
 #	s32	fsok;		# file system ok
 #	u64	roraddr;	# dump root addr 		- obsolete, unused in this program
 #	u64	last;		# last super block addr	- obsolete, unused in this program
@@ -2199,7 +2203,8 @@
 Ofsize: con Ofstart+8;
 Otfree: con Ofsize+8;
 Oqidgen: con Otfree+8;
-Ofsok: con Oqidgen+8;
+Ohwblock: con Oqidgen+8;
+Ofsok: con Ohwblock+8;
 #	Ororaddr: con Ofsok+8;
 #	Olast: con Ororaddr+8;
 #	Onext: con Olast+8;
@@ -2212,6 +2217,7 @@
 	s.fsize = get8(a, Ofsize);
 	s.tfree = get8(a, Otfree);
 	s.qidgen = get8(a, Oqidgen);
+	s.hwblock = get8(a, Ohwblock);
 	s.fsok = get4(a, Ofsok);
 	s.fbuf = a[Super1size:];
 	return s;
@@ -2223,13 +2229,14 @@
 	put8(a, Ofsize, s.fsize);
 	put8(a, Otfree, s.tfree);
 	put8(a, Oqidgen, s.qidgen);
+	put8(a, Ohwblock, s.hwblock);
 	put4(a, Ofsok, s.fsok);
 }
 
 Superb.print(sb: self ref Superb)
 {
-	sys->print("fstart=%bud fsize=%bud tfree=%bud qidgen=%bud fsok=%d\n",
-		sb.fstart, sb.fsize, sb.tfree, sb.qidgen, sb.fsok);
+	sys->print("fstart=%bud fsize=%bud tfree=%bud qidgen=%bud hwblock=%bud fsok=%d\n",
+		sb.fstart, sb.fsize, sb.tfree, sb.qidgen, sb.hwblock, sb.fsok);
 }
 
 Dentry.get(p: ref Iobuf, slot: int): ref Dentry
@@ -2575,7 +2582,7 @@
 	return addr;
 }
 
-# buffer pool management routines
+# allocate a disk block
 balloc(dev: ref Device, tag: int, qpath: big): big
 {
 	# TO DO: cache superblock to reduce pack/unpack
@@ -2587,11 +2594,32 @@
 	sb.tfree--;
 	if(n < 0 || n >= FEPERBUF)
 		panic("balloc: bad freelist");
+	if(sb.hwblock <= big 0)
+		panic(sys->sprint("balloct bad hwblock <= 0: %bd", sb.hwblock));
 	a := get8(sb.fbuf, 4+n*8);
 	if(n == 0){
 		if(a == big 0){
+			# out of free space within hwblock blocks
+			#	extend hwblock and add those new blocks as free space
+			if(sb.hwblock < sb.fsize-big 1){
+				end := sb.hwblock+big FEPERBUF**2;
+				if(end > sb.fsize -big 1)
+					end = sb.fsize -big 1;
+				if(debug)
+					sys->print("balloc: used up all free space, allocating upto %bd\n", end);
+				for(i := end; i>sb.hwblock; i--){
+					addfree(dev, i, sb);
+				}
+				sb.hwblock = end;
+				sb.touched();
+				sb.print();
+				sb.put();
+				return balloc(dev, tag, qpath);
+			}
 			sb.tfree = big 0;
 			sb.touched();
+			if(debug)
+				sb.print();
 			sb.put();
 			return big 0;
 		}
@@ -2621,7 +2649,7 @@
 	sb.put();
 	return a;
 }
-
+# add a freed block to the list of free blocks
 bfree(dev: ref Device, addr: big, d: int)
 {
 	if(addr == big 0)
@@ -2651,7 +2679,7 @@
 	addfree(dev, addr, s);
 	s.put();
 }
-
+# add the freed block to the list of free blocks in super block
 addfree(dev: ref Device, addr: big, sb: ref Superb)
 {
 	if(addr >= sb.fsize){
@@ -3202,7 +3230,6 @@
 	fsize := wrensize(dev);
 	if(fsize <= big 0)
 		panic("file system device size");
-	sys->print("kfs: ream %bd blocks ", fsize);
 	p := Iobuf.get(dev, addr, Bmod|Bimm);
 	p.iobuf[0:] = emptyblock;
 	p.settag(Tsuper, QPSUPER);
@@ -3212,11 +3239,20 @@
 	sb.fsize = fsize;
 	sb.qidgen = big 10;
 	sb.tfree = big 0;
+	sb.hwblock = big 2; # 0th block left out, super block at 1, root block at 2
 	sb.fsok = 0;
 	sb.fbuf = p.iobuf[Super1size:];
 	put4(sb.fbuf, 0, 1);	# nfree = 1
 	msg := "";
-	for(i := fsize-big 1; i>=addr+big 2; i--){
+#	this is taking forever.
+#		Check my notes in the kfs paper and inferno.notes
+#		it is more efficient to do this when needed
+#	for(i := fsize-big 1; i>=addr+big 2; i--){
+	end := sb.fstart+big FEPERBUF**2;
+	if(end > sb.fsize -big 1)
+		end = sb.fsize -big 1;
+	sys->print("kfs: ream %bd out of %bd blocks now:", end, fsize);
+	for(i := end; i>=addr+big 2; i--){
 		#sys->print("superream i %bd\n", i);
 		if(debug){
 			msg = sys->sprint(" %bd ", i);
@@ -3224,6 +3260,7 @@
 		}
 		addfree(dev, i, sb); # what does this do?
 	}
+	sb.hwblock = big end;
 	sys->print("done\n");
 	sb.put();
 }
@@ -3905,7 +3942,9 @@
 	sb.fbuf[0:] = emptyblock[0:4+FEPERBUF*8];
 	sb.tfree = big 0;
 	put4(sb.fbuf, 0, 1);	# nfree = 1
-	for(a:=sb.fsize-sb.fstart-big 1; a >= big 0; a--){
+	if(sb.hwblock <= big 0)
+		panic(sys->sprint("Check.mkfreelist bad hwblock <= 0: %bd", sb.hwblock));
+	for(a:=sb.hwblock-sb.fstart-big 1; a >= big 0; a--){
 		i := a>>3;
 		if(i < big 0 || i >= big len c.amap.bits)
 			continue;