ref: dd82b07a863d8ace74ae63a98513db69b24b0019
parent: 79323e05d14bc7d2672edac45aae88e494c06eaa
author: Ori Bernstein <ori@eigenstate.org>
date: Wed May 29 15:34:14 EDT 2024
gefs: correctly serialize updates to mounts we don't need a lock free list, we just need an rwlock; this isn't a high contention data structure.
--- a/sys/src/cmd/gefs/blk.c
+++ b/sys/src/cmd/gefs/blk.c
@@ -928,9 +928,6 @@
case DFtree:
free(p->t);
break;
- case DFmnt:
- free(p->m);
- break;
case DFblk:
a = getarena(p->bp.addr);
qe.op = Qfree;
--- a/sys/src/cmd/gefs/dat.h
+++ b/sys/src/cmd/gefs/dat.h
@@ -433,7 +433,6 @@
enum {
DFblk,
- DFmnt,
DFtree,
};
@@ -517,6 +516,7 @@
QLock synclk;
Rendez syncrz;
+ RWLock mountlk;
Mount *mounts;
Mount *snapmnt;
Lock connlk;
--- a/sys/src/cmd/gefs/fs.c
+++ b/sys/src/cmd/gefs/fs.c
@@ -96,8 +96,10 @@
*/
qlock(&fs->mutlk);
tracem("packb");
- for(mnt = agetp(&fs->mounts); mnt != nil; mnt = mnt->next)
+ rlock(&fs->mountlk);
+ for(mnt = fs->mounts; mnt != nil; mnt = mnt->next)
updatesnap(&mnt->root, mnt->root, mnt->name, mnt->flag);
+ runlock(&fs->mountlk);
/*
* Now that we've updated the snaps, we can sync the
* dlist; the snap tree will not change from here.
@@ -199,7 +201,8 @@
}
t = nil;
*tp = nil;
- for(mnt = agetp(&fs->mounts); mnt != nil; mnt = mnt->next){
+ rlock(&fs->mountlk);
+ for(mnt = fs->mounts; mnt != nil; mnt = mnt->next){
if(strcmp(a->old, mnt->name) == 0){
updatesnap(&mnt->root, mnt->root, mnt->name, mnt->flag);
t = agetp(&mnt->root);
@@ -207,6 +210,7 @@
break;
}
}
+ runlock(&fs->mountlk);
if(t == nil && (t = opensnap(a->old, nil)) == nil){
if(a->fd != -1)
fprint(a->fd, "snap: open '%s': does not exist\n", a->old);
@@ -623,13 +627,13 @@
return fs->snapmnt;
}
- for(mnt = agetp(&fs->mounts); mnt != nil; mnt = mnt->next){
+ wlock(&fs->mountlk);
+ for(mnt = fs->mounts; mnt != nil; mnt = mnt->next){
if(strcmp(name, mnt->name) == 0){
ainc(&mnt->ref);
goto Out;
}
}
-
if((mnt = mallocz(sizeof(*mnt), 1)) == nil)
error(Enomem);
if(waserror()){
@@ -644,10 +648,11 @@
mnt->flag = flg;
mnt->root = t;
mnt->next = fs->mounts;
- asetp(&fs->mounts, mnt);
+ fs->mounts = mnt;
poperror();
Out:
+ wunlock(&fs->mountlk);
return mnt;
}
@@ -654,22 +659,22 @@
void
clunkmount(Mount *mnt)
{
- Mount *me, **p;
- Bfree *f;
+ Mount *e, **p;
if(mnt == nil)
return;
if(adec(&mnt->ref) == 0){
- for(p = &fs->mounts; (me = *p) != nil; p = &me->next){
- if(me == mnt)
+ wlock(&fs->mountlk);
+ p = &fs->mounts;
+ for(e = fs->mounts; e != nil; e = e->next){
+ if(e == mnt)
break;
+ p = &e->next;
}
- assert(me != nil);
- f = emalloc(sizeof(Bfree), 0);
- f->op = DFmnt;
- f->m = mnt;
- *p = me->next;
- limbo(f);
+ assert(e != nil);
+ *p = e->next;
+ free(mnt);
+ wunlock(&fs->mountlk);
}
}
@@ -2673,7 +2678,8 @@
chsend(fs->admchan, a);
tmnow(&now, nil);
- for(mnt = agetp(&fs->mounts); mnt != nil; mnt = mnt->next){
+ rlock(&fs->mountlk);
+ for(mnt = fs->mounts; mnt != nil; mnt = mnt->next){
if(!(mnt->flag & Ltsnap))
continue;
if(now.yday != then.yday){
@@ -2696,6 +2702,7 @@
snapmsg("main", mnt->minutely[m], Lauto);
}
}
+ runlock(&fs->mountlk);
if(now.hour != then.hour)
h = (h+1)%24;
if(now.min != then.min)
--- a/sys/src/cmd/gefs/snap.c
+++ b/sys/src/cmd/gefs/snap.c
@@ -348,12 +348,14 @@
btupsert(&fs->snap, m, nm);
if(deltree){
reclaimblocks(t->gen, succ, t->pred);
- for(mnt = agetp(&fs->mounts); mnt != nil; mnt = mnt->next){
+ rlock(&fs->mountlk);
+ for(mnt = fs->mounts; mnt != nil; mnt = mnt->next){
if(mnt->root->gen == t->succ)
mnt->root->pred = t->pred;
if(mnt->root->gen == t->pred)
mnt->root->succ = t->succ;
}
+ runlock(&fs->mountlk);
}
}