Browse Source

Plan 9 from Bell Labs 2010-02-08

David du Colombier 14 years ago
parent
commit
be612b1442

+ 12 - 4
sys/src/cmd/5l/asm.c

@@ -638,7 +638,9 @@ PP = p;
 		r = p->reg;
 		if(p->to.type == D_NONE)
 			rt = 0;
-		if(r == NREG)
+		if(p->as == AMOVW || p->as == AMVN)
+			r = 0;
+		else if(r == NREG)
 			r = rt;
 		o1 |= rf | (r<<16) | (rt<<12);
 		break;
@@ -651,7 +653,9 @@ PP = p;
 		r = p->reg;
 		if(p->to.type == D_NONE)
 			rt = 0;
-		if(r == NREG)
+		if(p->as == AMOVW || p->as == AMVN)
+			r = 0;
+		else if(r == NREG)
 			r = rt;
 		o1 |= (r<<16) | (rt<<12);
 		break;
@@ -665,7 +669,9 @@ PP = p;
 		r = p->reg;
 		if(p->to.type == D_NONE)
 			rt = 0;
-		if(r == NREG)
+		if(p->as == AMOVW || p->as == AMVN)
+			r = 0;
+		else if(r == NREG)
 			r = rt;
 		o1 |= (r<<16) | (rt<<12);
 		break;
@@ -772,7 +778,9 @@ PP = p;
 		o2 = oprrr(p->as, p->scond);
 		o2 |= REGTMP;
 		r = p->reg;
-		if(r == NREG)
+		if(p->as == AMOVW || p->as == AMVN)
+			r = 0;
+		else if(r == NREG)
 			r = p->to.reg;
 		o2 |= r << 16;
 		if(p->to.type != D_NONE)

+ 6 - 6
sys/src/cmd/ndb/dblookup.c

@@ -111,11 +111,12 @@ dblookup(char *name, int class, int type, int auth, int ttl)
 	err = Rname;
 
 	if(type == Tall){
+		lock(&dnlock);
 		rp = nil;
 		for (type = Ta; type < Tall; type++)
-			/* HACK: exclude Taaaa (ipv6) for speed for now */
-			if(implemented[type] && (1 || type != Taaaa))
+			if(implemented[type])
 				rrcat(&rp, dblookup(name, class, type, auth, ttl));
+		unlock(&dnlock);
 		return rp;
 	}
 
@@ -671,7 +672,7 @@ loaddomsrvs(void)
 void
 db2cache(int doit)
 {
-	ulong youngest, temp;
+	ulong youngest;
 	Ndb *ndb;
 	Dir *d;
 	static ulong lastcheck, lastyoungest;
@@ -703,9 +704,8 @@ db2cache(int doit)
 			/* dirfstat avoids walking the mount table each time */
 			if((d = dirfstat(Bfildes(&ndb->b))) != nil ||
 			   (d = dirstat(ndb->file)) != nil){
-				temp = d->mtime;	/* ulong vs int crap */
-				if(temp > youngest)
-					youngest = temp;
+				if(d->mtime > youngest)
+					youngest = d->mtime;
 				free(d);
 			}
 		if(!doit && youngest == lastyoungest)

+ 18 - 10
sys/src/cmd/ndb/dn.c

@@ -217,8 +217,9 @@ dnlookup(char *name, int class, int enter)
 	assert(dp->name != nil);
 	dp->class = class;
 	dp->rr = 0;
-	dp->next = 0;
 	dp->referenced = now;
+	/* add new DN to tail of the hash list.  *l points to last next ptr. */
+	dp->next = nil;
 	*l = dp;
 	unlock(&dnlock);
 
@@ -741,7 +742,7 @@ rrattach1(RR *new, int auth)
 
 //	dnslog("rrattach1: %s", new->owner->name);
 	if(!new->db)
-		new->expire = new->ttl;
+		new->expire = new->ttl;		/* ? */
 	else
 		new->expire = now + Year;
 	dp = new->owner;
@@ -804,16 +805,16 @@ rrattach1(RR *new, int auth)
 		l = &rp->next;
 	}
 
-	if (rronlist(new, *l)) {
+	if (rronlist(new, rp)) {
 		/* should not happen; duplicates were processed above */
-		dnslog("adding duplicate %R to list of %R; aborting", new, *l);
+		dnslog("adding duplicate %R to list of %R; aborting", new, rp);
 		abort();
 	}
 	/*
 	 *  add to chain
 	 */
 	new->cached = 1;
-	new->next = *l;
+	new->next = rp;
 	*l = new;
 }
 
