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