ref: 39febdb6031e556559a43494b396abb898228b2f
parent: e7398383ed59cfcf02d8916fed0d0be3421822cd
author: Ori Bernstein <ori@eigenstate.org>
date: Mon Dec 18 13:01:43 EST 2023
blk: make dipping into reserve blocks a manual operation
--- a/blk.c
+++ b/blk.c
@@ -7,7 +7,7 @@
#include "fns.h"
#include "atomic.h"
-static vlong blkalloc_lk(Arena*, int);
+static vlong blkalloc_lk(Arena*);
static vlong blkalloc(int, uint);
static void blkdealloc_lk(Arena*, vlong);
static Blk* initblk(Blk*, vlong, vlong, int);
@@ -293,7 +293,7 @@
* and chaining.
*/
if(lb == nil || lb->logsz >= Logspc - Logslop){
- if((o = blkalloc_lk(a, 1)) == -1)
+ if((o = blkalloc_lk(a)) == -1)
error(Efs);
nl = mklogblk(a, o);
p = lb->data + lb->logsz;
@@ -434,7 +434,7 @@
return -1;
}
for(i = 0; i < nblks; i++)
- if((blks[i] = blkalloc_lk(a, 1)) == -1)
+ if((blks[i] = blkalloc_lk(a)) == -1)
error(Efs);
/* fill up the log with the ranges from the tree */
@@ -497,7 +497,7 @@
* the alloc log.
*/
static vlong
-blkalloc_lk(Arena *a, int force)
+blkalloc_lk(Arena *a)
{
Avltree *t;
Arange *r;
@@ -505,7 +505,7 @@
t = a->free;
r = (Arange*)t->root;
- if(!force && a->size - a->used <= a->reserve)
+ if(!usereserve && a->size - a->used <= a->reserve)
return -1;
if(r == nil)
broke(Estuffed);
@@ -559,20 +559,8 @@
tries = 0;
Again:
a = pickarena(ty, hint, tries);
- if(tries == fs->narena)
+ if(tries == 2*fs->narena)
error(Efull);
- /*
- * TODO: there's an extreme edge case
- * here.
- *
- * If the file system has room to alloc
- * a data block but no log block, then
- * we end up with it in a stuck state.
- * The fix is to reserve alloc blocks,
- * so that we're guaranteed to be able
- * to log an alloc if the disk is working
- * correctly.
- */
tries++;
if(tries < fs->narena){
if(canqlock(a) == 0)
@@ -583,7 +571,7 @@
qunlock(a);
nexterror();
}
- if((b = blkalloc_lk(a, 0)) == -1){
+ if((b = blkalloc_lk(a)) == -1){
qunlock(a);
poperror();
goto Again;
--- a/cons.c
+++ b/cons.c
@@ -235,6 +235,54 @@
}
+void
+showfid(int fd, char**, int)
+{
+ int i;
+ Fid *f;
+ Conn *c;
+
+ for(c = fs->conns; c != nil; c = c->next){
+ fprint(fd, "fids:\n");
+ for(i = 0; i < Nfidtab; i++){
+ lock(&c->fidtablk[i]);
+ for(f = c->fidtab[i]; f != nil; f = f->next){
+ rlock(f->dent);
+ fprint(fd, "\tfid[%d] from %#zx: %d [refs=%ld, k=%K, qid=%Q]\n",
+ i, getmalloctag(f), f->fid, f->dent->ref, &f->dent->Key, f->dent->qid);
+ runlock(f->dent);
+ }
+ unlock(&c->fidtablk[i]);
+ }
+ }
+}
+
+void
+showtree(int fd, char **ap, int na)
+{
+ char *name;
+ Tree *t;
+ Blk *b;
+ int h;
+
+ name = "main";
+ memset(&t, 0, sizeof(t));
+ if(na == 1)
+ name = ap[0];
+ if(strcmp(name, "snap") == 0)
+ t = &fs->snap;
+ else if((t = opensnap(name, nil)) == nil){
+ fprint(fd, "open %s: %r\n", name);
+ return;
+ }
+ b = getroot(t, &h);
+ fprint(fd, "=== [%s] %B @%d\n", name, t->bp, t->ht);
+ showblk(fd, b, "contents", 1);
+ dropblk(b);
+ if(t != &fs->snap)
+ closesnap(t);
+}
+
static void
permflip(int fd, char **ap, int)
{
@@ -248,36 +296,33 @@
}
static void
+unreserve(int fd, char **ap, int)
+{
+ if(strcmp(ap[0], "on") == 0)
+ usereserve = 0;
+ else if(strcmp(ap[0], "off") == 0)
+ usereserve = 1;
+ else
+ fprint(2, "unknown reserve %s\n", ap[0]);
+ fprint(fd, "reserve: %d → %d\n", !permissive, permissive);
+}
+static void
help(int fd, char**, int)
{
char *msg =
- "help\n"
- " show this help\n"
- "check\n"
- " run a consistency check on the file system\n"
- "df\n"
- " show disk usage stats\n"
- "halt\n"
- " stop all writers, sync, and go read-only\n"
- "permissive [on|off]\n"
- " switch to/from permissive mode\n"
- "snap (-d old | old new)\n"
- " delete, create or update a new snapshot based off old\n"
- "sync\n"
- " flush all pending writes to disk\n"
- "users\n"
- " reload user table from /adm/users in the main snap\n"
- "show\n"
- " show debug information, the following dumps\n"
- " are supported:\n"
+ "help -- show this help\n"
+ "check -- check for consistency\n"
+ "df -- show disk usage\n"
+ "halt -- stop all writers, sync, and go read-only\n"
+ "permit [on|off] -- switch to/from permissive mode\n"
+ "reserve [on|off] -- enable block reserves\n"
+ "snap -[Smdl] [old [new]] -- manage snapshots\n"
+ "sync --flush all pending writes to disk\n"
+ "users -- reload user table from adm snapshot\n"
+ "show -- debug dumps\n"
" tree [name]\n"
- " the contents of the tree associated with a\n"
- " snapshot. The special name 'snap' shows the\n"
- " snapshot tree\n"
" fid\n"
- " the summary of open fids\n"
- " users\n"
- " the known user file\n";
+ " users\n";
fprint(fd, "%s", msg);
}
@@ -287,9 +332,10 @@
{.name="df", .sub=nil, .minarg=0, .maxarg=0, .fn=showdf},
{.name="halt", .sub=nil, .minarg=0, .maxarg=0, .fn=haltfs},
{.name="help", .sub=nil, .minarg=0, .maxarg=0, .fn=help},
- {.name="permissive", .sub=nil, .minarg=1, .maxarg=1, .fn=permflip},
+ {.name="permit", .sub=nil, .minarg=1, .maxarg=1, .fn=permflip},
{.name="snap", .sub=nil, .minarg=1, .maxarg=3, .fn=snapfs},
{.name="sync", .sub=nil, .minarg=0, .maxarg=0, .fn=syncfs},
+ {.name="reserve", .sub=nil, .minarg=0, .maxarg=1, .fn=unreserve},
{.name="users", .sub=nil, .minarg=0, .maxarg=1, .fn=refreshusers},
/* debugging */
--- a/dump.c
+++ b/dump.c
@@ -331,32 +331,6 @@
}
void
-showtree(int fd, char **ap, int na)
-{
- char *name;
- Tree *t;
- Blk *b;
- int h;
-
- name = "main";
- memset(&t, 0, sizeof(t));
- if(na == 1)
- name = ap[0];
- if(strcmp(name, "snap") == 0)
- t = &fs->snap;
- else if((t = opensnap(name, nil)) == nil){
- fprint(fd, "open %s: %r\n", name);
- return;
- }
- b = getroot(t, &h);
- fprint(fd, "=== [%s] %B @%d\n", name, t->bp, t->ht);
- rshowblk(fd, b, 0, 1);
- dropblk(b);
- if(t != &fs->snap)
- closesnap(t);
-}
-
-void
showbp(int fd, Bptr bp, int recurse)
{
Blk *b;
--- a/fns.h
+++ b/fns.h
@@ -10,6 +10,7 @@
extern Gefs* fs;
extern int debug;
extern int permissive;
+extern int usereserve;
extern char* reamuser;
extern void** errctx;
extern Blk* blkbuf;
@@ -124,8 +125,6 @@
void showblk(int, Blk*, char*, int);
void showbp(int, Bptr, int);
void showtreeroot(int, Tree*);
-void showtree(int, char**, int);
-void showfid(int, char**, int);
int checkfs(int);
#define dprint(...) \
--- a/fs.c
+++ b/fs.c
@@ -537,28 +537,6 @@
unlock(&fs->dtablk);
}
-void
-showfid(int fd, char**, int)
-{
- int i;
- Fid *f;
- Conn *c;
-
- for(c = fs->conns; c != nil; c = c->next){
- fprint(fd, "fids:\n");
- for(i = 0; i < Nfidtab; i++){
- lock(&c->fidtablk[i]);
- for(f = c->fidtab[i]; f != nil; f = f->next){
- rlock(f->dent);
- fprint(fd, "\tfid[%d] from %#zx: %d [refs=%ld, k=%K, qid=%Q]\n",
- i, getmalloctag(f), f->fid, f->dent->ref, &f->dent->Key, f->dent->qid);
- runlock(f->dent);
- }
- unlock(&c->fidtablk[i]);
- }
- }
-}
-
static Fid*
getfid(Conn *c, u32int fid)
{
--- a/main.c
+++ b/main.c
@@ -17,6 +17,7 @@
int noauth;
int nproc;
int permissive;
+int usereserve;
char *reamuser;
char *dev;
vlong cachesz = 512*MiB;
--- a/ream.c
+++ b/ream.c
@@ -244,6 +244,7 @@
sz = d->length;
free(d);
+ print("reaming %s\n", dev);
if(sz < 128*MiB+Blksz)
sysfatal("ream: disk too small");
mnt = emalloc(sizeof(Mount), 1);