@@ -841,15 +842,21 @@ rrattach(RR *rp, int auth)
 		if(cfg.cachedb && !rp->db && inmyarea(rp->owner->name))
 			rrfree(rp);
 		else {
+			/* ameliorate the memory leak */
+			if (0 && rrlistlen(dp->rr) > 50 && !dp->keep) {
+				dnslog("rrattach(%s): rr list too long; "
+					"freeing it", dp->name);
+				rrfreelist(dp->rr);
+				dp->rr = nil;
+			} else
+				USED(dp);
 			rrattach1(rp, auth);
-			if (rrlistlen(dp->rr) % 100 == 0)
-				dnslog("rrlookup(%s): rr list len is multiple"
-					" of 100", dp->name);
 		}
 	}
 	unlock(&dnlock);
 }
 
+/* should be called with dnlock held */
 RR**
 rrcopy(RR *rp, RR **last)
 {
@@ -1060,7 +1067,8 @@ tsame(int t1, int t2)
 
 /*
  *  Add resource records to a list, duplicate them if they are cached
- *  RR's since these are shared.
+ *  RR's since these are shared.  should be called with dnlock held
+ *  to avoid racing down the start chain.
  */
 RR*
 rrcat(RR **start, RR *rp)
@@ -1963,7 +1971,7 @@ rrfree(RR *rp)
 	RR *nrp;
 	Txt *t;
 
-	assert(rp->magic = RRmagic);
+	assert(rp->magic == RRmagic);
 	assert(!rp->cached);
 
 	dp = rp->owner;

+ 5 - 1
sys/src/cmd/ndb/dnarea.c

@@ -49,14 +49,17 @@ addarea(DN *dp, RR *rp, Ndbtuple *t)
 	Area *s;
 	Area **l;
 
+	lock(&dnlock);
 	if(t->val[0])
 		l = &delegated;
 	else
 		l = &owned;
 
 	for (s = *l; s != nil; s = s->next)
-		if (strcmp(dp->name, s->soarr->owner->name) == 0)
+		if (strcmp(dp->name, s->soarr->owner->name) == 0) {
+			unlock(&dnlock);
 			return;		/* we've already got one */
+		}
 
 	/*
 	 *  The area contains a copy of the soa rr that created it.
@@ -78,6 +81,7 @@ addarea(DN *dp, RR *rp, Ndbtuple *t)
 
 	s->next = *l;
 	*l = s;
+	unlock(&dnlock);
 }
 
 void

+ 10 - 2
sys/src/cmd/ndb/dnresolve.c

@@ -89,7 +89,7 @@ static RR*	dnresolve1(char*, int, int, Request*, int, int);
 static int	netquery(Query *, int);
 
 /*
- * reading /proc/pid/args yields either "name" or "name [display args]",
+ * reading /proc/pid/args yields either "name args" or "name [display args]",
  * so return only display args, if any.
  */
 static char *
@@ -147,7 +147,9 @@ dnresolve(char *name, int class, int type, Request *req, RR **cn, int depth,
 				nrp->ptr->name);
 			rp = dnresolve(nname, class, type, req, cn, depth+1,
 				recurse, rooted, status);
+			lock(&dnlock);
 			rrfreelist(rrremneg(&rp));
+			unlock(&dnlock);
 		}
 		if(drp != nil)
 			rrfreelist(drp);
@@ -181,10 +183,12 @@ dnresolve(char *name, int class, int type, Request *req, RR **cn, int depth,
 				}
 
 				name = rp->host->name;
+				lock(&dnlock);
 				if(cn)
 					rrcat(cn, rp);
 				else
 					rrfreelist(rp);
+				unlock(&dnlock);
 
 				rp = dnresolve1(name, class, type, req,
 					depth, recurse);
@@ -225,7 +229,7 @@ static void
 querydestroy(Query *qp)
 {
 	queryck(qp);
-	/* leave udpfd alone */
+	/* leave udpfd open */
 	if (qp->tcpfd > 0)
 		close(qp->tcpfd);
 	if (qp->tcpctlfd > 0) {
@@ -793,7 +797,9 @@ serveraddrs(Query *qp, int nd, int depth)
 
 			arp = dnresolve(rp->host->name, Cin, Ta, qp->req, 0,
 				depth+1, Recurse, 1, 0);
+			lock(&dnlock);
 			rrfreelist(rrremneg(&arp));
+			unlock(&dnlock);
 			if(arp)
 				break;
 		}
@@ -1106,12 +1112,14 @@ procansw(Query *qp, DNSmsg *mp, uchar *srcip, int depth, Dest *p)
 	}
 
 	/* remove any soa's from the authority section */
