code: plan9front

Download patch

ref: 0b849750505a43d27deb1defcd8910193d066481
parent: 19b480838af1721b833f6cd7575e994a5d55071d
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat May 27 19:34:25 EDT 2023

devip: dynamically allocate memory for /net/ndb, increase maximum to 32K

--- a/sys/src/9/ip/devip.c
+++ b/sys/src/9/ip/devip.c
@@ -57,8 +57,11 @@
 
 extern	void nullmediumlink(void);
 extern	void pktmediumlink(void);
-	long ndbwrite(Fs *f, char *a, ulong off, int n);
 
+static void ndbopen(Ndb *ndb, int omode);
+static long ndbwrite(Ndb *ndb, char *a, ulong off, int n);
+static long ndbread(Ndb *ndb, char *a, ulong off, int n);
+
 static int
 ip3gen(Chan *c, int i, Dir *dp)
 {
@@ -149,8 +152,8 @@
 		break;
 	case Qndb:
 		p = "ndb";
-		len = strlen(f->ndb);
-		q.vers = f->ndbvers;
+		len = f->ndb.len;
+		q.vers = f->ndb.vers;
 		break;
 	case Qiproute:
 		p = "iproute";
@@ -165,8 +168,8 @@
 		break;
 	}
 	devdir(c, q, p, len, network, prot, dp);
-	if(i == Qndb && f->ndbmtime > kerndate)
-		dp->mtime = f->ndbmtime;
+	if(i == Qndb && f->ndb.mtime > kerndate)
+		dp->mtime = f->ndb.mtime;
 	return 1;
 }
 
@@ -355,10 +358,7 @@
 	default:
 		break;
 	case Qndb:
-		if((omode & (OWRITE|OTRUNC)) != 0 && !iseve())
-			error(Eperm);
-		if((omode & (OWRITE|OTRUNC)) == (OWRITE|OTRUNC))
-			f->ndb[0] = 0;
+		ndbopen(&f->ndb, omode);
 		break;
 	case Qlog:
 		netlogopen(f);
@@ -640,7 +640,7 @@
  	case Qbootp:
  		return bootpread(a, offset, n);
  	case Qndb:
-		return readstr(offset, a, n, f->ndb);
+		return ndbread(&f->ndb, a, offset, n);
 	case Qiproute:
 		return routeread(f, a, offset, n);
 	case Qipselftab:
@@ -1167,7 +1167,7 @@
 		netlogctl(f, a, n);
 		return n;
 	case Qndb:
-		return ndbwrite(f, a, offset, n);
+		return ndbwrite(&f->ndb, a, offset, n);
 		break;
 	case Qctl:
 		x = f->p[PROTO(ch->qid)];
@@ -1488,17 +1488,72 @@
 	return nc;
 }
 
-long
-ndbwrite(Fs *f, char *a, ulong off, int n)
+static void
+ndbopen(Ndb *ndb, int omode)
 {
-	if(off > strlen(f->ndb))
+	int trunc;
+
+	trunc = omode & OTRUNC;
+	omode = openmode(omode);
+
+	if((omode == OWRITE || omode == ORDWR || trunc) && !iseve())
+		error(Eperm);
+
+	if(trunc){
+		qlock(ndb);
+		free(ndb->buf);
+		ndb->buf = nil;
+		ndb->len = 0;
+		ndb->vers++;
+		ndb->mtime = seconds();
+		qunlock(ndb);
+	}
+}
+
+static long
+ndbwrite(Ndb *ndb, char *a, ulong off, int n)
+{
+	qlock(ndb);
+	if(waserror()){
+		qunlock(ndb);
+		nexterror();
+	}
+	if(off > ndb->len || off+n >= 32*1024)
 		error(Eio);
-	if(off+n >= sizeof(f->ndb))
-		error(Eio);
-	memmove(f->ndb+off, a, n);
-	f->ndb[off+n] = 0;
-	f->ndbvers++;
-	f->ndbmtime = seconds();
+	if(n > 0){
+		if(off+n > ndb->len){
+			char *nb = realloc(ndb->buf, off+n);
+			if(nb == nil)
+				error(Enomem);
+			ndb->buf = nb;
+			ndb->len = off+n;
+		}
+		memmove(ndb->buf+off, a, n);
+		ndb->vers++;
+		ndb->mtime = seconds();
+	}
+	qunlock(ndb);
+	poperror();
+	return n;
+}
+
+static long
+ndbread(Ndb *ndb, char *a, ulong off, int n)
+{
+	qlock(ndb);
+	if(waserror()){
+		qunlock(ndb);
+		nexterror();
+	}
+	if(off >= ndb->len)
+		n = 0;
+	else {
+		if(off+n > ndb->len)
+			n = ndb->len - off;
+		memmove(a, ndb->buf+off, n);
+	}
+	qunlock(ndb);
+	poperror();
 	return n;
 }
 
--- a/sys/src/9/ip/ip.h
+++ b/sys/src/9/ip/ip.h
@@ -15,6 +15,7 @@
 typedef struct	Ipifc	Ipifc;
 typedef struct	Iphash	Iphash;
 typedef struct	Ipht	Ipht;
+typedef struct	Ndb	Ndb;
 typedef struct	Netlog	Netlog;
 typedef struct	Medium	Medium;
 typedef struct	Proto	Proto;
@@ -457,6 +458,14 @@
 
 int unusedlport(Proto *p);
 
+struct Ndb
+{
+	QLock;
+	char	*buf;
+	int	len;
+	int	vers;
+	long	mtime;
+};
 
 /*
  *  one per IP protocol stack
@@ -483,9 +492,7 @@
 
 	Netlog	*alog;
 
-	char	ndb[1024];		/* an ndb entry for this interface */
-	int	ndbvers;
-	long	ndbmtime;
+	Ndb	ndb;			/* an ndb entry for this interface */
 };
 
 struct v6params