shithub: ext4srv

Download patch

ref: 3618c20c3cc2c8dc2cd0cafefec57806b72febbb
parent: 28414e1e7ea575d0d0e7ca747661875e3d954711
author: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
date: Sun Nov 15 16:53:32 EST 2020

SRVNAME.cmd, stats command and proper partition locking

--- a/common.h
+++ b/common.h
@@ -26,10 +26,12 @@
 
 	char dev[32];
 	char mnt[32];
+	char *partdev;
 
 	struct ext4_blockdev bdev;
 	struct ext4_blockdev_iface bdif;
 	struct ext4_sblock *sb;
+	struct ext4_lock oslocks;
 	Qid qid;
 	Qid qidmask;
 	Groups groups;
@@ -45,5 +47,6 @@
 Part *openpart(char *dev, Opts *opts);
 void closepart(Part *p);
 void closeallparts(void);
+void statallparts(void);
 
 char *errno2s(int err);
--- a/ext4srv.c
+++ b/ext4srv.c
@@ -3,6 +3,7 @@
 #include <fcall.h>
 #include <thread.h>
 #include <9p.h>
+#include <bio.h>
 #include "group.h"
 #include "common.h"
 
@@ -45,6 +46,7 @@
 };
 static u8int zero[65536];
 static char Eperm[] = "permission denied";
+static char *srvname;
 
 static char *
 linkresolve(Aux *a, char *s, char **value)
@@ -855,9 +857,41 @@
 }
 
 static void
+cmdsrv(void *)
+{
+	char s[32], *c, *a[16];
+	int f, p[2], n;
+	Biobuf b;
+
+	if(pipe(p) < 0)
+		sysfatal("%r");
+	snprint(s, sizeof(s), "#s/%s.cmd", srvname);
+	if((f = create(s, ORCLOSE|OWRITE, 0660)) < 0){
+		remove(s);
+		if((f = create(s, ORCLOSE|OWRITE, 0660)) < 0)
+			sysfatal("%r");
+	}
+	if(fprint(f, "%d", p[0]) < 1)
+		sysfatal("srv write");
+
+	dup(p[1], 0);
+	close(p[1]);
+	close(p[0]);
+
+	Binit(&b, 0, OREAD);
+	for(; (c = Brdstr(&b, '\n', 1)) != nil; free(c)){
+		if((n = tokenize(c, a, nelem(a))) < 1)
+			continue;
+		if(strcmp(a[0], "stats") == 0)
+			statallparts();
+	}
+}
+
+static void
 rstart(Srv *)
 {
 	threadnotify(note, 1);
+	proccreate(cmdsrv, nil, mainstacksize);
 }
 
 static void
@@ -906,11 +940,13 @@
 void
 threadmain(int argc, char **argv)
 {
-	char *srv, *gr;
+	char *gr;
 	vlong sz;
 	int f;
 
-	srv = "ext4";
+	rfork(RFNOTEG);
+
+	srvname = "ext4";
 	ARGBEGIN{
 	case 'D':
 		chatty9p++;
@@ -926,7 +962,7 @@
 		opts.linkmode = linkmode(EARGF(usage()));
 		goto nomkfs;
 	case 's':
-		srv = EARGF(usage());
+		srvname = EARGF(usage());
 		goto nomkfs;
 	case 'g':
 		gr = EARGF(usage());
@@ -991,7 +1027,7 @@
 		if(argc != 0)
 			usage();
 
-		threadpostmountsrv(&fs, srv, nil, 0);
+		threadpostmountsrv(&fs, srvname, nil, 0);
 		threadexits(nil);
 	}
 }
--- a/part.c
+++ b/part.c
@@ -90,30 +90,6 @@
 }
 
 static int
