summaryrefslogtreecommitdiff
path: root/sys/src/cmd/unix/drawterm/exportfs
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2013-11-23 01:05:33 +0100
committercinap_lenrek <cinap_lenrek@felloff.net>2013-11-23 01:05:33 +0100
commit2f9ae0f8ac8610e13ced184847b57b87fe5db580 (patch)
treef9ad2223d518585a2cfe9ea1c73e1e37d07bf637 /sys/src/cmd/unix/drawterm/exportfs
parentea5797c0731203c09ec5fb7172e77eab2750f1a9 (diff)
removing (outdated) drawterm
drawterm is much better maintained by russ cox, so removing this outdated copy. for a more recent version, go to: http://swtch.com/drawterm/
Diffstat (limited to 'sys/src/cmd/unix/drawterm/exportfs')
-rw-r--r--sys/src/cmd/unix/drawterm/exportfs/Makefile16
-rw-r--r--sys/src/cmd/unix/drawterm/exportfs/exportfs.c511
-rw-r--r--sys/src/cmd/unix/drawterm/exportfs/exportfs.h148
-rw-r--r--sys/src/cmd/unix/drawterm/exportfs/exportsrv.c676
4 files changed, 0 insertions, 1351 deletions
diff --git a/sys/src/cmd/unix/drawterm/exportfs/Makefile b/sys/src/cmd/unix/drawterm/exportfs/Makefile
deleted file mode 100644
index e66d8778d..000000000
--- a/sys/src/cmd/unix/drawterm/exportfs/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-ROOT=..
-include ../Make.config
-LIB=libexportfs.a
-
-OFILES=\
- exportfs.$O\
- exportsrv.$O
-
-default: $(LIB)
-$(LIB): $(OFILES)
- $(AR) r $(LIB) $(OFILES)
- $(RANLIB) $(LIB)
-
-%.$O: %.c
- $(CC) $(CFLAGS) $*.c
-
diff --git a/sys/src/cmd/unix/drawterm/exportfs/exportfs.c b/sys/src/cmd/unix/drawterm/exportfs/exportfs.c
deleted file mode 100644
index 568cdbea1..000000000
--- a/sys/src/cmd/unix/drawterm/exportfs/exportfs.c
+++ /dev/null
@@ -1,511 +0,0 @@
-/*
- * exportfs - Export a plan 9 name space across a network
- */
-#include <u.h>
-#include <libc.h>
-#include <fcall.h>
-#include <libsec.h>
-#include "drawterm.h"
-#define Extern
-#include "exportfs.h"
-
-/* #define QIDPATH ((1LL<<48)-1) */
-#define QIDPATH ((((vlong)1)<<48)-1)
-vlong newqid = 0;
-
-void (*fcalls[256])(Fsrpc*);
-
-/* accounting and debugging counters */
-int filecnt;
-int freecnt;
-int qidcnt;
-int qfreecnt;
-int ncollision;
-int netfd;
-
-int
-exportfs(int fd, int msgsz)
-{
- char buf[ERRMAX], ebuf[ERRMAX];
- Fsrpc *r;
- int i, n;
-
- fcalls[Tversion] = Xversion;
- fcalls[Tauth] = Xauth;
- fcalls[Tflush] = Xflush;
- fcalls[Tattach] = Xattach;
- fcalls[Twalk] = Xwalk;
- fcalls[Topen] = slave;
- fcalls[Tcreate] = Xcreate;
- fcalls[Tclunk] = Xclunk;
- fcalls[Tread] = slave;
- fcalls[Twrite] = slave;
- fcalls[Tremove] = Xremove;
- fcalls[Tstat] = Xstat;
- fcalls[Twstat] = Xwstat;
-
- srvfd = -1;
- netfd = fd;
- //dbg = 1;
-
- strcpy(buf, "this is buf");
- strcpy(ebuf, "this is ebuf");
- DEBUG(DFD, "exportfs: started\n");
-
-// rfork(RFNOTEG);
-
- messagesize = msgsz;
- if(messagesize == 0){
- messagesize = iounit(netfd);
- if(messagesize == 0)
- messagesize = 8192+IOHDRSZ;
- }
-
- Workq = emallocz(sizeof(Fsrpc)*Nr_workbufs);
-// for(i=0; i<Nr_workbufs; i++)
-// Workq[i].buf = emallocz(messagesize);
- fhash = emallocz(sizeof(Fid*)*FHASHSIZE);
-
- fmtinstall('F', fcallfmt);
-
- initroot();
-
- DEBUG(DFD, "exportfs: %s\n", buf);
-
- /*
- * Start serving file requests from the network
- */
- for(;;) {
- r = getsbuf();
- if(r == 0)
- fatal("Out of service buffers");
-
- DEBUG(DFD, "read9p...");
- n = read9pmsg(netfd, r->buf, messagesize);
- if(n <= 0)
- fatal("eof: n=%d %r", n);
-
- if(convM2S(r->buf, n, &r->work) == 0){
- iprint("convM2S %d byte message\n", n);
- for(i=0; i<n; i++){
- iprint(" %.2ux", r->buf[i]);
- if(i%16 == 15)
- iprint("\n");
- }
- if(i%16)
- iprint("\n");
- fatal("convM2S format error");
- }
-
-if(0) iprint("<- %F\n", &r->work);
- DEBUG(DFD, "%F\n", &r->work);
- (fcalls[r->work.type])(r);
- }
-}
-
-void
-reply(Fcall *r, Fcall *t, char *err)
-{
- uchar *data;
- int m, n;
-
- t->tag = r->tag;
- t->fid = r->fid;
- if(err) {
- t->type = Rerror;
- t->ename = err;
- }
- else
- t->type = r->type + 1;
-
-if(0) iprint("-> %F\n", t);
- DEBUG(DFD, "\t%F\n", t);
-
- data = malloc(messagesize); /* not mallocz; no need to clear */
- if(data == nil)
- fatal(Enomem);
- n = convS2M(t, data, messagesize);
- if((m=write(netfd, data, n))!=n){
- iprint("wrote %d got %d (%r)\n", n, m);
- fatal("write");
- }
- free(data);
-}
-
-Fid *
-getfid(int nr)
-{
- Fid *f;
-
- for(f = fidhash(nr); f; f = f->next)
- if(f->nr == nr)
- return f;
-
- return 0;
-}
-
-int
-freefid(int nr)
-{
- Fid *f, **l;
- char buf[128];
-
- l = &fidhash(nr);
- for(f = *l; f; f = f->next) {
- if(f->nr == nr) {
- if(f->mid) {
- sprint(buf, "/mnt/exportfs/%d", f->mid);
- unmount(0, buf);
- psmap[f->mid] = 0;
- }
- if(f->f) {
- freefile(f->f);
- f->f = nil;
- }
- *l = f->next;
- f->next = fidfree;
- fidfree = f;
- return 1;
- }
- l = &f->next;
- }
-
- return 0;
-}
-
-Fid *
-newfid(int nr)
-{
- Fid *new, **l;
- int i;
-
- l = &fidhash(nr);
- for(new = *l; new; new = new->next)
- if(new->nr == nr)
- return 0;
-
- if(fidfree == 0) {
- fidfree = emallocz(sizeof(Fid) * Fidchunk);
-
- for(i = 0; i < Fidchunk-1; i++)
- fidfree[i].next = &fidfree[i+1];
-
- fidfree[Fidchunk-1].next = 0;
- }
-
- new = fidfree;
- fidfree = new->next;
-
- memset(new, 0, sizeof(Fid));
- new->next = *l;
- *l = new;
- new->nr = nr;
- new->fid = -1;
- new->mid = 0;
-
- return new;
-}
-
-Fsrpc *
-getsbuf(void)
-{
- static int ap;
- int look, rounds;
- Fsrpc *wb;
- int small_instead_of_fast = 1;
-
- if(small_instead_of_fast)
- ap = 0; /* so we always start looking at the beginning and reuse buffers */
-
- for(rounds = 0; rounds < 10; rounds++) {
- for(look = 0; look < Nr_workbufs; look++) {
- if(++ap == Nr_workbufs)
- ap = 0;
- if(Workq[ap].busy == 0)
- break;
- }
-
- if(look == Nr_workbufs){
- sleep(10 * rounds);
- continue;
- }
-
- wb = &Workq[ap];
- wb->pid = 0;
- wb->canint = 0;
- wb->flushtag = NOTAG;
- wb->busy = 1;
- if(wb->buf == nil) /* allocate buffers dynamically to keep size down */
- wb->buf = emallocz(messagesize);
- return wb;
- }
- fatal("No more work buffers");
- return nil;
-}
-
-void
-freefile(File *f)
-{
- File *parent, *child;
-
-Loop:
- f->ref--;
- if(f->ref > 0)
- return;
- freecnt++;
- if(f->ref < 0) abort();
- DEBUG(DFD, "free %s\n", f->name);
- /* delete from parent */
- parent = f->parent;
- if(parent->child == f)
- parent->child = f->childlist;
- else{
- for(child=parent->child; child->childlist!=f; child=child->childlist)
- if(child->childlist == nil)
- fatal("bad child list");
- child->childlist = f->childlist;
- }
- freeqid(f->qidt);
- free(f->name);
- f->name = nil;
- free(f);
- f = parent;
- if(f != nil)
- goto Loop;
-}
-
-File *
-file(File *parent, char *name)
-{
- Dir *dir;
- char *path;
- File *f;
-
- DEBUG(DFD, "\tfile: 0x%p %s name %s\n", parent, parent->name, name);
-
- path = makepath(parent, name);
- dir = dirstat(path);
- free(path);
- if(dir == nil)
- return nil;
-
- for(f = parent->child; f; f = f->childlist)
- if(strcmp(name, f->name) == 0)
- break;
-
- if(f == nil){
- f = emallocz(sizeof(File));
- f->name = estrdup(name);
-
- f->parent = parent;
- f->childlist = parent->child;
- parent->child = f;
- parent->ref++;
- f->ref = 0;
- filecnt++;
- }
- f->ref++;
- f->qid.type = dir->qid.type;
- f->qid.vers = dir->qid.vers;
- f->qidt = uniqueqid(dir);
- f->qid.path = f->qidt->uniqpath;
-
- f->inval = 0;
-
- free(dir);
-
- return f;
-}
-
-void
-initroot(void)
-{
- Dir *dir;
-
- root = emallocz(sizeof(File));
- root->name = estrdup(".");
-
- dir = dirstat(root->name);
- if(dir == nil)
- fatal("root stat");
-
- root->ref = 1;
- root->qid.vers = dir->qid.vers;
- root->qidt = uniqueqid(dir);
- root->qid.path = root->qidt->uniqpath;
- root->qid.type = QTDIR;
- free(dir);
-
- psmpt = emallocz(sizeof(File));
- psmpt->name = estrdup("/");
-
- dir = dirstat(psmpt->name);
- if(dir == nil)
- return;
-
- psmpt->ref = 1;
- psmpt->qid.vers = dir->qid.vers;
- psmpt->qidt = uniqueqid(dir);
- psmpt->qid.path = psmpt->qidt->uniqpath;
- free(dir);
-
- psmpt = file(psmpt, "mnt");
- if(psmpt == 0)
- return;
- psmpt = file(psmpt, "exportfs");
-}
-
-char*
-makepath(File *p, char *name)
-{
- int i, n;
- char *c, *s, *path, *seg[256];
-
- seg[0] = name;
- n = strlen(name)+2;
- for(i = 1; i < 256 && p; i++, p = p->parent){
- seg[i] = p->name;
- n += strlen(p->name)+1;
- }
- path = malloc(n);
- if(path == nil)
- fatal("out of memory");
- s = path;
-
- while(i--) {
- for(c = seg[i]; *c; c++)
- *s++ = *c;
- *s++ = '/';
- }
- while(s[-1] == '/')
- s--;
- *s = '\0';
-
- return path;
-}
-
-int
-qidhash(vlong path)
-{
- int h, n;
-
- h = 0;
- for(n=0; n<64; n+=Nqidbits){
- h ^= path;
- path >>= Nqidbits;
- }
- return h & (Nqidtab-1);
-}
-
-void
-freeqid(Qidtab *q)
-{
- ulong h;
- Qidtab *l;
-
- q->ref--;
- if(q->ref > 0)
- return;
- qfreecnt++;
- h = qidhash(q->path);
- if(qidtab[h] == q)
- qidtab[h] = q->next;
- else{
- for(l=qidtab[h]; l->next!=q; l=l->next)
- if(l->next == nil)
- fatal("bad qid list");
- l->next = q->next;
- }
- free(q);
-}
-
-Qidtab*
-qidlookup(Dir *d)
-{
- ulong h;
- Qidtab *q;
-
- h = qidhash(d->qid.path);
- for(q=qidtab[h]; q!=nil; q=q->next)
- if(q->type==d->type && q->dev==d->dev && q->path==d->qid.path)
- return q;
- return nil;
-}
-
-int
-qidexists(vlong path)
-{
- int h;
- Qidtab *q;
-
- for(h=0; h<Nqidtab; h++)
- for(q=qidtab[h]; q!=nil; q=q->next)
- if(q->uniqpath == path)
- return 1;
- return 0;
-}
-
-Qidtab*
-uniqueqid(Dir *d)
-{
- ulong h;
- vlong path;
- Qidtab *q;
-
- q = qidlookup(d);
- if(q != nil){
- q->ref++;
- return q;
- }
- path = d->qid.path;
- while(qidexists(path)){
- DEBUG(DFD, "collision on %s\n", d->name);
- /* collision: find a new one */
- ncollision++;
- path &= QIDPATH;
- ++newqid;
- if(newqid >= (1<<16)){
- DEBUG(DFD, "collision wraparound\n");
- newqid = 1;
- }
- path |= newqid<<48;
- DEBUG(DFD, "assign qid %.16llux\n", path);
- }
- q = mallocz(sizeof(Qidtab), 1);
- if(q == nil)
- fatal("no memory for qid table");
- qidcnt++;
- q->ref = 1;
- q->type = d->type;
- q->dev = d->dev;
- q->path = d->qid.path;
- q->uniqpath = path;
- h = qidhash(d->qid.path);
- q->next = qidtab[h];
- qidtab[h] = q;
- return q;
-}
-
-void
-fatal(char *s, ...)
-{
- char buf[ERRMAX];
- va_list arg;
-
- if (s) {
- va_start(arg, s);
- vsnprint(buf, ERRMAX, s, arg);
- va_end(arg);
- }
-
- /* Clear away the slave children */
-// for(m = Proclist; m; m = m->next)
-// postnote(PNPROC, m->pid, "kill");
-
- DEBUG(DFD, "%s\n", buf);
- if (s)
- sysfatal(buf);
- else
- sysfatal("");
-}
-
diff --git a/sys/src/cmd/unix/drawterm/exportfs/exportfs.h b/sys/src/cmd/unix/drawterm/exportfs/exportfs.h
deleted file mode 100644
index 3231573a9..000000000
--- a/sys/src/cmd/unix/drawterm/exportfs/exportfs.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * exportfs.h - definitions for exporting file server
- */
-
-#define DEBUG if(!dbg){}else fprint
-#define DFD 2
-#define fidhash(s) fhash[s%FHASHSIZE]
-
-#define Proc Exproc
-
-
-typedef struct Fsrpc Fsrpc;
-typedef struct Fid Fid;
-typedef struct File File;
-typedef struct Proc Proc;
-typedef struct Qidtab Qidtab;
-
-struct Fsrpc
-{
- int busy; /* Work buffer has pending rpc to service */
- int pid; /* Pid of slave process executing the rpc */
- int canint; /* Interrupt gate */
- int flushtag; /* Tag on which to reply to flush */
- Fcall work; /* Plan 9 incoming Fcall */
- uchar *buf; /* Data buffer */
-};
-
-struct Fid
-{
- int fid; /* system fd for i/o */
- File *f; /* File attached to this fid */
- int mode;
- int nr; /* fid number */
- int mid; /* Mount id */
- Fid *next; /* hash link */
-};
-
-struct File
-{
- char *name;
- int ref;
- Qid qid;
- Qidtab *qidt;
- int inval;
- File *parent;
- File *child;
- File *childlist;
-};
-
-struct Proc
-{
- int pid;
- int busy;
- Proc *next;
-};
-
-struct Qidtab
-{
- int ref;
- int type;
- int dev;
- vlong path;
- vlong uniqpath;
- Qidtab *next;
-};
-
-enum
-{
- MAXPROC = 50,
- FHASHSIZE = 64,
- Nr_workbufs = 50,
- Fidchunk = 1000,
- Npsmpt = 32,
- Nqidbits = 5,
- Nqidtab = (1<<Nqidbits),
-};
-
-#define Enomem Exenomem
-#define Ebadfix Exebadfid
-#define Enotdir Exenotdir
-#define Edupfid Exedupfid
-#define Eopen Exeopen
-#define Exmnt Exexmnt
-#define Emip Exemip
-#define Enopsmt Exenopsmt
-
-extern char Ebadfid[];
-extern char Enotdir[];
-extern char Edupfid[];
-extern char Eopen[];
-extern char Exmnt[];
-extern char Enomem[];
-extern char Emip[];
-extern char Enopsmt[];
-
-Extern Fsrpc *Workq;
-Extern int dbg;
-Extern File *root;
-Extern File *psmpt;
-Extern Fid **fhash;
-Extern Fid *fidfree;
-Extern Proc *Proclist;
-Extern char psmap[Npsmpt];
-Extern Qidtab *qidtab[Nqidtab];
-Extern ulong messagesize;
-Extern int srvfd;
-
-/* File system protocol service procedures */
-void Xattach(Fsrpc*);
-void Xauth(Fsrpc*);
-void Xclunk(Fsrpc*);
-void Xcreate(Fsrpc*);
-void Xflush(Fsrpc*);
-void Xnop(Fsrpc*);
-void Xremove(Fsrpc*);
-void Xstat(Fsrpc*);
-void Xversion(Fsrpc*);
-void Xwalk(Fsrpc*);
-void Xwstat(Fsrpc*);
-void slave(Fsrpc*);
-
-void reply(Fcall*, Fcall*, char*);
-Fid *getfid(int);
-int freefid(int);
-Fid *newfid(int);
-Fsrpc *getsbuf(void);
-void initroot(void);
-void fatal(char*, ...);
-char* makepath(File*, char*);
-File *file(File*, char*);
-void freefile(File*);
-void slaveopen(Fsrpc*);
-void slaveread(Fsrpc*);
-void slavewrite(Fsrpc*);
-void blockingslave(void*);
-void reopen(Fid *f);
-void noteproc(int, char*);
-void flushaction(void*, char*);
-void pushfcall(char*);
-Qidtab* uniqueqid(Dir*);
-void freeqid(Qidtab*);
-char* estrdup(char*);
-void* emallocz(uint);
-int readmessage(int, char*, int);
-
-#define notify(x)
-#define noted(x)
-#define exits(x)
diff --git a/sys/src/cmd/unix/drawterm/exportfs/exportsrv.c b/sys/src/cmd/unix/drawterm/exportfs/exportsrv.c
deleted file mode 100644
index dabb6a0e8..000000000
--- a/sys/src/cmd/unix/drawterm/exportfs/exportsrv.c
+++ /dev/null
@@ -1,676 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <fcall.h>
-#define Extern extern
-#include "exportfs.h"
-
-char Ebadfid[] = "Bad fid";
-char Enotdir[] = "Not a directory";
-char Edupfid[] = "Fid already in use";
-char Eopen[] = "Fid already opened";
-char Exmnt[] = "Cannot .. past mount point";
-char Emip[] = "Mount in progress";
-char Enopsmt[] = "Out of pseudo mount points";
-char Enomem[] = "No memory";
-char Eversion[] = "Bad 9P2000 version";
-
-int iounit(int x)
-{
- return 8192+IOHDRSZ;
-}
-
-void*
-emallocz(ulong n)
-{
- void *v;
-
- v = mallocz(n, 1);
- if(v == nil)
- panic("out of memory");
- return v;
-}
-
-
-void
-Xversion(Fsrpc *t)
-{
- Fcall rhdr;
-
- if(t->work.msize > messagesize)
- t->work.msize = messagesize;
- messagesize = t->work.msize;
- if(strncmp(t->work.version, "9P2000", 6) != 0){
- reply(&t->work, &rhdr, Eversion);
- return;
- }
- rhdr.version = "9P2000";
- rhdr.msize = t->work.msize;
- reply(&t->work, &rhdr, 0);
- t->busy = 0;
-}
-
-void
-Xauth(Fsrpc *t)
-{
- Fcall rhdr;
-
- reply(&t->work, &rhdr, "exportfs: authentication not required");
- t->busy = 0;
-}
-
-void
-Xflush(Fsrpc *t)
-{
- Fsrpc *w, *e;
- Fcall rhdr;
-
- e = &Workq[Nr_workbufs];
-
- for(w = Workq; w < e; w++) {
- if(w->work.tag == t->work.oldtag) {
- DEBUG(DFD, "\tQ busy %d pid %d can %d\n", w->busy, w->pid, w->canint);
- if(w->busy && w->pid) {
- w->flushtag = t->work.tag;
- DEBUG(DFD, "\tset flushtag %d\n", t->work.tag);
- // if(w->canint)
- // postnote(PNPROC, w->pid, "flush");
- t->busy = 0;
- return;
- }
- }
- }
-
- reply(&t->work, &rhdr, 0);
- DEBUG(DFD, "\tflush reply\n");
- t->busy = 0;
-}
-
-void
-Xattach(Fsrpc *t)
-{
- Fcall rhdr;
- Fid *f;
-
- f = newfid(t->work.fid);
- if(f == 0) {
- reply(&t->work, &rhdr, Ebadfid);
- t->busy = 0;
- return;
- }
-
- if(srvfd >= 0){
-/*
- if(psmpt == 0){
- Nomount:
- reply(&t->work, &rhdr, Enopsmt);
- t->busy = 0;
- freefid(t->work.fid);
- return;
- }
- for(i=0; i<Npsmpt; i++)
- if(psmap[i] == 0)
- break;
- if(i >= Npsmpt)
- goto Nomount;
- sprint(buf, "%d", i);
- f->f = file(psmpt, buf);
- if(f->f == nil)
- goto Nomount;
- sprint(buf, "/mnt/exportfs/%d", i);
- nfd = dup(srvfd, -1);
- if(amount(nfd, buf, MREPL|MCREATE, t->work.aname) < 0){
- errstr(buf, sizeof buf);
- reply(&t->work, &rhdr, buf);
- t->busy = 0;
- freefid(t->work.fid);
- close(nfd);
- return;
- }
- psmap[i] = 1;
- f->mid = i;
-*/
- }else{
- f->f = root;
- f->f->ref++;
- }
-
- rhdr.qid = f->f->qid;
- reply(&t->work, &rhdr, 0);
- t->busy = 0;
-}
-
-Fid*
-clonefid(Fid *f, int new)
-{
- Fid *n;
-
- n = newfid(new);
- if(n == 0) {
- n = getfid(new);
- if(n == 0)
- fatal("inconsistent fids");
- if(n->fid >= 0)
- close(n->fid);
- freefid(new);
- n = newfid(new);
- if(n == 0)
- fatal("inconsistent fids2");
- }
- n->f = f->f;
- n->f->ref++;
- return n;
-}
-
-void
-Xwalk(Fsrpc *t)
-{
- char err[ERRMAX], *e;
- Fcall rhdr;
- Fid *f, *nf;
- File *wf;
- int i;
-
- f = getfid(t->work.fid);
- if(f == 0) {
- reply(&t->work, &rhdr, Ebadfid);
- t->busy = 0;
- return;
- }
-
- nf = nil;
- if(t->work.newfid != t->work.fid){
- nf = clonefid(f, t->work.newfid);
- f = nf;
- }
-
- rhdr.nwqid = 0;
- e = nil;
- for(i=0; i<t->work.nwname; i++){
- if(i == MAXWELEM){
- e = "Too many path elements";
- break;
- }
-
- if(strcmp(t->work.wname[i], "..") == 0) {
- if(f->f->parent == nil) {
- e = Exmnt;
- break;
- }
- wf = f->f->parent;
- wf->ref++;
- goto Accept;
- }
-
- wf = file(f->f, t->work.wname[i]);
- if(wf == 0){
- errstr(err, sizeof err);
- e = err;
- break;
- }
- Accept:
- freefile(f->f);
- rhdr.wqid[rhdr.nwqid++] = wf->qid;
- f->f = wf;
- continue;
- }
-
- if(nf!=nil && (e!=nil || rhdr.nwqid!=t->work.nwname))
- freefid(t->work.newfid);
- if(rhdr.nwqid > 0)
- e = nil;
- reply(&t->work, &rhdr, e);
- t->busy = 0;
-}
-
-void
-Xclunk(Fsrpc *t)
-{
- Fcall rhdr;
- Fid *f;
-
- f = getfid(t->work.fid);
- if(f == 0) {
- reply(&t->work, &rhdr, Ebadfid);
- t->busy = 0;
- return;
- }
-
- if(f->fid >= 0)
- close(f->fid);
-
- freefid(t->work.fid);
- reply(&t->work, &rhdr, 0);
- t->busy = 0;
-}
-
-void
-Xstat(Fsrpc *t)
-{
- char err[ERRMAX], *path;
- Fcall rhdr;
- Fid *f;
- Dir *d;
- int s;
- uchar *statbuf;
-
- f = getfid(t->work.fid);
- if(f == 0) {
- reply(&t->work, &rhdr, Ebadfid);
- t->busy = 0;
- return;
- }
- if(f->fid >= 0)
- d = dirfstat(f->fid);
- else {
- path = makepath(f->f, "");
- d = dirstat(path);
- free(path);
- }
-
- if(d == nil) {
- errstr(err, sizeof err);
- reply(&t->work, &rhdr, err);
- t->busy = 0;
- return;
- }
-
- d->qid.path = f->f->qidt->uniqpath;
- s = sizeD2M(d);
- statbuf = emallocz(s);
- s = convD2M(d, statbuf, s);
- free(d);
- rhdr.nstat = s;
- rhdr.stat = statbuf;
- reply(&t->work, &rhdr, 0);
- free(statbuf);
- t->busy = 0;
-}
-
-static int
-getiounit(int fd)
-{
- int n;
-
- n = iounit(fd);
- if(n > messagesize-IOHDRSZ)
- n = messagesize-IOHDRSZ;
- return n;
-}
-
-void
-Xcreate(Fsrpc *t)
-{
- char err[ERRMAX], *path;
- Fcall rhdr;
- Fid *f;
- File *nf;
-
- f = getfid(t->work.fid);
- if(f == 0) {
- reply(&t->work, &rhdr, Ebadfid);
- t->busy = 0;
- return;
- }
-
-
- path = makepath(f->f, t->work.name);
- f->fid = create(path, t->work.mode, t->work.perm);
- free(path);
- if(f->fid < 0) {
- errstr(err, sizeof err);
- reply(&t->work, &rhdr, err);
- t->busy = 0;
- return;
- }
-
- nf = file(f->f, t->work.name);
- if(nf == 0) {
- errstr(err, sizeof err);
- reply(&t->work, &rhdr, err);
- t->busy = 0;
- return;
- }
-
- f->mode = t->work.mode;
- freefile(f->f);
- f->f = nf;
- rhdr.qid = f->f->qid;
- rhdr.iounit = getiounit(f->fid);
- reply(&t->work, &rhdr, 0);
- t->busy = 0;
-}
-
-void
-Xremove(Fsrpc *t)
-{
- char err[ERRMAX], *path;
- Fcall rhdr;
- Fid *f;
-
- f = getfid(t->work.fid);
- if(f == 0) {
- reply(&t->work, &rhdr, Ebadfid);
- t->busy = 0;
- return;
- }
-
- path = makepath(f->f, "");
- DEBUG(DFD, "\tremove: %s\n", path);
- if(remove(path) < 0) {
- free(path);
- errstr(err, sizeof err);
- reply(&t->work, &rhdr, err);
- t->busy = 0;
- return;
- }
- free(path);
-
- f->f->inval = 1;
- if(f->fid >= 0)
- close(f->fid);
- freefid(t->work.fid);
-
- reply(&t->work, &rhdr, 0);
- t->busy = 0;
-}
-
-void
-Xwstat(Fsrpc *t)
-{
- char err[ERRMAX], *path;
- Fcall rhdr;
- Fid *f;
- int s;
- char *strings;
- Dir d;
-
- f = getfid(t->work.fid);
- if(f == 0) {
- reply(&t->work, &rhdr, Ebadfid);
- t->busy = 0;
- return;
- }
- strings = emallocz(t->work.nstat); /* ample */
- if(convM2D(t->work.stat, t->work.nstat, &d, strings) <= BIT16SZ){
- rerrstr(err, sizeof err);
- reply(&t->work, &rhdr, err);
- t->busy = 0;
- free(strings);
- return;
- }
-
- if(f->fid >= 0)
- s = dirfwstat(f->fid, &d);
- else {
- path = makepath(f->f, "");
- s = dirwstat(path, &d);
- free(path);
- }
- if(s < 0) {
- rerrstr(err, sizeof err);
- reply(&t->work, &rhdr, err);
- }
- else {
- /* wstat may really be rename */
- if(strcmp(d.name, f->f->name)!=0 && strcmp(d.name, "")!=0){
- free(f->f->name);
- f->f->name = estrdup(d.name);
- }
- reply(&t->work, &rhdr, 0);
- }
- free(strings);
- t->busy = 0;
-}
-
-void
-slave(Fsrpc *f)
-{
- Proc *p;
- int pid;
- static int nproc;
-
- for(;;) {
- for(p = Proclist; p; p = p->next) {
- if(p->busy == 0) {
- f->pid = p->pid;
- p->busy = 1;
- pid = (uintptr)rendezvous((void*)(uintptr)p->pid, f);
- if(pid != p->pid)
- fatal("rendezvous sync fail");
- return;
- }
- }
-
- if(++nproc > MAXPROC)
- fatal("too many procs");
-
- pid = kproc("slave", blockingslave, nil);
- DEBUG(DFD, "slave pid %d\n", pid);
- if(pid == -1)
- fatal("kproc");
-
- p = malloc(sizeof(Proc));
- if(p == 0)
- fatal("out of memory");
-
- p->busy = 0;
- p->pid = pid;
- p->next = Proclist;
- Proclist = p;
-
-DEBUG(DFD, "parent %d rendez\n", pid);
- rendezvous((void*)(uintptr)pid, p);
-DEBUG(DFD, "parent %d went\n", pid);
- }
-}
-
-void
-blockingslave(void *x)
-{
- Fsrpc *p;
- Fcall rhdr;
- Proc *m;
- int pid;
-
- USED(x);
-
- notify(flushaction);
-
- pid = getpid();
-
-DEBUG(DFD, "blockingslave %d rendez\n", pid);
- m = (Proc*)rendezvous((void*)(uintptr)pid, 0);
-DEBUG(DFD, "blockingslave %d rendez got %p\n", pid, m);
-
- for(;;) {
- p = rendezvous((void*)(uintptr)pid, (void*)(uintptr)pid);
- if((uintptr)p == ~(uintptr)0) /* Interrupted */
- continue;
-
- DEBUG(DFD, "\tslave: %d %F b %d p %d\n", pid, &p->work, p->busy, p->pid);
- if(p->flushtag != NOTAG)
- goto flushme;
-
- switch(p->work.type) {
- case Tread:
- slaveread(p);
- break;
-
- case Twrite:
- slavewrite(p);
- break;
-
- case Topen:
- slaveopen(p);
- break;
-
- default:
- reply(&p->work, &rhdr, "exportfs: slave type error");
- }
- if(p->flushtag != NOTAG) {
-flushme:
- p->work.type = Tflush;
- p->work.tag = p->flushtag;
- reply(&p->work, &rhdr, 0);
- }
- p->busy = 0;
- m->busy = 0;
- }
-}
-
-int
-openmount(int sfd)
-{
- werrstr("openmount not implemented");
- return -1;
-}
-
-void
-slaveopen(Fsrpc *p)
-{
- char err[ERRMAX], *path;
- Fcall *work, rhdr;
- Fid *f;
- Dir *d;
-
- work = &p->work;
-
- f = getfid(work->fid);
- if(f == 0) {
- reply(work, &rhdr, Ebadfid);
- return;
- }
- if(f->fid >= 0) {
- close(f->fid);
- f->fid = -1;
- }
-
- path = makepath(f->f, "");
- DEBUG(DFD, "\topen: %s %d\n", path, work->mode);
-
- p->canint = 1;
- if(p->flushtag != NOTAG){
- free(path);
- return;
- }
- /* There is a race here I ignore because there are no locks */
- f->fid = open(path, work->mode);
- free(path);
- p->canint = 0;
- if(f->fid < 0 || (d = dirfstat(f->fid)) == nil) {
- Error:
- errstr(err, sizeof err);
- reply(work, &rhdr, err);
- return;
- }
- f->f->qid = d->qid;
- free(d);
- if(f->f->qid.type & QTMOUNT){ /* fork new exportfs for this */
- f->fid = openmount(f->fid);
- if(f->fid < 0)
- goto Error;
- }
-
- DEBUG(DFD, "\topen: fd %d\n", f->fid);
- f->mode = work->mode;
- rhdr.iounit = getiounit(f->fid);
- rhdr.qid = f->f->qid;
- reply(work, &rhdr, 0);
-}
-
-void
-slaveread(Fsrpc *p)
-{
- Fid *f;
- int n, r;
- Fcall *work, rhdr;
- char *data, err[ERRMAX];
-
- work = &p->work;
-
- f = getfid(work->fid);
- if(f == 0) {
- reply(work, &rhdr, Ebadfid);
- return;
- }
-
- n = (work->count > messagesize-IOHDRSZ) ? messagesize-IOHDRSZ : work->count;
- p->canint = 1;
- if(p->flushtag != NOTAG)
- return;
- data = malloc(n);
- if(data == nil)
- fatal(Enomem);
-
- /* can't just call pread, since directories must update the offset */
- r = pread(f->fid, data, n, work->offset);
- p->canint = 0;
- if(r < 0) {
- free(data);
- errstr(err, sizeof err);
- reply(work, &rhdr, err);
- return;
- }
-
- DEBUG(DFD, "\tread: fd=%d %d bytes\n", f->fid, r);
-
- rhdr.data = data;
- rhdr.count = r;
- reply(work, &rhdr, 0);
- free(data);
-}
-
-void
-slavewrite(Fsrpc *p)
-{
- char err[ERRMAX];
- Fcall *work, rhdr;
- Fid *f;
- int n;
-
- work = &p->work;
-
- f = getfid(work->fid);
- if(f == 0) {
- reply(work, &rhdr, Ebadfid);
- return;
- }
-
- n = (work->count > messagesize-IOHDRSZ) ? messagesize-IOHDRSZ : work->count;
- p->canint = 1;
- if(p->flushtag != NOTAG)
- return;
- n = pwrite(f->fid, work->data, n, work->offset);
- p->canint = 0;
- if(n < 0) {
- errstr(err, sizeof err);
- reply(work, &rhdr, err);
- return;
- }
-
- DEBUG(DFD, "\twrite: %d bytes fd=%d\n", n, f->fid);
-
- rhdr.count = n;
- reply(work, &rhdr, 0);
-}
-
-void
-reopen(Fid *f)
-{
- USED(f);
- fatal("reopen");
-}
-
-void
-flushaction(void *a, char *cause)
-{
- USED(a);
- if(strncmp(cause, "sys:", 4) == 0 && !strstr(cause, "pipe")) {
- fprint(2, "exportsrv: note: %s\n", cause);
- exits("noted");
- }
- if(strncmp(cause, "kill", 4) == 0)
- noted(NDFLT);
-
- noted(NCONT);
-}