summaryrefslogtreecommitdiff
path: root/sys/src/cmd/cwfs
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@localhost>2011-04-12 15:53:55 +0000
committercinap_lenrek <cinap_lenrek@localhost>2011-04-12 15:53:55 +0000
commit67e93d6a0a4f15192638e131413b9d64c4269c76 (patch)
tree88fd1d17c4be283683a96ced44159e3ce6b6f2f7 /sys/src/cmd/cwfs
parent7208d528bd42f981f2535403f72e4c0d7d8df643 (diff)
updating cwfs and moving installer in /rc/bin
Diffstat (limited to 'sys/src/cmd/cwfs')
-rw-r--r--sys/src/cmd/cwfs/64xbit.h22
-rw-r--r--sys/src/cmd/cwfs/con.c7
-rw-r--r--sys/src/cmd/cwfs/config.c41
-rw-r--r--sys/src/cmd/cwfs/cwfs64/conf.c31
-rw-r--r--sys/src/cmd/cwfs/cwfs64/dat.h36
-rw-r--r--sys/src/cmd/cwfs/cwfs64/mkfile2
-rw-r--r--sys/src/cmd/cwfs/cwfs64x/conf.c31
-rw-r--r--sys/src/cmd/cwfs/cwfs64x/dat.h36
-rw-r--r--sys/src/cmd/cwfs/cwfs64x/mkfile2
-rw-r--r--sys/src/cmd/cwfs/iobuf.c34
-rw-r--r--sys/src/cmd/cwfs/main.c101
-rw-r--r--sys/src/cmd/cwfs/mkfile7
-rw-r--r--sys/src/cmd/cwfs/net.c358
-rw-r--r--sys/src/cmd/cwfs/pc.c2
-rw-r--r--sys/src/cmd/cwfs/portdat.h1
-rw-r--r--sys/src/cmd/cwfs/portfns.h6
-rw-r--r--sys/src/cmd/cwfs/portmkfile2
-rw-r--r--sys/src/cmd/cwfs/srv.c209
-rw-r--r--sys/src/cmd/cwfs/sub.c4
-rw-r--r--sys/src/cmd/cwfs/wren.c1
20 files changed, 548 insertions, 385 deletions
diff --git a/sys/src/cmd/cwfs/64xbit.h b/sys/src/cmd/cwfs/64xbit.h
new file mode 100644
index 000000000..53edb78db
--- /dev/null
+++ b/sys/src/cmd/cwfs/64xbit.h
@@ -0,0 +1,22 @@
+/*
+ * fundamental constants and types of the implementation
+ * changing any of these changes the layout on disk
+ */
+
+/* the glorious new, incompatible (on disk) 64-bit world */
+
+/* keeping NAMELEN ≤ 50 bytes permits 3 Dentrys per mag disk sector */
+enum {
+ NAMELEN = 144, /* max size of file name components */
+ NDBLOCK = 6, /* number of direct blocks in Dentry */
+ NIBLOCK = 4, /* max depth of indirect blocks */
+};
+
+/*
+ * file offsets & sizes, in bytes & blocks. typically long or vlong.
+ * vlong is used in the code where would be needed if Off were just long.
+ */
+typedef vlong Off;
+
+#undef COMPAT32
+#define swaboff swab8
diff --git a/sys/src/cmd/cwfs/con.c b/sys/src/cmd/cwfs/con.c
index 6448b4666..c1aa59623 100644
--- a/sys/src/cmd/cwfs/con.c
+++ b/sys/src/cmd/cwfs/con.c
@@ -36,13 +36,10 @@ consserve1(void *)
char *conline;
for (;;) {
- /* conslock(); */
do {
- print("%s: ", service);
- if ((conline = Brdline(&bin, '\n')) == nil)
- print("\n");
- else {
+ if ((conline = Brdline(&bin, '\n')) != nil) {
conline[Blinelen(&bin)-1] = '\0';
+ print("%s: %s\n", service, conline);
cmd_exec(conline);
}
} while (conline != nil);
diff --git a/sys/src/cmd/cwfs/config.c b/sys/src/cmd/cwfs/config.c
index bc0d118ea..b11c53e77 100644
--- a/sys/src/cmd/cwfs/config.c
+++ b/sys/src/cmd/cwfs/config.c
@@ -82,6 +82,11 @@ devcmpr(Device *d1, Device *d2)
case Devwren:
case Devworm:
case Devlworm:
+ if(d1->wren.file || d2->wren.file){
+ if(d1->wren.file == nil || d2->wren.file == nil)
+ return 1;
+ return !!strcmp(d1->wren.file, d2->wren.file);
+ }
if(d1->wren.ctrl == d2->wren.ctrl)
if(d1->wren.targ == d2->wren.targ)
if(d1->wren.lun == d2->wren.lun)
@@ -222,7 +227,7 @@ config(void)
{
int c, m;
Device *d;
- char *icp;
+ char *icp, *s, *e;
if(f.error)
return devnone;
@@ -248,7 +253,41 @@ config(void)
d->type = Devnone;
break;
+ case '/': /* /path/to/file mapped file */
+ case '"': /* "/path/to/file" mapped file */
+ case '\'': /* '/path/to/file' mapped file */
+ Mapped:
+ d->type = Devwren;
+ if(c == '/'){
+ s = f.charp-1;
+ for(e = s+1; *e; e++)
+ if(*e == ')' || *e == ']' || *e == '}')
+ break;
+ f.charp = e;
+ } else {
+ s = f.charp;
+ if((e = strchr(s, c)) == nil){
+ cdiag("unterminated string", c);
+ return devnone;
+ }
+ f.charp = e+1;
+ }
+ d->wren.ctrl = -1;
+ d->wren.targ = -1;
+ d->wren.lun = -1;
+ d->wren.file = malloc((e - s) + 1);
+ memmove(d->wren.file, s, e - s);
+ d->wren.file[e - s] = 0;
+ break;
+
case 'w': /* w[#.]#[.#] wren [ctrl] unit [lun] */
+ switch(*f.charp){
+ case '/':
+ case '"':
+ case '\'':
+ c = *f.charp++;
+ goto Mapped;
+ }
case 'r': /* r# worm side */
case 'l': /* l# labelled-worm side */
icp = f.charp;
diff --git a/sys/src/cmd/cwfs/cwfs64/conf.c b/sys/src/cmd/cwfs/cwfs64/conf.c
new file mode 100644
index 000000000..876cdee30
--- /dev/null
+++ b/sys/src/cmd/cwfs/cwfs64/conf.c
@@ -0,0 +1,31 @@
+/* generic old-cw configuration */
+
+#include "all.h"
+
+#ifndef DATE
+#define DATE 1170808167L
+#endif
+
+Timet fs_mktime = DATE; /* set by mkfile */
+
+Startsb startsb[] = {
+ "main", 2,
+ nil,
+};
+
+void
+localconfinit(void)
+{
+ conf.nfile = 40000;
+ conf.nodump = 0;
+// conf.nodump = 1; /* jukebox is r/o */
+ conf.firstsb = 13219302;
+ conf.recovsb = 0;
+ conf.nlgmsg = 100;
+ conf.nsmmsg = 500;
+}
+
+int (*fsprotocol[])(Msgbuf*) = {
+ serve9p2,
+ nil,
+};
diff --git a/sys/src/cmd/cwfs/cwfs64/dat.h b/sys/src/cmd/cwfs/cwfs64/dat.h
new file mode 100644
index 000000000..4c63315ca
--- /dev/null
+++ b/sys/src/cmd/cwfs/cwfs64/dat.h
@@ -0,0 +1,36 @@
+/* generic old-cw configuration: 16K blocks, 32-bit sizes */
+
+/*
+ * The most fundamental constant.
+ * The code will not compile with RBUFSIZE made a variable;
+ * for one thing, RBUFSIZE determines FEPERBUF, which determines
+ * the number of elements in a free-list-block array.
+ */
+#ifndef RBUFSIZE
+#define RBUFSIZE (16*1024) /* raw buffer size */
+#endif
+#include "64bit.h"
+/*
+ * setting this to zero permits the use of discs of different sizes, but
+ * can make jukeinit() quite slow while the robotics work through each disc
+ * twice (once per side).
+ */
+enum { FIXEDSIZE = 1 };
+
+
+#include "portdat.h"
+
+enum { MAXBANK = 2 };
+
+typedef struct Mbank {
+ ulong base;
+ ulong limit;
+} Mbank;
+
+typedef struct Mconf {
+ Lock;
+ Mbank bank[MAXBANK];
+ int nbank;
+ ulong memsize;
+} Mconf;
+extern Mconf mconf;
diff --git a/sys/src/cmd/cwfs/cwfs64/mkfile b/sys/src/cmd/cwfs/cwfs64/mkfile
new file mode 100644
index 000000000..8835ba7cd
--- /dev/null
+++ b/sys/src/cmd/cwfs/cwfs64/mkfile
@@ -0,0 +1,2 @@
+FS='64'
+<../portmkfile
diff --git a/sys/src/cmd/cwfs/cwfs64x/conf.c b/sys/src/cmd/cwfs/cwfs64x/conf.c
new file mode 100644
index 000000000..876cdee30
--- /dev/null
+++ b/sys/src/cmd/cwfs/cwfs64x/conf.c
@@ -0,0 +1,31 @@
+/* generic old-cw configuration */
+
+#include "all.h"
+
+#ifndef DATE
+#define DATE 1170808167L
+#endif
+
+Timet fs_mktime = DATE; /* set by mkfile */
+
+Startsb startsb[] = {
+ "main", 2,
+ nil,
+};
+
+void
+localconfinit(void)
+{
+ conf.nfile = 40000;
+ conf.nodump = 0;
+// conf.nodump = 1; /* jukebox is r/o */
+ conf.firstsb = 13219302;
+ conf.recovsb = 0;
+ conf.nlgmsg = 100;
+ conf.nsmmsg = 500;
+}
+
+int (*fsprotocol[])(Msgbuf*) = {
+ serve9p2,
+ nil,
+};
diff --git a/sys/src/cmd/cwfs/cwfs64x/dat.h b/sys/src/cmd/cwfs/cwfs64x/dat.h
new file mode 100644
index 000000000..e14371d43
--- /dev/null
+++ b/sys/src/cmd/cwfs/cwfs64x/dat.h
@@ -0,0 +1,36 @@
+/* generic old-cw configuration: 16K blocks, 32-bit sizes */
+
+/*
+ * The most fundamental constant.
+ * The code will not compile with RBUFSIZE made a variable;
+ * for one thing, RBUFSIZE determines FEPERBUF, which determines
+ * the number of elements in a free-list-block array.
+ */
+#ifndef RBUFSIZE
+#define RBUFSIZE (16*1024) /* raw buffer size */
+#endif
+#include "64xbit.h"
+/*
+ * setting this to zero permits the use of discs of different sizes, but
+ * can make jukeinit() quite slow while the robotics work through each disc
+ * twice (once per side).
+ */
+enum { FIXEDSIZE = 1 };
+
+
+#include "portdat.h"
+
+enum { MAXBANK = 2 };
+
+typedef struct Mbank {
+ ulong base;
+ ulong limit;
+} Mbank;
+
+typedef struct Mconf {
+ Lock;
+ Mbank bank[MAXBANK];
+ int nbank;
+ ulong memsize;
+} Mconf;
+extern Mconf mconf;
diff --git a/sys/src/cmd/cwfs/cwfs64x/mkfile b/sys/src/cmd/cwfs/cwfs64x/mkfile
new file mode 100644
index 000000000..ab94d0fb2
--- /dev/null
+++ b/sys/src/cmd/cwfs/cwfs64x/mkfile
@@ -0,0 +1,2 @@
+FS='64x'
+<../portmkfile
diff --git a/sys/src/cmd/cwfs/iobuf.c b/sys/src/cmd/cwfs/iobuf.c
index 11879f37c..577cc7c38 100644
--- a/sys/src/cmd/cwfs/iobuf.c
+++ b/sys/src/cmd/cwfs/iobuf.c
@@ -204,21 +204,36 @@ int
checktag(Iobuf *p, int tag, Off qpath)
{
Tag *t;
- static Off lastaddr;
+ ulong pc;
+ qpath &= ~QPDIR;
t = (Tag*)(p->iobuf+BUFSIZE);
+ if((tag != t->tag) || ((qpath != QPNONE) && (qpath != t->path))){
+ pc = getcallerpc(&p);
+
+ if(qpath == QPNONE){
+ print("checktag pc=%lux %Z(%llux) tag/path=%G/%llud; expected %G\n",
+ pc, p->dev, (Wideoff)p->addr, t->tag, (Wideoff)t->path, tag);
+ } else {
+ print("checktag pc=%lux %Z(%llux) tag/path=%G/%llud; expected %G/%llud\n",
+ pc, p->dev, (Wideoff)p->addr, t->tag, (Wideoff)t->path, tag, qpath);
+ }
+ return 1;
+ }
+
+ /*
if(t->tag != tag) {
if(p->flags & Bmod) {
- print("\ttag = %d/%llud; expected %lld/%d -- not flushed\n",
+ print("\t%llux: tag = %G/%llud; expected %G/%d -- not flushed\n",
t->tag, (Wideoff)t->path, (Wideoff)qpath, tag);
return 2;
}
if(p->dev != nil && p->dev->type == Devcw)
cwfree(p->dev, p->addr);
if(p->addr != lastaddr)
- print("\ttag = %G/%llud; expected %G/%lld -- flushed (%lld)\n",
- t->tag, (Wideoff)t->path, tag, (Wideoff)qpath,
- (Wideoff)p->addr);
+ print("\t%llux: tag = %G/%llud; expected %G/%lld -- flushed\n",
+ (Wideoff)p->addr, t->tag, (Wideoff)t->path, tag, (Wideoff)qpath);
+
lastaddr = p->addr;
p->dev = devnone;
p->addr = -1;
@@ -226,13 +241,14 @@ checktag(Iobuf *p, int tag, Off qpath)
return 2;
}
if(qpath != QPNONE) {
- if((qpath ^ t->path) & ~QPDIR) {
- if(1 || CHAT(0))
- print("\ttag/path = %llud; expected %d/%llux\n",
- (Wideoff)t->path, tag, (Wideoff)qpath);
+ if(qpath ^ t->path) {
+ print("\t%llux: tag/path = %G/%llud; expected %G/%llux\n",
+ (Wideoff)p->addr, t->tag, (Wideoff)t->path, tag, (Wideoff)qpath);
return 0;
}
}
+ */
+
return 0;
}
diff --git a/sys/src/cmd/cwfs/main.c b/sys/src/cmd/cwfs/main.c
index d1422a1f9..b7654e505 100644
--- a/sys/src/cmd/cwfs/main.c
+++ b/sys/src/cmd/cwfs/main.c
@@ -7,6 +7,7 @@ extern int oldcachefmt;
Map *devmap;
+int sfd, rfd;
Biobuf bin;
void
@@ -148,6 +149,57 @@ confinit(void)
mapinit(conf.devmap);
}
+static int
+srvfd(char *s, int mode, int sfd)
+{
+ int fd;
+ char buf[32];
+
+ fd = create(s, ORCLOSE|OWRITE, mode);
+ if(fd < 0){
+ remove(s);
+ fd = create(s, ORCLOSE|OWRITE, mode);
+ if(fd < 0)
+ panic(s);
+ }
+ sprint(buf, "%d", sfd);
+ if(write(fd, buf, strlen(buf)) != strlen(buf))
+ panic("srv write");
+ return sfd;
+}
+
+static void
+postservice(void)
+{
+ char buf[3*NAMELEN];
+ int p[2];
+
+ if(sfd < 0){
+ if(pipe(p) < 0)
+ panic("can't make a pipe");
+ sfd = p[0];
+ rfd = p[1];
+ }
+
+ /* post 9p service */
+ snprint(buf, sizeof(buf), "#s/%s", service);
+ srvfd(buf, 0666, sfd);
+ close(sfd);
+ srvchan(rfd, buf);
+
+ if(pipe(p) < 0)
+ panic("can't make a pipe");
+
+ /* post cmd service */
+ snprint(buf, sizeof(buf), "#s/%s.cmd", service);
+ srvfd(buf, 0222, p[0]);
+ close(p[0]);
+
+ /* use it as stdin */
+ dup(p[1], 0);
+ close(p[1]);
+}
+
/*
* compute BUFSIZE*(NDBLOCK+INDPERBUF+INDPERBUF⁲+INDPERBUF⁳+INDPERBUF⁴)
* while watching for overflow; in that case, return 0.
@@ -224,8 +276,7 @@ printsizes(void)
void
usage(void)
{
- fprint(2, "usage: %s [-cf][-a ann-str][-m dev-map] config-dev\n",
- argv0);
+ fprint(2, "usage: %s [ -csC ] [ -a ann-str ] [ -m dev-map ] [-f config-dev ]\n", argv0);
exits("usage");
}
@@ -234,11 +285,13 @@ main(int argc, char **argv)
{
int i, nets = 0;
char *ann;
-
+
rfork(RFNOTEG);
formatinit();
machinit();
- conf.confdev = "n"; /* Devnone */
+ conf.confdev = "/dev/sdC0/cwfs";
+
+ rfd = sfd = -1;
ARGBEGIN{
case 'a': /* announce on this net */
@@ -250,12 +303,25 @@ main(int argc, char **argv)
}
annstrs[nets++] = ann;
break;
- case 'c': /* use new, faster cache layout */
+ case 's':
+ sfd = dup(0, -1);
+ rfd = dup(1, -1);
+ close(0);
+ if(open("/dev/cons", OREAD) < 0)
+ open("#c/cons", OREAD);
+ close(1);
+ if(open("/dev/cons", OWRITE) < 0)
+ open("#c/cons", OWRITE);
+ break;
+ case 'C': /* use new, faster cache layout */
oldcachefmt = 0;
break;
- case 'f': /* enter configuration mode first */
+ case 'c':
conf.configfirst++;
break;
+ case 'f': /* device / partition / file */
+ conf.confdev = EARGF(usage());
+ break;
case 'm': /* name device-map file */
conf.devmap = EARGF(usage());
break;
@@ -264,9 +330,8 @@ main(int argc, char **argv)
break;
}ARGEND
- if (argc != 1)
+ if(argc != 0)
usage();
- conf.confdev = argv[0]; /* config string for dev holding full config */
Binit(&bin, 0, OREAD);
confinit();
@@ -304,6 +369,13 @@ main(int argc, char **argv)
print("sysinit\n");
sysinit();
+ srvinit();
+
+ /*
+ * post filedescriptors to /srv
+ */
+ postservice();
+
/*
* Ethernet i/o processes
*/
@@ -326,16 +398,14 @@ main(int argc, char **argv)
newproc(wormcopy, 0, "wcp");
/*
- * processes to read the console
+ * "sync" copy process
*/
- consserve();
+ newproc(synccopy, 0, "scp");
/*
- * "sync" copy process
- * this doesn't return.
+ * processes to read the console
*/
- procsetname("scp");
- synccopy();
+ consserve();
}
/*
@@ -541,7 +611,7 @@ wormcopy(void *)
* to get up-to-date.
*/
void
-synccopy(void)
+synccopy(void *)
{
int f;
@@ -584,3 +654,4 @@ inqsize(char *file)
free(data);
return rv;
}
+
diff --git a/sys/src/cmd/cwfs/mkfile b/sys/src/cmd/cwfs/mkfile
index 6ff9c0126..19d826980 100644
--- a/sys/src/cmd/cwfs/mkfile
+++ b/sys/src/cmd/cwfs/mkfile
@@ -2,9 +2,14 @@ default:V: all
all allall first default clean nuke install installall safeinstall safeinstallall update man:V:
cd cwfs && mk $target
+
emelie.%:V:
cd emelie && mk $stem
fs64.%:V:
cd fs64 && mk $stem
+cwfs64.%:V:
+ cd cwfs64 && mk $stem
+cwfs64x.%:V:
+ cd cwfs64x && mk $stem
-cleanall:V: clean emelie.clean fs64.clean
+cleanall:V: clean emelie.clean fs64.clean cwfs64.clean cwfs64x.clean
diff --git a/sys/src/cmd/cwfs/net.c b/sys/src/cmd/cwfs/net.c
index 97553be6a..b2f2b7272 100644
--- a/sys/src/cmd/cwfs/net.c
+++ b/sys/src/cmd/cwfs/net.c
@@ -2,16 +2,6 @@
#include "all.h"
#include "io.h"
-#include <fcall.h> /* 9p2000 */
-#include <thread.h>
-
-enum {
- Maxfdata = 8192,
- Nqueue = 200, /* queue size (tunable) */
-
- Netclosed = 0, /* Connection state */
- Netopen,
-};
/*
* the kernel file server read packets directly from
@@ -40,14 +30,11 @@ enum {
*/
typedef struct Network Network;
-typedef struct Netconn Netconn;
-typedef struct Conn9p Conn9p;
/* a network, not necessarily an ethernet */
struct Network {
int ctlrno;
- char iname[NAMELEN];
- char oname[NAMELEN];
+ char name[NAMELEN];
char *dialstr;
char anndir[40];
@@ -55,295 +42,18 @@ struct Network {
int annfd; /* fd from announce */
};
-/* an open tcp (or other transport) connection */
-struct Netconn {
- Queue* reply; /* network output */
- char* raddr; /* remote caller's addr */
- Chan* chan; /* list of tcp channels */
-
- int alloc; /* flag: allocated */
-
- int state;
- Conn9p* conn9p; /* not reference-counted */
-
- Lock;
-};
-
-/*
- * incoming 9P network connection from a given machine.
- * typically will multiplex 9P sessions for multiple users.
- */
-struct Conn9p {
- QLock;
- Ref;
- int fd;
- char* dir;
- Netconn*netconn; /* cross-connection */
- char* raddr;
-};
-
static Network netif[Maxnets];
-static struct {
- Lock;
- Chan* chan;
-} netchans;
-static Queue *netoq; /* only one network output queue is needed */
char *annstrs[Maxnets] = {
"tcp!*!9fs",
};
-/* never returns nil */
-static Chan*
-getchan(Conn9p *conn9p)
-{
- Netconn *netconn;
- Chan *cp, *xcp;
-
- lock(&netchans);
-
- /* look for conn9p's Chan */
- xcp = nil;
- for(cp = netchans.chan; cp; cp = netconn->chan) {
- netconn = cp->pdata;
- if(!netconn->alloc)
- xcp = cp; /* remember free Chan */
- else if(netconn->raddr != nil &&
- strcmp(conn9p->raddr, netconn->raddr) == 0) {
- unlock(&netchans);
- return cp; /* found conn9p's Chan */
- }
- }
-
- /* conn9p's Chan not found; if no free Chan, allocate & fill in one */
- cp = xcp;
- if(cp == nil) {
- cp = fs_chaninit(Devnet, 1, sizeof(Netconn));
- netconn = cp->pdata;
- netconn->chan = netchans.chan;
- netconn->state = Netopen; /* a guess */
- /* cross-connect netconn and conn9p */
- netconn->conn9p = conn9p; /* not reference-counted */
- conn9p->netconn = netconn;
- netchans.chan = cp;
- }
-
- /* fill in Chan's netconn */
- netconn = cp->pdata;
- netconn->raddr = strdup(conn9p->raddr);
-
- /* fill in Chan */
- cp->send = serveq;
- if (cp->reply == nil)
- cp->reply = netoq;
- netconn->reply = netoq;
- cp->protocol = nil;
- cp->msize = 0;
- cp->whotime = 0;
- strncpy(cp->whochan, conn9p->raddr, sizeof cp->whochan);
-// cp->whoprint = tcpwhoprint;
- netconn->alloc = 1;
-
- unlock(&netchans);
- return cp;
-}
-
-static char *
-fd2name(int fd)
-{
- char data[128];
-
- if (fd2path(fd, data, sizeof data) < 0)
- return strdup("/GOK");
- return strdup(data);
-}
-
-static void
-hangupdfd(int dfd)
-{
- int ctlfd;
- char *end, *data;
-
- data = fd2name(dfd);
- close(dfd);
-
- end = strstr(data, "/data");
- if (end != nil)
- strcpy(end, "/ctl");
- ctlfd = open(data, OWRITE);
- if (ctlfd >= 0) {
- hangup(ctlfd);
- close(ctlfd);
- }
- free(data);
-}
-
-void
-closechan(int n)
-{
- Chan *cp;
-
- for(cp = chans; cp; cp = cp->next)
- if(cp->whotime != 0 && cp->chan == n)
- fileinit(cp);
-}
-
-void
-nethangup(Chan *cp, char *msg, int dolock)
-{
- Netconn *netconn;
-
- netconn = cp->pdata;
- netconn->state = Netclosed;
-
- if(msg != nil)
- print("hangup! %s %s\n", msg, netconn->raddr);
-
- fileinit(cp);
- cp->whotime = 0;
- strcpy(cp->whoname, "<none>");
-
- if(dolock)
- lock(&netchans);
- netconn->alloc = 0;
- free(netconn->raddr);
- netconn->raddr = nil;
- if(dolock)
- unlock(&netchans);
-}
-
-void
-chanhangup(Chan *cp, char *msg, int dolock)
-{
- Netconn *netconn = cp->pdata;
- Conn9p *conn9p = netconn->conn9p;
-
- if (conn9p->fd > 0)
- hangupdfd(conn9p->fd); /* drop it */
- nethangup(cp, msg, dolock);
-}
-
-/*
- * returns length of next 9p message (including the length) and
- * leaves it in the first few bytes of abuf.
- */
-static long
-size9pmsg(int fd, void *abuf, uint n)
-{
- int m;
- uchar *buf = abuf;
-
- if (n < BIT32SZ)
- return -1; /* caller screwed up */
-
- /* read count */
- m = readn(fd, buf, BIT32SZ);
- if(m != BIT32SZ){
- if(m < 0)
- return -1;
- return 0;
- }
- return GBIT32(buf);
-}
-
-static int
-readalloc9pmsg(int fd, Msgbuf **mbp)
-{
- int m, len;
- uchar lenbuf[BIT32SZ];
- Msgbuf *mb;
-
- *mbp = nil;
- len = size9pmsg(fd, lenbuf, BIT32SZ);
- if (len <= 0)
- return len;
- if(len <= BIT32SZ || len > IOHDRSZ+Maxfdata){
- werrstr("bad length in 9P2000 message header");
- return -1;
- }
- if ((mb = mballoc(len, nil, Mbeth1)) == nil)
- panic("readalloc9pmsg: mballoc failed");
- *mbp = mb;
- memmove(mb->data, lenbuf, BIT32SZ);
- len -= BIT32SZ;
- m = readn(fd, mb->data+BIT32SZ, len);
- if(m < len)
- return 0;
- return BIT32SZ+m;
-}
-
-static void
-connection(void *v)
-{
- int n;
- char buf[64];
- Chan *chan9p;
- Conn9p *conn9p = v;
- Msgbuf *mb;
- NetConnInfo *nci;
-
- incref(conn9p); /* count connections */
- nci = getnetconninfo(conn9p->dir, conn9p->fd);
- if (nci == nil)
- panic("connection: getnetconninfo(%s, %d) failed",
- conn9p->dir, conn9p->fd);
- conn9p->raddr = nci->raddr;
-
- chan9p = getchan(conn9p);
- print("new connection on %s pid %d from %s\n",
- conn9p->dir, getpid(), conn9p->raddr);
-
- /*
- * reading from a pipe or a network device
- * will give an error after a few eof reads.
- * however, we cannot tell the difference
- * between a zero-length read and an interrupt
- * on the processes writing to us,
- * so we wait for the error.
- */
- while (conn9p->fd > 0 && (n = readalloc9pmsg(conn9p->fd, &mb)) >= 0) {
- if(n == 0)
- continue;
- mb->param = (uintptr)conn9p; /* has fd for replies */
- mb->chan = chan9p;
-
- assert(mb->magic == Mbmagic);
- incref(conn9p); /* & count packets in flight */
- fs_send(serveq, mb); /* to 9P server processes */
- /* mb will be freed by receiving process */
- }
-
- rerrstr(buf, sizeof buf);
-
- qlock(conn9p);
- print("connection hung up from %s\n", conn9p->dir);
- if (conn9p->fd > 0) /* not poisoned yet? */
- hangupdfd(conn9p->fd); /* poison the fd */
-
- nethangup(chan9p, "remote hung up", 1);
- closechan(chan9p->chan);
-
- conn9p->fd = -1; /* poison conn9p */
- if (decref(conn9p) == 0) { /* last conn.? turn the lights off */
- free(conn9p->dir);
- qunlock(conn9p);
- free(conn9p);
- } else
- qunlock(conn9p);
-
- freenetconninfo(nci);
-
- if(buf[0] == '\0' || strstr(buf, "hungup") != nil)
- exits("");
- sysfatal("mount read, pid %d", getpid());
-}
-
static void
neti(void *v)
{
int lisfd, accfd;
Network *net;
- Conn9p *conn9p;
+ NetConnInfo *nci;
net = v;
print("net%di\n", net->ctlrno);
@@ -362,77 +72,23 @@ neti(void *v)
continue;
}
- /* accepted that call */
- conn9p = malloc(sizeof *conn9p);
- conn9p->dir = strdup(net->lisdir);
- conn9p->fd = accfd;
- newproc(connection, conn9p, smprint("9P read %s", conn9p->dir));
+ nci = getnetconninfo(net->lisdir, accfd);
+ srvchan(accfd, nci->raddr);
+ freenetconninfo(nci);
close(lisfd);
}
}
-/* only need one of these for all network connections, thus all interfaces */
-static void
-neto(void *)
-{
- int len, datafd;
- Msgbuf *mb;
- Conn9p *conn9p;
-
- print("neto\n");
- for(;;) {
- /* receive 9P answer from 9P server processes */
- while((mb = fs_recv(netoq, 0)) == nil)
- continue;
-
- if(mb->data == nil) {
- print("neto: pkt nil cat=%d free=%d\n",
- mb->category, mb->flags&FREE);
- if(!(mb->flags & FREE))
- mbfree(mb);
- continue;
- }
-
- /* send answer back over the network connection in the reply */
- len = mb->count;
- conn9p = (Conn9p *)mb->param;
- assert(conn9p);
-
- qlock(conn9p);
- datafd = conn9p->fd;
- assert(len >= 0);
- /* datafd < 0 probably indicates poisoning by the read side */
- if (datafd < 0 || write(datafd, mb->data, len) != len) {
- print( "network write error (%r);");
- print(" closing connection for %s\n", conn9p->dir);
- nethangup(getchan(conn9p), "network write error", 1);
- if (datafd > 0)
- hangupdfd(datafd); /* drop it */
- conn9p->fd = -1; /* poison conn9p */
- }
- mbfree(mb);
- if (decref(conn9p) == 0)
- panic("neto: zero ref count");
- qunlock(conn9p);
- }
-}
-
void
netstart(void)
{
- int netorun = 0;
Network *net;
- if(netoq == nil)
- netoq = newqueue(Nqueue, "network reply");
for(net = &netif[0]; net < &netif[Maxnets]; net++){
if(net->dialstr == nil)
continue;
- sprint(net->oname, "neto");
- if (netorun++ == 0)
- newproc(neto, nil, net->oname);
- sprint(net->iname, "net%di", net->ctlrno);
- newproc(neti, net, net->iname);
+ sprint(net->name, "net%di", net->ctlrno);
+ newproc(neti, net, net->name);
}
}
diff --git a/sys/src/cmd/cwfs/pc.c b/sys/src/cmd/cwfs/pc.c
index a4aed8530..ea817c8f7 100644
--- a/sys/src/cmd/cwfs/pc.c
+++ b/sys/src/cmd/cwfs/pc.c
@@ -33,7 +33,7 @@ mconfinit(void)
}
Bterm(bp);
if (pgsize > 0 && userpgs > 0)
- size = (((userpgs - userused)*3LL)/4)*pgsize;
+ size = (((userpgs - userused)*1LL)/4)*pgsize;
}
mconf.memsize = size;
mbp = mconf.bank;
diff --git a/sys/src/cmd/cwfs/portdat.h b/sys/src/cmd/cwfs/portdat.h
index d01be6fea..a2e96b157 100644
--- a/sys/src/cmd/cwfs/portdat.h
+++ b/sys/src/cmd/cwfs/portdat.h
@@ -699,6 +699,7 @@ enum
Devfloppy, /* floppy drive */
Devswab, /* swab data between mem and device */
Devmirr, /* mirror devices */
+ Devsrv, /* pipes and network connections */
MAXDEV
};
diff --git a/sys/src/cmd/cwfs/portfns.h b/sys/src/cmd/cwfs/portfns.h
index e1810d869..3a2d70ac5 100644
--- a/sys/src/cmd/cwfs/portfns.h
+++ b/sys/src/cmd/cwfs/portfns.h
@@ -197,6 +197,7 @@ void schedinit(void);
int scsiio(Device*, int, uchar*, int, void*, int);
void scsiinit(void);
Off scsiread(int, void*, long);
+Devsize scsiseek(int, Devsize);
Off scsiwrite(int, void*, long);
char* sdof(Device*);
void sec2rtc(Timet, Rtc *);
@@ -229,7 +230,7 @@ void unlock(Lock*);
void newproc(void(*)(void *), void*, char*);
void wormcopy(void *);
void wormprobe(void);
-void synccopy(void);
+void synccopy(void *);
long wormsearch(Device*, int, long, long);
int wormread(Device*, Off, void*);
Devsize wormsize(Device*);
@@ -243,3 +244,6 @@ int wrenwrite(Device*, Off, void*);
void cmd_exec(char*);
void cmd_install(char*, char*, void (*)(int, char*[]));
ulong flag_install(char*, char*);
+void srvinit(void);
+Chan *srvchan(int, char *);
+
diff --git a/sys/src/cmd/cwfs/portmkfile b/sys/src/cmd/cwfs/portmkfile
index be276aca7..0bc734183 100644
--- a/sys/src/cmd/cwfs/portmkfile
+++ b/sys/src/cmd/cwfs/portmkfile
@@ -27,10 +27,12 @@ OFILES=\
time.$O\
uidgid.$O\
wren.$O\
+ srv.$O\
HFILES=\
../32bit.h\
../64bit.h\
+ ../64xbit.h\
../9p1.h\
../all.h\
dat.h\
diff --git a/sys/src/cmd/cwfs/srv.c b/sys/src/cmd/cwfs/srv.c
new file mode 100644
index 000000000..0cfafbb41
--- /dev/null
+++ b/sys/src/cmd/cwfs/srv.c
@@ -0,0 +1,209 @@
+#include "all.h"
+#include "io.h"
+#include <fcall.h> /* 9p2000 */
+#include <thread.h>
+
+enum {
+ Maxfdata = 8192,
+ Nqueue = 200, /* queue size (tunable) */
+ Nsrvo = 8, /* number of write workers */
+};
+
+typedef struct Srv Srv;
+struct Srv
+{
+ Ref;
+ char *name;
+ Chan *chan;
+ int fd;
+ char buf[64];
+};
+
+static struct {
+ Lock;
+ Chan *hd;
+} freechans;
+
+static Queue *srvoq;
+
+void
+chanhangup(Chan *chan, char *msg, int dolock)
+{
+ Srv *srv;
+
+ USED(dolock);
+ USED(msg);
+
+ fileinit(chan);
+ if(chan->type != Devsrv)
+ return;
+ srv = chan->pdata;
+ if(srv == nil || srv->chan != chan)
+ return;
+ close(srv->fd);
+ srv->fd = -1;
+}
+
+static void
+srvput(Srv *srv)
+{
+ Chan *chan;
+
+ if(decref(srv))
+ return;
+
+ print("%s closed\n", srv->name);
+
+ chanhangup(srv->chan, "", 0);
+ memset(srv->buf, 0, sizeof(srv->buf));
+ chan = srv->chan;
+ lock(&freechans);
+ srv->chan = freechans.hd;
+ freechans.hd = chan;
+ unlock(&freechans);
+}
+
+static void
+srvo(void *)
+{
+ Srv *srv;
+ Msgbuf *mb;
+ char buf[ERRMAX];
+
+ print("srvo\n");
+
+ for(;;){
+ mb = fs_recv(srvoq, 0);
+ if(mb == nil)
+ continue;
+ if(mb->data == nil){
+ if(!(mb->flags & FREE))
+ mbfree(mb);
+ continue;
+ }
+ srv = (Srv*)mb->param;
+ while((srv->fd >= 0) && (write(srv->fd, mb->data, mb->count) != mb->count)){
+ rerrstr(buf, sizeof(buf));
+ if(strstr(buf, "interrupt"))
+ continue;
+
+ if(buf[0])
+ print("srvo %s: %s\n", srv->name, buf);
+ chanhangup(srv->chan, buf, 0);
+ break;
+ }
+ mbfree(mb);
+ srvput(srv);
+ }
+}
+
+static void
+srvi(void *aux)
+{
+ Srv *srv = aux;
+ Msgbuf *mb, *ms;
+ uchar *b, *p, *e;
+ int n, m;
+ char buf[ERRMAX];
+
+ print("srvi %s\n", srv->name);
+
+ if((mb = mballoc(IOHDRSZ+Maxfdata, srv->chan, Mbeth1)) == nil)
+ panic("srvi %s: mballoc failed", srv->name);
+ b = mb->data;
+ p = b;
+ e = b + mb->count;
+
+Read:
+ while((srv->fd >= 0) && ((n = read(srv->fd, p, e - p)) >= 0)){
+ p += n;
+ while((p - b) >= BIT32SZ){
+ m = GBIT32(b);
+ if((m < BIT32SZ) || (m > mb->count)){
+ werrstr("bad length in 9P2000 message header");
+ goto Error;
+ }
+ if((n = (p - b) - m) < 0){
+ e = b + m;
+ goto Read;
+ }
+ if(m <= SMALLBUF){
+ if((ms = mballoc(m, srv->chan, Mbeth1)) == nil)
+ panic("srvi %s: mballoc failed", srv->name);
+ memmove(ms->data, b, m);
+ } else {
+ ms = mb;
+ if((mb = mballoc(mb->count, srv->chan, Mbeth1)) == nil)
+ panic("srvi %s: mballoc failed", srv->name);
+ ms->count = m;
+ }
+ if(n > 0)
+ memmove(mb->data, b + m, n);
+ b = mb->data;
+ p = b + n;
+
+ incref(srv);
+ ms->param = (uint)srv;
+ fs_send(serveq, ms);
+ }
+ e = b + mb->count;
+ }
+
+Error:
+ rerrstr(buf, sizeof(buf));
+ if(strstr(buf, "interrupt"))
+ goto Read;
+
+ if(buf[0])
+ print("srvi %s: %s\n", srv->name, buf);
+ chanhangup(srv->chan, buf, 0);
+ srvput(srv);
+
+ mbfree(mb);
+}
+
+Chan*
+srvchan(int fd, char *name)
+{
+ Chan *chan;
+ Srv *srv;
+
+ lock(&freechans);
+ if(chan = freechans.hd){
+ srv = chan->pdata;
+ freechans.hd = srv->chan;
+ unlock(&freechans);
+ } else {
+ unlock(&freechans);
+ chan = fs_chaninit(Devsrv, 1, sizeof(*srv));
+ srv = chan->pdata;
+ }
+ chan->reply = srvoq;
+ if(chan->send == nil)
+ chan->send = serveq;
+ chan->protocol = nil;
+ chan->msize = 0;
+ chan->whotime = 0;
+
+ incref(srv);
+ srv->chan = chan;
+ srv->fd = fd;
+ snprint(srv->buf, sizeof(srv->buf), "srvi %s", name);
+ srv->name = strchr(srv->buf, ' ')+1;
+ newproc(srvi, srv, srv->buf);
+
+ return chan;
+}
+
+void
+srvinit(void)
+{
+ int i;
+
+ if(srvoq != nil)
+ return;
+
+ srvoq = newqueue(Nqueue, "srvoq");
+ for(i=0; i<Nsrvo; i++)
+ newproc(srvo, nil, "srvo");
+}
diff --git a/sys/src/cmd/cwfs/sub.c b/sys/src/cmd/cwfs/sub.c
index 44f985757..bca9e5264 100644
--- a/sys/src/cmd/cwfs/sub.c
+++ b/sys/src/cmd/cwfs/sub.c
@@ -614,7 +614,9 @@ Zfmt(Fmt* fmt)
case Devlworm:
if (c == '\0')
c = 'l';
- if(d->wren.ctrl == 0 && d->wren.lun == 0)
+ if(d->wren.file)
+ snprint(s, sizeof(s), "%c\"%s\"", c, d->wren.file);
+ else if(d->wren.ctrl == 0 && d->wren.lun == 0)
sprint(s, "%c%d", c, d->wren.targ);
else
sprint(s, "%c%d.%d.%d", c, d->wren.ctrl, d->wren.targ,
diff --git a/sys/src/cmd/cwfs/wren.c b/sys/src/cmd/cwfs/wren.c
index 5f67706bc..9b8f09c8b 100644
--- a/sys/src/cmd/cwfs/wren.c
+++ b/sys/src/cmd/cwfs/wren.c
@@ -116,5 +116,6 @@ wrenwrite(Device *d, Off b, void *c)
cons.nwrenwe++;
r = 1;
}
+
return r;
}