-bdlock(struct ext4_blockdev *bdev)
-{
-	Part *p;
-
-	p = BDEV2PART(bdev);
-	TRACE("bdlock %p\n", p);
-	qlock(p);
-
-	return 0;
-}
-
-static int
-bdunlock(struct ext4_blockdev *bdev)
-{
-	Part *p;
-
-	p = BDEV2PART(bdev);
-	TRACE("bdunlock %p\n", p);
-	qunlock(p);
-
-	return 0;
-}
-
-static int
 getblksz(char *dev, u32int *blksz)
 {
 	char *s, *e, *g, *a[5];
@@ -241,6 +217,10 @@
 		werrstr("mount: %s", errno2s(r));
 		goto error;
 	}
+	if((r = ext4_mount_setup_locks(p->mnt, &p->oslocks)) != 0){
+		werrstr("locks: %s", errno2s(r));
+		goto error;
+	}
 	if((r = ext4_recover(p->mnt)) != 0 && r != ENOTSUP){
 		werrstr("recover: %s", errno2s(r));
 		goto error;
@@ -273,6 +253,24 @@
 	return -1;
 }
 
+static void
+plock(void *aux)
+{
+	Part *p;
+
+	p = aux;
+	qlock(p);
+}
+
+static void
+punlock(void *aux)
+{
+	Part *p;
+
+	p = aux;
+	qunlock(p);
+}
+
 Part *
 openpart(char *dev, Opts *opts)
 {
@@ -298,7 +296,7 @@
 	/* see if it's already opened */
 	for(p = sv.ps; p != nil && p->qid.path != d->qid.path; p = p->next);
 	if(p == nil){ /* no? then make one */
-		if(getblksz(dev, &blksz) != 0 || (p = calloc(1, sizeof(*p)+blksz)) == nil)
+		if(getblksz(dev, &blksz) != 0 || (p = calloc(1, sizeof(*p)+blksz+strlen(dev)+1)) == nil)
 			goto error;
 
 		p->f = f;
@@ -309,13 +307,17 @@
 		p->bdif.bread = bdread;
 		p->bdif.bwrite = bdwrite;
 		p->bdif.close = bdclose;
-		p->bdif.lock = bdlock;
-		p->bdif.unlock = bdunlock;
 		p->bdif.ph_bsize = blksz;
 		p->bdif.ph_bcnt = d->length/blksz;
 		p->bdif.ph_bbuf = p->blkbuf;
+		p->oslocks.lock = plock;
+		p->oslocks.unlock = punlock;
+		p->oslocks.p_user = p;
 		p->bdif.p_user = p;
 
+		p->partdev = (char*)(p+1) + blksz;
+		strcpy(p->partdev, dev);
+
 		if(opts->fstype > 1){
 			memset(&fs, 0, sizeof(fs));
 			memset(&info, 0, sizeof(info));
@@ -398,5 +400,45 @@
 	qlock(&sv);
 	while(sv.ps != nil)
 		_closepart(sv.ps);
+	qunlock(&sv);
+}
+
+void
+statallparts(void)
+{
+	struct ext4_mount_stats s;
+	uvlong div;
+	Part *p;
+	int r;
+
+	qlock(&sv);
+	for(p = sv.ps; p != nil; p = p->next){
+		if((r = ext4_mount_point_stats(p->mnt, &s)) != 0){
+			print("error: %s: %s\n", p->partdev, errno2s(r));
+		}else{
+			print(
+				"%s (inodes) free %ud, used %ud, total %ud\n",
+				p->partdev,
+				s.free_inodes_count,
+				s.inodes_count-s.free_inodes_count,
+				s.inodes_count
+			);
+			print(
+				"%s (blocks) free %llud, used %llud, total %llud, each %ud\n",
+				p->partdev,
+				s.free_blocks_count,
+				s.blocks_count-s.free_blocks_count,
+				s.blocks_count, s.block_size
+			);
+			div = 1024/(s.block_size/1024);
+			print(
+				"%s (MB) free %llud, used %llud, total %llud\n",
+				p->partdev,
+				s.free_blocks_count/div,
+				(s.blocks_count-s.free_blocks_count)/div,
+				s.blocks_count/div
+			);
+		}
+	}
 	qunlock(&sv);
 }