+	lock(&dnlock);
 	soarr = rrremtype(&mp->ns, Tsoa);
 
 	/* incorporate answers */
 	unique(mp->an);
 	unique(mp->ns);
 	unique(mp->ar);
+	unlock(&dnlock);
 	if(mp->an)
 		rrattach(mp->an, (mp->flags & Fauth) != 0);
 	if(mp->ar)

+ 5 - 2
sys/src/cmd/ndb/dns.c

@@ -321,8 +321,8 @@ newfid(int fid, int needunused)
 		}
 	mf = emalloc(sizeof(*mf));
 	mf->fid = fid;
-	mf->next = mfalloc.inuse;
 	mf->user = estrdup("dummy");
+	mf->next = mfalloc.inuse;
 	mfalloc.inuse = mf;
 	unlock(&mfalloc);
 	return mf;
@@ -344,6 +344,7 @@ freefid(Mfile *mf)
 			unlock(&mfalloc);
 			return;
 		}
+	unlock(&mfalloc);
 	sysfatal("freeing unused fid");
 }
 
@@ -356,6 +357,7 @@ copyfid(Mfile *mf, int fid)
 	if(nmf == nil)
 		return nil;
 	nmf->fid = fid;
+	free(nmf->user);			/* estrdup("dummy") */
 	nmf->user = estrdup(mf->user);
 	nmf->qid.type = mf->qid.type;
 	nmf->qid.path = mf->qid.path;
@@ -424,7 +426,6 @@ io(void)
 	 */
 	if(setjmp(req.mret))
 		putactivity(0);
-//	procsetname("9p server");
 	req.isslave = 0;
 	stop = 0;
 	while(!stop){
@@ -810,11 +811,13 @@ rwrite(Job *job, Mfile *mf, Request *req)
 	rp = dnresolve(p, Cin, mf->type, req, 0, 0, Recurse, rooted, &status);
 
 	dncheck(0, 1);
+	lock(&dnlock);
 	neg = rrremneg(&rp);
 	if(neg){
 		status = neg->negrcode;
 		rrfreelist(neg);
 	}
+	unlock(&dnlock);
 
 	if(rp == nil)
 		switch(status){

+ 1 - 0
sys/src/cmd/ndb/dns.h

@@ -447,6 +447,7 @@ extern char	*rrtname[];
 extern char	*rname[];
 extern unsigned	nrname;
 extern char	*opname[];
+extern Lock	dnlock;
 
 void	abort(); /* char*, ... */;
 void	addserver(Server**, char*);

+ 14 - 3
sys/src/cmd/ndb/dnserver.c

@@ -132,29 +132,38 @@ dnserver(DNSmsg *reqp, DNSmsg *repp, Request *req, uchar *srcip, int rcode)
 			hint(&repp->ar, tp);
 	}
 
+	/* hint calls rrlookup which holds dnlock, so don't lock before this. */
+
 	/*
 	 *  add an soa to the authority section to help client
 	 *  with negative caching
 	 */
 	if(repp->an == nil)
 		if(myarea != nil){
+			lock(&dnlock);
 			rrcopy(myarea->soarr, &tp);
 			rrcat(&repp->ns, tp);
+			unlock(&dnlock);
 		} else if(neg != nil) {
-			if(neg->negsoaowner != nil)
-				rrcat(&repp->ns, rrlookup(neg->negsoaowner,
-					Tsoa, NOneg));
+			if(neg->negsoaowner != nil) {
+				tp = rrlookup(neg->negsoaowner, Tsoa, NOneg);
+				lock(&dnlock);
+				rrcat(&repp->ns, tp);
+				unlock(&dnlock);
+			}
 			repp->flags |= neg->negrcode;
 		}
 
 	/*
 	 *  get rid of duplicates
 	 */
+	lock(&dnlock);
 	unique(repp->an);
 	unique(repp->ns);
 	unique(repp->ar);
 
 	rrfreelist(neg);
+	unlock(&dnlock);
 
 	dncheck(nil, 1);
 }
@@ -173,6 +182,7 @@ doextquery(DNSmsg *mp, Request *req, int recurse)
 	type = mp->qd->type;
 	rp = dnresolve(name, Cin, type, req, &mp->an, 0, recurse, 1, 0);
 
+	lock(&dnlock);
 	/* don't return soa hints as answers, it's wrong */
 	if(rp && rp->db && !rp->auth && rp->type == Tsoa) {
 		rrfreelist(rp);
@@ -182,6 +192,7 @@ doextquery(DNSmsg *mp, Request *req, int recurse)
 	/* don't let negative cached entries escape */
 	neg = rrremneg(&rp);
 	rrcat(&mp->an, rp);
+	unlock(&dnlock);
 	return neg;
 }