shithub: gefs

Download patch

ref: 3cd02d7caba79a9b680b4685d963c812d6eeda58
parent: 1d8fed57471bb32dd0ed4a6558fcb1e725203380
author: Michael Forney <mforney@mforney.org>
date: Thu Mar 24 01:08:09 EDT 2022

fs: share mounts of same snap

--- a/dat.h
+++ b/dat.h
@@ -414,9 +414,9 @@
 	Rendez	syncrz;
 
 	QLock	snaplk;	/* snapshot lock */
-	Mount	*mounts;
 	Tree	*osnap;
-
+	Lock	mountlk;
+	Mount	*mounts;
 	Lock	connlk;
 	Conn	*conns;
 
--- a/fs.c
+++ b/fs.c
@@ -370,13 +370,69 @@
 	return de;
 }
 
+static Mount *
+getmount(char *name)
+{
+	Mount *mnt;
+	Tree *t;
+
+	lock(&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)
+		goto Out;
+	mnt->ref = 1;
+	if((mnt->name = strdup(name)) == nil){
+		free(mnt);
+		mnt = nil;
+		goto Out;
+	}
+	if((t = openlabel(name)) == nil){
+		werrstr("%s", Enosnap);
+		free(mnt->name);
+		free(mnt);
+		mnt = nil;
+		goto Out;
+	}
+	mnt->root = newsnap(t);
+	closesnap(t);
+	if(mnt->root == nil){
+		free(mnt->name);
+		free(mnt);
+		mnt = nil;
+		goto Out;
+	}
+
+	mnt->next = fs->mounts;
+	fs->mounts = mnt;
+
+Out:
+	unlock(&fs->mountlk);
+	return mnt;
+}
+
 static void
 clunkmount(Mount *mnt)
 {
-	if(mnt != nil && adec(&mnt->ref) == 0){
+	Mount *me, **p;
+
+	if(mnt == nil)
+		return;
+	lock(&fs->mountlk);
+	if(adec(&mnt->ref) == 0){
+		for(p = &fs->mounts; (me = *p) != nil; p = &me->next){
+			if(me == mnt)
+				break;
+		}
+		assert(me != nil);
+		*p = me->next;
 		free(mnt->name);
 		free(mnt);
 	}
+	unlock(&fs->mountlk);
 }
 
 static void
@@ -749,19 +805,13 @@
 	Kvp kv;
 	Key dk;
 	Fid f;
-	Tree *t;
 	int uid;
 
 	de = nil;
-	if((mnt = mallocz(sizeof(Mount), 1)) == nil){
-		rerror(m, Enomem);
-		goto Out;
-	}
-	mnt->ref = 1;
 	if(m->aname[0] == '\0')
 		m->aname = "main";
-	if((mnt->name = strdup(m->aname)) == nil){
-		rerror(m, Enomem);
+	if((mnt = getmount(m->aname)) == nil){
+		rerror(m, "%r");
 		goto Out;
 	}
 
@@ -775,17 +825,6 @@
 	uid = u->id;
 	runlock(&fs->userlk);
 
-	if((t = openlabel(m->aname)) == nil){
-		rerror(m, Enosnap);
-		goto Out;
-	}
-	mnt->root = newsnap(t);
-	closesnap(t);
-	if(mnt->root == nil){
-		rerror(m, Enomem);
-		goto Out;
-	}
-
 	if((p = packdkey(dbuf, sizeof(dbuf), -1ULL, "")) == nil){
 		rerror(m, Elength);
 		goto Out;
@@ -822,8 +861,6 @@
 		goto Out;
 	}
 
-	mnt->next = fs->mounts;
-	fs->mounts = mnt;
 	r.type = Rattach;
 	r.qid = d.qid;
 	respond(m, &r);