diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2013-11-23 01:05:33 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2013-11-23 01:05:33 +0100 |
commit | 2f9ae0f8ac8610e13ced184847b57b87fe5db580 (patch) | |
tree | f9ad2223d518585a2cfe9ea1c73e1e37d07bf637 /sys/src/cmd/unix/drawterm/exportfs | |
parent | ea5797c0731203c09ec5fb7172e77eab2750f1a9 (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/Makefile | 16 | ||||
-rw-r--r-- | sys/src/cmd/unix/drawterm/exportfs/exportfs.c | 511 | ||||
-rw-r--r-- | sys/src/cmd/unix/drawterm/exportfs/exportfs.h | 148 | ||||
-rw-r--r-- | sys/src/cmd/unix/drawterm/exportfs/exportsrv.c | 676 |
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); -} |