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);
}