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)