shithub: gefs

Download patch

ref: 77d59f66059e6632fa5dec987b05fa52315325d1
parent: 421f12180aa74b9628ba189b7bef9bdb24319935
author: Ori Bernstein <ori@eigenstate.org>
date: Sat Apr 8 20:45:49 EDT 2023

ream: add support for growing file systems

--- a/fns.h
+++ b/fns.h
@@ -67,6 +67,7 @@
 void	closesnap(Tree*);
 uvlong	siphash(void*, usize);
 void	reamfs(char*);
+void	growfs(char*);
 int	loadarena(Arena*, Fshdr *fi, vlong);
 void	loadfs(char*);
 void	sync(void);
--- a/main.c
+++ b/main.c
@@ -9,6 +9,7 @@
 Gefs *fs;
 
 int	ream;
+int	grow;
 int	debug;
 int	stdio;
 int	noauth;
@@ -144,6 +145,9 @@
 	case 'r':
 		ream = 1;
 		break;
+	case 'g':
+		grow = 1;
+		break;
 	case 'm':
 		cachesz = strtoll(EARGF(usage()), nil, 0)*MiB;
 		break;
@@ -204,6 +208,10 @@
 		nproc = 8;
 	if(ream){
 		reamfs(dev);
+		exits(nil);
+	}
+	if(grow){
+		growfs(dev);
 		exits(nil);
 	}
 
--- a/ream.c
+++ b/ream.c
@@ -148,7 +148,7 @@
 		sysfatal("ream: %r");
 	sz = d->length;
 	free(d);
-	if(sz < 64*MiB)
+	if(sz < 512*MiB)
 		sysfatal("ream: disk too small");
 	if((mnt = mallocz(sizeof(Mount), 1)) == nil)
 		sysfatal("ream: alloc mount: %r");
@@ -165,8 +165,6 @@
 
 	asz = sz/fs->narena;
 	asz = asz - (asz % Blksz) - Blksz;
-	if(asz < 128*MiB)
-		sysfatal("disk too small");
 	fs->arenasz = asz;
 	off = 0;
 	for(i = 0; i < fs->narena; i++){
@@ -222,4 +220,59 @@
 			sysfatal("sync arena: %r");
 	}
 	free(mnt);
+}
+
+void
+growfs(char *dev)
+{
+	vlong sz, off;
+	int i, narena;
+	Arena *a;
+	Fshdr fi;
+	Dir *d;
+
+	if((fs->fd = open(dev, ORDWR)) == -1)
+		sysfatal("open %s: %r", dev);
+	if((d = dirfstat(fs->fd)) == nil)
+		sysfatal("ream: %r");
+	sz = d->length;
+	free(d);
+
+	if((fs->arenas = calloc(1, sizeof(Arena))) == nil)
+		sysfatal("malloc: %r");
+	fs->narena = 1;
+	for(i = 0; i < fs->narena; i++){
+	Arena *a;
+		a = &fs->arenas[i];
+		if((loadarena(a, &fi, i*fs->arenasz)) == -1)
+			sysfatal("growfs: %r");
+		if(fs->narena == 1){
+			fs->Fshdr = fi;
+			if((fs->arenas = realloc(fs->arenas, fs->narena*sizeof(Arena))) == nil)
+				sysfatal("malloc: %r");
+		}
+	}
+	narena = sz/fs->arenasz;
+	off = fs->arenasz * fs->narena;
+	if(narena <= fs->narena)
+		sysfatal("disk too small for more arenas");
+	if((fs->arenas = realloc(fs->arenas, narena*sizeof(Arena))) == nil)
+		sysfatal("malloc: %r");
+	for(i = fs->narena; i < narena; i++){
+		a = &fs->arenas[i];
+		print("\tadding %d: %lld blocks at %llx\n", i, fs->arenasz/Blksz, off);
+		initarena(&fs->arenas[i], fs, off, fs->arenasz);
+		if((loadarena(a, &fi, i*fs->arenasz)) == -1)
+			sysfatal("growfs: %r");
+		off += fs->arenasz;
+	}
+
+	fs->narena = narena;
+	for(i = 0; i < narena; i++){
+		a = &fs->arenas[i];
+		packarena(a->b->data, Blksz, a, fs);
+		finalize(a->b);
+		if(syncblk(a->b) == -1)
+			sysfatal("sync arena: %r");
+	}
 }