code: mafs

Download patch

ref: 7d2937ab03a29b69f66845c73fc13de64b3349f6
parent: 4e38ae914082c603f04ce820b0ac167c65bd02d2
author: 9ferno <[email protected]>
date: Mon Dec 5 14:50:49 EST 2022

speeding up disk/unused

--- a/extents.c
+++ b/extents.c
@@ -552,8 +552,7 @@
 s32
 saveextents(Extents *es, s8 *buf, u32 nbuf)
 {
-	u64 n, used;
-	s8 tmp[128];
+	u64 used;
 	Extent *e;
 	s32 ret;
 
@@ -674,13 +673,23 @@
 s8
 find(Extents *es, u64 bno)
 {
+	s64 dir;
 	Extent *e;
 
 	if(es == nil || es->lru == nil)
 		return 0;
-	for(e = lowest(es); e != nil; e=e->high){
-		if(e->start == bno)
-			return 1;
+	e = searchlrus(es, bno, 1, &dir);
+	if(dir < 0){
+		for(; e!= nil; e = e->low){
+			if(e->start < bno && bno < e->start+e->len)
+				return 1;
+		}
+	}else if(dir > 0){
+		for(; e!= nil; e = e->high){
+			if(e->start < bno && bno < e->start+e->len)
+				return 1;
+		}
+	}else{ /* dir == 0 */
 		if(e->start < bno && bno < e->start+e->len)
 			return 1;
 	}
@@ -694,6 +703,25 @@
 	if(name != nil)
 		strncpy(es->name, name, 32);
 	es->flush = flush;
+}
+
+/*
+	Prepare an extents with the holes of es.
+	Given used blocks, shows the free blocks.
+ */
+Extents *
+holes(Extents *es, Extents *inv)
+{
+	Extent *e;
+	u64 start;
+
+	if(es == nil || inv == nil)
+		return nil;
+	for(e=lowest(es); e!=nil && e->high != nil; e=e->high){
+		start = e->start+e->len;
+		bfree(inv, start, e->high->start-start);
+	}
+	return inv;
 }
 
 /* obsolete */
--- a/extents.h
+++ b/extents.h
@@ -38,6 +38,7 @@
 void	panic(char *fmt, ...);
 s8	find(Extents *es, u64 bno);
 Extent *add(Extents *es, u64 blkno, u64 len);
+Extents *holes(Extents *es, Extents *inv);
 
 void	showblocknos(int fd, Extents *es);
 void	showextents(int fd, char *msg, Extents *es);
--- a/free.c
+++ b/free.c
@@ -89,10 +89,10 @@
 {
 	s8 *buf;
 
-	buf = emalloc(Maxdatablocksize);
+	buf = emalloc(Maxdatablockunits*Blocksize);
 	devread(blkno, buf, 1);
 	devread(blkno, buf, ((Data*)buf)->len);
-	loadextents(&frees, buf, ((Data*)buf)->len*Blocksize);
+	loadextents(&frees, (s8*)((Data*)buf)->buf, ((Data*)buf)->len*Blocksize -Ddataidssize);
 	free(buf);
 }
 
--- a/fsck
+++ b/fsck
@@ -11,7 +11,9 @@
 nblocks=`{disk/block $disk 2 | awk '$1 == "nblocks"{ print $2 }'}
 
 # write the free extents to /adm/frees
-disk/updatefrees $disk <{disk/unused $nblocks <{disk/used $disk}}
+disk/used $disk > /tmp/used.blocks
+disk/updatefrees $disk <{disk/unused $nblocks /tmp/used.blocks}
 
 # change fsok from 0 to 1
 disk/fsok $disk
+rm /tmp/used.blocks
--- a/mkfile
+++ b/mkfile
@@ -43,7 +43,7 @@
 $O.fsok:	blk.$O dat.$O dev.$O misc.$O tag.$O fsok.$O
 	$LD $LDFLAGS -o $target $prereq
 
-$O.updatefrees:	blk.$O dat.$O dev.$O misc.$O tag.$O updatefrees.$O
+$O.updatefrees:	blk.$O dat.$O dev.$O misc.$O tag.$O extents.$O updatefrees.$O
 	$LD $LDFLAGS -o $target $prereq
 
 $O.unused:	blk.$O dat.$O dev.$O extents.$O unused.$O misc.$O
--- a/unused.c
+++ b/unused.c
@@ -26,8 +26,7 @@
 	disk/unused 11721040049 `{disk/used /dev/sdF1/fs}
 
 	disk/used /dev/sdF1/fs > /mnt/term/tmp/used.blocks
-	sort -n /mnt/term/tmp/used.blocks -o /mnt/term/tmp/used.blocks.sorted
-	disk/unused 11721040049 /mnt/term/tmp/used.blocks.sorted
+	disk/unused 11721040049 /mnt/term/tmp/used.blocks
 
 	diff <{ disk/unused -l 32 <{disk/used tests/test.0/disk}} <{ disk/free tests/test.0/disk }
  */
@@ -99,11 +98,8 @@
 
 	/* identify unused blocks */
 	initextents(&unused, "unused", nil);
-	for(i = 0; i < nblocks; i++){
-		if(find(u.es, i) == 0){
-			add(&unused, i, 1);
-		}
-	}
+	holes(u.es, &unused);
+
 	if(listblocks)
 		showblocknos(1, &unused);
 	else
--- a/updatefrees.c
+++ b/updatefrees.c
@@ -2,6 +2,7 @@
 #include <libc.h>
 #include "dat.h"
 #include "fns.h"
+#include "extents.h"
 
 /*
 	update /adm/frees
@@ -11,11 +12,13 @@
 	disk/updatefrees tests/test.0/disk /mnt/term/tmp/unused.blocks
 
 	TODO
-		does not work when the size of free extents > Blocksize-(3*8)
+		does not work when the size of free extents > Maxdatablocksize
  */
 
+int chatty9p;
 int debug = 0;
 char *devfile = nil, *freesfile = nil;
+Extents frees = {0};
 
 static void
 usage(void)
@@ -27,13 +30,13 @@
 void
 main(int argc, char *argv[])
 {
-	u64 size, freeblkno;
+	u64 size, freeblkno, nblocks;
 	s32 nfreesize;
-	s8 buf[Metadatablocksize], frees[Maxdatablocksize];
-	u64 freesdata[Nu64perblock];
+	s8 buf[Metadatablocksize], freesdata[Maxdatablockunits*Blocksize];
 	int fd;
 	Data *f;
 	Dentry *d;
+	u64 *f64;
 
 	ARGBEGIN{
 	default:	usage();
@@ -52,26 +55,25 @@
 		sysfatal("no frees file");
 
 	memset(buf, 0, Metadatablocksize);
-	memset(frees, 0, Maxdatablocksize);
+	memset(freesdata, 0, Maxdatablockunits*Blocksize);
+	f = (Data*)freesdata;
+	f64 = (u64*)freesdata;
 
 	fd = open(freesfile, OREAD);
 	if(fd < 0)
 		sysfatal("updatefrees: cannot open freesfile %s\n", freesfile);
 
-	nfreesize = readn(fd, frees, Maxdatablocksize);
+	nfreesize = readn(fd, f->buf, Maxdatablocksize);
 	if(nfreesize <= 0)
 		sysfatal("updatefrees: nfreesize %d <= 0\n", nfreesize);
-	if(nfreesize > (Blocksize -sizeof(Datahdr) -sizeof(u64 /* trailing path */)))
+	if(nfreesize > (Maxdatablocksize -sizeof(Datahdr) -sizeof(u64 /* trailing path */)))
 		sysfatal("updatefrees: unsupported nfreesize %d needs more than a block Datablocksize %llud\n",
-					nfreesize, Blocksize -sizeof(Datahdr) -sizeof(u64 /* trailing path */));
-	if(nfreesize > Maxdatablocksize)
+					nfreesize, Maxdatablocksize -sizeof(Datahdr) -sizeof(u64 /* trailing path */));
+	if(nfreesize >= Maxdatablocksize)
 		sysfatal("updatefrees: unsupported nfreesize %d > Datablocksize %llud\n",
 					nfreesize, Maxdatablocksize);
 	close(fd);
 
-	/* use the first block to write */
-	freeblkno = atoll((s8*)frees);
-
 	if (access(devfile, AREAD|AWRITE) == -1)
 		sysfatal("%s cannot access device", devfile);
 
@@ -90,24 +92,24 @@
 
 	if(d->size != nfreesize)
 		print("changed size: %llud to %d\n", d->size, nfreesize);
+	memset(d->buf, 0, Ddatasize);
 	d->size = nfreesize;
 	if(nfreesize < Ddatasize){
-		strncpy(d->buf, frees, nfreesize);
+		strncpy(d->buf, (s8*)f->buf, nfreesize);
 		devwrite(Bdfrees, buf, Metadataunits);
 	}else{
-		if(d->dblocks[0] != freeblkno)
-			print("changed dblocks[0]: %llud to %llud\n", d->dblocks[0], freeblkno);
-		d->dblocks[0] = freeblkno;
+		initextents(&frees, "frees", nil);
+		loadextents(&frees, (s8*)f->buf, nfreesize);
+		nblocks = nlastdatablocks(nfreesize);
+		freeblkno = balloc(&frees, nblocks);
 
-		f = (Data*)freesdata;
+		d->dblocks[0] = freeblkno;
 		f->tag = Tdata;
-		f->len = 1;
-		memcpy(f->buf, frees, Blocksize -Ddataidssize);
-		freesdata[Dpathidx] = Qpfrees;
+		f->len = nblocks;
+		f64[nblocks*Nu64perblock -1] = Qpfrees;
 
 		devwrite(Bdfrees, buf, Metadataunits);
-		// devwrite(freeblkno, frees, nlastdatablocks(nfreesize));
-		devwrite(freeblkno, (s8*)freesdata, 1);
+		devwrite(freeblkno, (s8*)freesdata, nblocks);
 	}
 	close(devfd);
 	exits(0);
--- a/used.c
+++ b/used.c
@@ -31,8 +31,7 @@
 
 	ARGBEGIN{
 	default:	usage();
-	case 'D':	chatty9p= 8
-	; break;
+	case 'D':	chatty9p= 8; break;
 	}ARGEND
 
 	if(argc != 1)