| plan 9 kernel history: overview | file list | diff list |
1993/0501/port/devroot.c (diff list | history)
| port/devroot.c on 1990/0227 | ||
| 1990/0227 | #include "u.h" | |
| 1992/0321 | #include "../port/lib.h" | |
| 1990/0227 | #include "mem.h" #include "dat.h" #include "fns.h" | |
| 1992/0111 | #include "../port/error.h" | |
| 1990/0227 | #include "devtab.h" | |
| 1993/0501 | enum { | |
| 1990/0227 | Qdir, Qbin, Qdev, Qenv, Qproc, | |
| 1992/0213 | Qnet, | |
| 1993/0501 | Qrecover, | |
| 1991/1206 | Qboot, Qcfs, | |
| 1992/0902 | Qfs, | |
| 1990/0227 | }; | |
| 1991/0214 | extern long cfslen; | |
| 1991/0216 | extern ulong cfscode[]; | |
| 1992/0902 | extern long fslen; extern ulong fscode[]; | |
| 1991/1206 | extern ulong bootlen; | |
| 1992/0902 | extern uchar bootcode[]; | |
| 1991/0214 | ||
| 1990/0227 | Dirtab rootdir[]={ | |
| 1991/1112 | "bin", {Qbin|CHDIR}, 0, 0777, "boot", {Qboot}, 0, 0777, "dev", {Qdev|CHDIR}, 0, 0777, "env", {Qenv|CHDIR}, 0, 0777, "proc", {Qproc|CHDIR}, 0, 0777, | |
| 1992/0213 | "net", {Qnet|CHDIR}, 0, 0777, | |
| 1993/0501 | "recover", {Qrecover}, 0, 0777, | |
| 1990/0227 | }; #define NROOT (sizeof rootdir/sizeof(Dirtab)) | |
| 1991/0615 | Dirtab rootpdir[]={ | |
| 1991/1112 | "cfs", {Qcfs}, 0, 0777, | |
| 1992/0902 | "fs", {Qfs}, 0, 0777, | |
| 1991/0615 | }; Dirtab *rootmap[sizeof rootpdir/sizeof(Dirtab)]; | |
| 1991/0214 | int nroot; | |
| 1990/0227 | ||
| 1993/0501 | typedef struct Recover Recover; struct Recover { int len; char *req; Recover *next; }; struct { Lock; QLock; Rendez; Recover *q; }reclist; | |
| 1991/0615 | int rootgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp) { | |
| 1992/0711 | USED(ntab); | |
| 1992/0225 | if(i >= nroot) | |
| 1991/0615 | return -1; | |
| 1992/0225 | ||
| 1991/0615 | if(i < NROOT) | |
| 1992/0225 | tab = &rootdir[i]; | |
| 1991/0615 | else tab = rootmap[i - NROOT]; | |
| 1992/0225 | ||
| 1991/1109 | devdir(c, tab->qid, tab->name, tab->length, eve, tab->perm, dp); | |
| 1991/0615 | return 1; } | |
| 1990/0227 | void rootreset(void) { | |
| 1991/0615 | int i; i = 0; if(cfslen) rootmap[i++] = &rootpdir[0]; | |
| 1992/0902 | if(fslen) | |
| 1991/0913 | rootmap[i++] = &rootpdir[1]; | |
| 1991/0615 | nroot = NROOT + i; | |
| 1990/0227 | } void rootinit(void) { } Chan* rootattach(char *spec) { return devattach('/', spec); } Chan* rootclone(Chan *c, Chan *nc) { return devclone(c, nc); } int rootwalk(Chan *c, char *name) { | |
| 1991/1206 | if(strcmp(name, "..") == 0) { c->qid.path = Qdir|CHDIR; return 1; } | |
| 1992/0225 | if((c->qid.path & ~CHDIR) != Qdir) | |
| 1992/0226 | return 0; | |
| 1991/0615 | return devwalk(c, name, rootdir, nroot, rootgen); | |
| 1990/0227 | } void rootstat(Chan *c, char *dp) { | |
| 1991/0615 | devstat(c, dp, rootdir, nroot, rootgen); | |
| 1990/0227 | } Chan* rootopen(Chan *c, int omode) { | |
| 1993/0501 | switch(c->qid.path & ~CHDIR) { default: break; case Qrecover: if(strcmp(up->user, eve) != 0) error(Eperm); break; } | |
| 1991/0615 | return devopen(c, omode, rootdir, nroot, rootgen); | |
| 1990/0227 | } void rootcreate(Chan *c, char *name, int omode, ulong perm) { | |
| 1991/1115 | USED(c, name, omode, perm); | |
| 1990/11211 | error(Eperm); | |
| 1990/0227 | } /* * sysremove() knows this is a nop */ void rootclose(Chan *c) { | |
| 1991/1115 | USED(c); | |
| 1990/0227 | } | |
| 1993/0501 | int rdrdy(void *a) { USED(a); return reclist.q != 0; } | |
| 1990/0227 | long | |
| 1991/0411 | rootread(Chan *c, void *buf, long n, ulong offset) | |
| 1990/0227 | { | |
| 1993/0501 | Recover *r; | |
| 1990/0227 | ||
| 1990/11211 | switch(c->qid.path & ~CHDIR){ | |
| 1990/0227 | case Qdir: | |
| 1991/0615 | return devdirread(c, buf, n, rootdir, nroot, rootgen); | |
| 1990/0227 | case Qboot: /* boot */ | |
| 1991/1206 | if(offset >= bootlen) | |
| 1990/0227 | return 0; | |
| 1991/1206 | if(offset+n > bootlen) n = bootlen - offset; | |
| 1992/0902 | memmove(buf, bootcode+offset, n); | |
| 1991/0214 | return n; | |
| 1991/0312 | case Qcfs: /* cfs */ | |
| 1991/0411 | if(offset >= cfslen) | |
| 1991/0214 | return 0; | |
| 1991/0411 | if(offset+n > cfslen) n = cfslen - offset; memmove(buf, ((char*)cfscode)+offset, n); | |
| 1991/0910 | return n; | |
| 1992/0902 | case Qfs: /* fs */ if(offset >= fslen) | |
| 1991/0910 | return 0; | |
| 1992/0902 | if(offset+n > fslen) n = fslen - offset; memmove(buf, ((char*)fscode)+offset, n); | |
| 1990/0227 | return n; | |
| 1993/0501 | case Qrecover: qlock(&reclist); if(waserror()) { qunlock(&reclist); nexterror(); } sleep(&reclist, rdrdy, 0); lock(&reclist); r = reclist.q; reclist.q = r->next; unlock(&reclist); qunlock(&reclist); poperror(); if(n < r->len) n = r->len; memmove(buf, r->req, n); free(r->req); free(r); return n; | |
| 1990/0227 | case Qdev: return 0; } return 0; } long | |
| 1991/0411 | rootwrite(Chan *c, void *buf, long n, ulong offset) | |
| 1990/0227 | { | |
| 1993/0501 | char tmp[256]; USED(offset); switch(c->qid.path & ~CHDIR){ default: error(Egreg); case Qrecover: if(n > sizeof(tmp)-1) error(Etoosmall); /* Nul terminate */ memmove(tmp, buf, n); tmp[n] = '\0'; mntrepl(tmp); return n; } return 0; | |
| 1990/0227 | } void rootremove(Chan *c) { | |
| 1991/1115 | USED(c); | |
| 1990/11211 | error(Eperm); | |
| 1990/0227 | } void rootwstat(Chan *c, char *dp) { | |
| 1991/1115 | USED(c, dp); | |
| 1990/11211 | error(Eperm); | |
| 1993/0501 | } void rootrecover(Path *p, char *mntname) { int i; Recover *r; char buf[256]; r = malloc(sizeof(Recover)); i = ptpath(p, buf, sizeof(buf)); r->req = smalloc(i+strlen(mntname)+2); sprint(r->req, "%s %s", buf, mntname); lock(&reclist); r->next = reclist.q; reclist.q = r; unlock(&reclist); wakeup(&reclist); | |
| 1990/0227 | } | |