101a344a2SDavid du Colombier #include "all.h"
201a344a2SDavid du Colombier #include "io.h"
301a344a2SDavid du Colombier
401a344a2SDavid du Colombier enum {
501a344a2SDavid du Colombier Slop = 256, /* room at the start of a message buf for proto hdrs */
601a344a2SDavid du Colombier };
701a344a2SDavid du Colombier
801a344a2SDavid du Colombier Filsys*
fsstr(char * p)901a344a2SDavid du Colombier fsstr(char *p)
1001a344a2SDavid du Colombier {
1101a344a2SDavid du Colombier Filsys *fs;
1201a344a2SDavid du Colombier
1301a344a2SDavid du Colombier for(fs=filsys; fs->name; fs++)
1401a344a2SDavid du Colombier if(strcmp(fs->name, p) == 0)
1501a344a2SDavid du Colombier return fs;
1601a344a2SDavid du Colombier return 0;
1701a344a2SDavid du Colombier }
1801a344a2SDavid du Colombier
1901a344a2SDavid du Colombier Filsys*
dev2fs(Device * dev)2001a344a2SDavid du Colombier dev2fs(Device *dev)
2101a344a2SDavid du Colombier {
2201a344a2SDavid du Colombier Filsys *fs;
2301a344a2SDavid du Colombier
2401a344a2SDavid du Colombier for(fs=filsys; fs->name; fs++)
2501a344a2SDavid du Colombier if(fs->dev == dev)
2601a344a2SDavid du Colombier return fs;
2701a344a2SDavid du Colombier return 0;
2801a344a2SDavid du Colombier }
2901a344a2SDavid du Colombier
3001a344a2SDavid du Colombier /*
3101a344a2SDavid du Colombier * allocate 'count' contiguous channels
3201a344a2SDavid du Colombier * of type 'type' and return pointer to base
3301a344a2SDavid du Colombier */
3401a344a2SDavid du Colombier Chan*
fs_chaninit(int type,int count,int data)3501a344a2SDavid du Colombier fs_chaninit(int type, int count, int data)
3601a344a2SDavid du Colombier {
3701a344a2SDavid du Colombier uchar *p;
3801a344a2SDavid du Colombier Chan *cp, *icp;
3901a344a2SDavid du Colombier int i;
4001a344a2SDavid du Colombier
4101a344a2SDavid du Colombier p = malloc(count * (sizeof(Chan)+data));
4201a344a2SDavid du Colombier icp = (Chan*)p;
4301a344a2SDavid du Colombier for(i = 0; i < count; i++) {
4401a344a2SDavid du Colombier cp = (Chan*)p;
4501a344a2SDavid du Colombier cp->next = chans;
4601a344a2SDavid du Colombier chans = cp;
4701a344a2SDavid du Colombier cp->type = type;
4801a344a2SDavid du Colombier cp->chan = cons.chano;
4901a344a2SDavid du Colombier cons.chano++;
5001a344a2SDavid du Colombier strncpy(cp->whoname, "<none>", sizeof cp->whoname);
5101a344a2SDavid du Colombier wlock(&cp->reflock);
5201a344a2SDavid du Colombier wunlock(&cp->reflock);
5301a344a2SDavid du Colombier rlock(&cp->reflock);
5401a344a2SDavid du Colombier runlock(&cp->reflock);
5501a344a2SDavid du Colombier
5601a344a2SDavid du Colombier p += sizeof(Chan);
5701a344a2SDavid du Colombier if(data){
5801a344a2SDavid du Colombier cp->pdata = p;
5901a344a2SDavid du Colombier p += data;
6001a344a2SDavid du Colombier }
6101a344a2SDavid du Colombier }
6201a344a2SDavid du Colombier return icp;
6301a344a2SDavid du Colombier }
6401a344a2SDavid du Colombier
6501a344a2SDavid du Colombier void
fileinit(Chan * cp)6601a344a2SDavid du Colombier fileinit(Chan *cp)
6701a344a2SDavid du Colombier {
6801a344a2SDavid du Colombier File *f, *prev;
6901a344a2SDavid du Colombier Tlock *t;
7001a344a2SDavid du Colombier int h;
7101a344a2SDavid du Colombier
7201a344a2SDavid du Colombier loop:
7301a344a2SDavid du Colombier lock(&flock);
7401a344a2SDavid du Colombier for (h=0; h < nelem(flist); h++)
7501a344a2SDavid du Colombier for (prev=0, f = flist[h]; f; prev=f, f=f->next) {
7601a344a2SDavid du Colombier if(f->cp != cp)
7701a344a2SDavid du Colombier continue;
7801a344a2SDavid du Colombier if(prev) {
7901a344a2SDavid du Colombier prev->next = f->next;
8001a344a2SDavid du Colombier f->next = flist[h];
8101a344a2SDavid du Colombier flist[h] = f;
8201a344a2SDavid du Colombier }
8301a344a2SDavid du Colombier flist[h] = f->next;
8401a344a2SDavid du Colombier unlock(&flock);
8501a344a2SDavid du Colombier
8601a344a2SDavid du Colombier qlock(f);
8701a344a2SDavid du Colombier if(t = f->tlock) {
8801a344a2SDavid du Colombier if(t->file == f)
8901a344a2SDavid du Colombier t->time = 0; /* free the lock */
9001a344a2SDavid du Colombier f->tlock = 0;
9101a344a2SDavid du Colombier }
9201a344a2SDavid du Colombier if(f->open & FREMOV)
9301a344a2SDavid du Colombier doremove(f, 0);
9401a344a2SDavid du Colombier freewp(f->wpath);
9501a344a2SDavid du Colombier f->open = 0;
9601a344a2SDavid du Colombier authfree(f->auth);
9701a344a2SDavid du Colombier f->auth = 0;
9801a344a2SDavid du Colombier f->cp = 0;
9901a344a2SDavid du Colombier qunlock(f);
10001a344a2SDavid du Colombier goto loop;
10101a344a2SDavid du Colombier }
10201a344a2SDavid du Colombier unlock(&flock);
10301a344a2SDavid du Colombier }
10401a344a2SDavid du Colombier
10501a344a2SDavid du Colombier enum { NOFID = (ulong)~0 };
10601a344a2SDavid du Colombier
10701a344a2SDavid du Colombier /*
10801a344a2SDavid du Colombier * returns a locked file structure
10901a344a2SDavid du Colombier */
11001a344a2SDavid du Colombier File*
filep(Chan * cp,ulong fid,int flag)11101a344a2SDavid du Colombier filep(Chan *cp, ulong fid, int flag)
11201a344a2SDavid du Colombier {
11301a344a2SDavid du Colombier File *f;
11401a344a2SDavid du Colombier int h;
11501a344a2SDavid du Colombier
11601a344a2SDavid du Colombier if(fid == NOFID)
11701a344a2SDavid du Colombier return 0;
11801a344a2SDavid du Colombier
119223a0358SDavid du Colombier h = (long)(uintptr)cp + fid;
12001a344a2SDavid du Colombier if(h < 0)
12101a344a2SDavid du Colombier h = ~h;
12201a344a2SDavid du Colombier h %= nelem(flist);
12301a344a2SDavid du Colombier
12401a344a2SDavid du Colombier loop:
12501a344a2SDavid du Colombier lock(&flock);
12601a344a2SDavid du Colombier for(f=flist[h]; f; f=f->next)
12701a344a2SDavid du Colombier if(f->fid == fid && f->cp == cp){
12801a344a2SDavid du Colombier /*
12901a344a2SDavid du Colombier * Already in use is an error
13001a344a2SDavid du Colombier * when called from attach or clone (walk
13101a344a2SDavid du Colombier * in 9P2000). The console uses FID[12] and
13201a344a2SDavid du Colombier * never clunks them so catch that case.
13301a344a2SDavid du Colombier */
13401a344a2SDavid du Colombier if(flag == 0 || cp == cons.chan)
13501a344a2SDavid du Colombier goto out;
13601a344a2SDavid du Colombier unlock(&flock);
13701a344a2SDavid du Colombier return 0;
13801a344a2SDavid du Colombier }
13901a344a2SDavid du Colombier
14001a344a2SDavid du Colombier if(flag) {
14101a344a2SDavid du Colombier f = newfp();
14201a344a2SDavid du Colombier if(f) {
14301a344a2SDavid du Colombier f->fid = fid;
14401a344a2SDavid du Colombier f->cp = cp;
14501a344a2SDavid du Colombier f->wpath = 0;
14601a344a2SDavid du Colombier f->tlock = 0;
14701a344a2SDavid du Colombier f->doffset = 0;
14801a344a2SDavid du Colombier f->dslot = 0;
14901a344a2SDavid du Colombier f->auth = 0;
15001a344a2SDavid du Colombier f->next = flist[h];
15101a344a2SDavid du Colombier flist[h] = f;
15201a344a2SDavid du Colombier goto out;
15301a344a2SDavid du Colombier }
15401a344a2SDavid du Colombier }
15501a344a2SDavid du Colombier unlock(&flock);
15601a344a2SDavid du Colombier return 0;
15701a344a2SDavid du Colombier
15801a344a2SDavid du Colombier out:
15901a344a2SDavid du Colombier unlock(&flock);
16001a344a2SDavid du Colombier qlock(f);
16101a344a2SDavid du Colombier if(f->fid == fid && f->cp == cp)
16201a344a2SDavid du Colombier return f;
16301a344a2SDavid du Colombier qunlock(f);
16401a344a2SDavid du Colombier goto loop;
16501a344a2SDavid du Colombier }
16601a344a2SDavid du Colombier
16701a344a2SDavid du Colombier /*
16801a344a2SDavid du Colombier * always called with flock locked
16901a344a2SDavid du Colombier */
17001a344a2SDavid du Colombier File*
newfp(void)17101a344a2SDavid du Colombier newfp(void)
17201a344a2SDavid du Colombier {
17301a344a2SDavid du Colombier static int first;
17401a344a2SDavid du Colombier File *f;
17501a344a2SDavid du Colombier int start, i;
17601a344a2SDavid du Colombier
17701a344a2SDavid du Colombier i = first;
17801a344a2SDavid du Colombier start = i;
17901a344a2SDavid du Colombier do {
18001a344a2SDavid du Colombier f = &files[i];
18101a344a2SDavid du Colombier i++;
18201a344a2SDavid du Colombier if(i >= conf.nfile)
18301a344a2SDavid du Colombier i = 0;
18401a344a2SDavid du Colombier if(f->cp)
18501a344a2SDavid du Colombier continue;
18601a344a2SDavid du Colombier first = i;
18701a344a2SDavid du Colombier return f;
18801a344a2SDavid du Colombier } while(i != start);
18901a344a2SDavid du Colombier
19001a344a2SDavid du Colombier print("out of files\n");
19101a344a2SDavid du Colombier return 0;
19201a344a2SDavid du Colombier }
19301a344a2SDavid du Colombier
19401a344a2SDavid du Colombier void
freefp(File * fp)19501a344a2SDavid du Colombier freefp(File *fp)
19601a344a2SDavid du Colombier {
19701a344a2SDavid du Colombier Chan *cp;
19801a344a2SDavid du Colombier File *f, *prev;
19901a344a2SDavid du Colombier int h;
20001a344a2SDavid du Colombier
20101a344a2SDavid du Colombier if(!fp || !(cp = fp->cp))
20201a344a2SDavid du Colombier return;
20301a344a2SDavid du Colombier
204223a0358SDavid du Colombier h = (long)(uintptr)cp + fp->fid;
20501a344a2SDavid du Colombier if(h < 0)
20601a344a2SDavid du Colombier h = ~h;
20701a344a2SDavid du Colombier h %= nelem(flist);
20801a344a2SDavid du Colombier
20901a344a2SDavid du Colombier lock(&flock);
21001a344a2SDavid du Colombier for(prev=0,f=flist[h]; f; prev=f,f=f->next)
21101a344a2SDavid du Colombier if(f == fp) {
21201a344a2SDavid du Colombier if(prev)
21301a344a2SDavid du Colombier prev->next = f->next;
21401a344a2SDavid du Colombier else
21501a344a2SDavid du Colombier flist[h] = f->next;
21601a344a2SDavid du Colombier break;
21701a344a2SDavid du Colombier }
21801a344a2SDavid du Colombier fp->cp = 0;
21901a344a2SDavid du Colombier unlock(&flock);
22001a344a2SDavid du Colombier }
22101a344a2SDavid du Colombier
22201a344a2SDavid du Colombier int
iaccess(File * f,Dentry * d,int m)22301a344a2SDavid du Colombier iaccess(File *f, Dentry *d, int m)
22401a344a2SDavid du Colombier {
22501a344a2SDavid du Colombier /* uid none gets only other permissions */
22601a344a2SDavid du Colombier if(f->uid != 0) {
22701a344a2SDavid du Colombier /*
22801a344a2SDavid du Colombier * owner
22901a344a2SDavid du Colombier */
23001a344a2SDavid du Colombier if(f->uid == d->uid)
23101a344a2SDavid du Colombier if((m<<6) & d->mode)
23201a344a2SDavid du Colombier return 0;
23301a344a2SDavid du Colombier /*
23401a344a2SDavid du Colombier * group membership
23501a344a2SDavid du Colombier */
23601a344a2SDavid du Colombier if(ingroup(f->uid, d->gid))
23701a344a2SDavid du Colombier if((m<<3) & d->mode)
23801a344a2SDavid du Colombier return 0;
23901a344a2SDavid du Colombier }
24001a344a2SDavid du Colombier
24101a344a2SDavid du Colombier /*
24201a344a2SDavid du Colombier * other
24301a344a2SDavid du Colombier */
24401a344a2SDavid du Colombier if(m & d->mode) {
24501a344a2SDavid du Colombier if((d->mode & DDIR) && (m == DEXEC))
24601a344a2SDavid du Colombier return 0;
24701a344a2SDavid du Colombier if(!ingroup(f->uid, 9999))
24801a344a2SDavid du Colombier return 0;
24901a344a2SDavid du Colombier }
25001a344a2SDavid du Colombier
25101a344a2SDavid du Colombier /*
25201a344a2SDavid du Colombier * various forms of superuser
25301a344a2SDavid du Colombier */
25401a344a2SDavid du Colombier if(wstatallow)
25501a344a2SDavid du Colombier return 0;
25601a344a2SDavid du Colombier if(duallow != 0 && duallow == f->uid)
25701a344a2SDavid du Colombier if((d->mode & DDIR) && (m == DREAD || m == DEXEC))
25801a344a2SDavid du Colombier return 0;
25901a344a2SDavid du Colombier
26001a344a2SDavid du Colombier return 1;
26101a344a2SDavid du Colombier }
26201a344a2SDavid du Colombier
26301a344a2SDavid du Colombier Tlock*
tlocked(Iobuf * p,Dentry * d)26401a344a2SDavid du Colombier tlocked(Iobuf *p, Dentry *d)
26501a344a2SDavid du Colombier {
26601a344a2SDavid du Colombier Tlock *t, *t1;
26701a344a2SDavid du Colombier Off qpath;
26801a344a2SDavid du Colombier Timet tim;
26901a344a2SDavid du Colombier Device *dev;
27001a344a2SDavid du Colombier
27101a344a2SDavid du Colombier tim = toytime();
27201a344a2SDavid du Colombier qpath = d->qid.path;
27301a344a2SDavid du Colombier dev = p->dev;
27401a344a2SDavid du Colombier
27501a344a2SDavid du Colombier again:
27601a344a2SDavid du Colombier t1 = 0;
27701a344a2SDavid du Colombier for(t=tlocks+NTLOCK-1; t>=tlocks; t--) {
27801a344a2SDavid du Colombier if(t->qpath == qpath)
27901a344a2SDavid du Colombier if(t->time >= tim)
28001a344a2SDavid du Colombier if(t->dev == dev)
28101a344a2SDavid du Colombier return nil; /* its locked */
28201a344a2SDavid du Colombier if(t1 != nil && t->time == 0)
28301a344a2SDavid du Colombier t1 = t; /* remember free lock */
28401a344a2SDavid du Colombier }
28501a344a2SDavid du Colombier if(t1 == 0) {
28601a344a2SDavid du Colombier // reclaim old locks
28701a344a2SDavid du Colombier lock(&tlocklock);
28801a344a2SDavid du Colombier for(t=tlocks+NTLOCK-1; t>=tlocks; t--)
28901a344a2SDavid du Colombier if(t->time < tim) {
29001a344a2SDavid du Colombier t->time = 0;
29101a344a2SDavid du Colombier t1 = t;
29201a344a2SDavid du Colombier }
29301a344a2SDavid du Colombier unlock(&tlocklock);
29401a344a2SDavid du Colombier }
29501a344a2SDavid du Colombier if(t1) {
29601a344a2SDavid du Colombier lock(&tlocklock);
29701a344a2SDavid du Colombier if(t1->time != 0) {
29801a344a2SDavid du Colombier unlock(&tlocklock);
29901a344a2SDavid du Colombier goto again;
30001a344a2SDavid du Colombier }
30101a344a2SDavid du Colombier t1->dev = dev;
30201a344a2SDavid du Colombier t1->qpath = qpath;
30301a344a2SDavid du Colombier t1->time = tim + TLOCK;
30401a344a2SDavid du Colombier unlock(&tlocklock);
30501a344a2SDavid du Colombier }
30601a344a2SDavid du Colombier /* botch
30701a344a2SDavid du Colombier * out of tlock nodes simulates
30801a344a2SDavid du Colombier * a locked file
30901a344a2SDavid du Colombier */
31001a344a2SDavid du Colombier return t1;
31101a344a2SDavid du Colombier }
31201a344a2SDavid du Colombier
31301a344a2SDavid du Colombier Wpath*
newwp(void)31401a344a2SDavid du Colombier newwp(void)
31501a344a2SDavid du Colombier {
31601a344a2SDavid du Colombier static int si = 0;
31701a344a2SDavid du Colombier int i;
31801a344a2SDavid du Colombier Wpath *w, *sw, *ew;
31901a344a2SDavid du Colombier
32001a344a2SDavid du Colombier i = si + 1;
32101a344a2SDavid du Colombier if(i < 0 || i >= conf.nwpath)
32201a344a2SDavid du Colombier i = 0;
32301a344a2SDavid du Colombier si = i;
32401a344a2SDavid du Colombier sw = &wpaths[i];
32501a344a2SDavid du Colombier ew = &wpaths[conf.nwpath];
32601a344a2SDavid du Colombier for(w=sw;;) {
32701a344a2SDavid du Colombier w++;
32801a344a2SDavid du Colombier if(w >= ew)
32901a344a2SDavid du Colombier w = &wpaths[0];
33001a344a2SDavid du Colombier if(w == sw) {
33101a344a2SDavid du Colombier print("out of wpaths\n");
33201a344a2SDavid du Colombier return 0;
33301a344a2SDavid du Colombier }
33401a344a2SDavid du Colombier if(w->refs)
33501a344a2SDavid du Colombier continue;
33601a344a2SDavid du Colombier lock(&wpathlock);
33701a344a2SDavid du Colombier if(w->refs) {
33801a344a2SDavid du Colombier unlock(&wpathlock);
33901a344a2SDavid du Colombier continue;
34001a344a2SDavid du Colombier }
34101a344a2SDavid du Colombier w->refs = 1;
34201a344a2SDavid du Colombier w->up = 0;
34301a344a2SDavid du Colombier unlock(&wpathlock);
34401a344a2SDavid du Colombier return w;
34501a344a2SDavid du Colombier }
34601a344a2SDavid du Colombier
34701a344a2SDavid du Colombier }
34801a344a2SDavid du Colombier
34901a344a2SDavid du Colombier void
freewp(Wpath * w)35001a344a2SDavid du Colombier freewp(Wpath *w)
35101a344a2SDavid du Colombier {
35201a344a2SDavid du Colombier lock(&wpathlock);
35301a344a2SDavid du Colombier for(; w; w=w->up)
35401a344a2SDavid du Colombier w->refs--;
35501a344a2SDavid du Colombier unlock(&wpathlock);
35601a344a2SDavid du Colombier }
35701a344a2SDavid du Colombier
35801a344a2SDavid du Colombier Off
qidpathgen(Device * dev)35901a344a2SDavid du Colombier qidpathgen(Device *dev)
36001a344a2SDavid du Colombier {
36101a344a2SDavid du Colombier Iobuf *p;
36201a344a2SDavid du Colombier Superb *sb;
36301a344a2SDavid du Colombier Off path;
36401a344a2SDavid du Colombier
36501a344a2SDavid du Colombier p = getbuf(dev, superaddr(dev), Brd|Bmod);
36601a344a2SDavid du Colombier if(!p || checktag(p, Tsuper, QPSUPER))
36701a344a2SDavid du Colombier panic("newqid: super block");
36801a344a2SDavid du Colombier sb = (Superb*)p->iobuf;
36901a344a2SDavid du Colombier sb->qidgen++;
37001a344a2SDavid du Colombier path = sb->qidgen;
37101a344a2SDavid du Colombier putbuf(p);
37201a344a2SDavid du Colombier return path;
37301a344a2SDavid du Colombier }
37401a344a2SDavid du Colombier
37501a344a2SDavid du Colombier /* truncating to length > 0 */
37601a344a2SDavid du Colombier static void
truncfree(Truncstate * ts,Device * dev,int d,Iobuf * p,int i)37701a344a2SDavid du Colombier truncfree(Truncstate *ts, Device *dev, int d, Iobuf *p, int i)
37801a344a2SDavid du Colombier {
37901a344a2SDavid du Colombier int pastlast;
38001a344a2SDavid du Colombier Off a;
38101a344a2SDavid du Colombier
38201a344a2SDavid du Colombier pastlast = ts->pastlast;
38301a344a2SDavid du Colombier a = ((Off *)p->iobuf)[i];
38401a344a2SDavid du Colombier if (d > 0 || pastlast)
38501a344a2SDavid du Colombier buffree(dev, a, d, ts);
38601a344a2SDavid du Colombier if (pastlast) {
38701a344a2SDavid du Colombier ((Off *)p->iobuf)[i] = 0;
38801a344a2SDavid du Colombier p->flags |= Bmod|Bimm;
38901a344a2SDavid du Colombier } else if (d == 0 && ts->relblk == ts->lastblk)
39001a344a2SDavid du Colombier ts->pastlast = 1;
39101a344a2SDavid du Colombier if (d == 0)
39201a344a2SDavid du Colombier ts->relblk++;
39301a344a2SDavid du Colombier }
39401a344a2SDavid du Colombier
39501a344a2SDavid du Colombier /*
39601a344a2SDavid du Colombier * free the block at `addr' on dev.
39701a344a2SDavid du Colombier * if it's an indirect block (d [depth] > 0),
39801a344a2SDavid du Colombier * first recursively free all the blocks it names.
39901a344a2SDavid du Colombier *
40001a344a2SDavid du Colombier * ts->relblk is the block number within the file of this
40101a344a2SDavid du Colombier * block (or the first data block eventually pointed to via
40201a344a2SDavid du Colombier * this indirect block).
40301a344a2SDavid du Colombier */
40401a344a2SDavid du Colombier void
buffree(Device * dev,Off addr,int d,Truncstate * ts)40501a344a2SDavid du Colombier buffree(Device *dev, Off addr, int d, Truncstate *ts)
40601a344a2SDavid du Colombier {
40701a344a2SDavid du Colombier Iobuf *p;
40801a344a2SDavid du Colombier Off a;
40901a344a2SDavid du Colombier int i, pastlast;
41001a344a2SDavid du Colombier
41101a344a2SDavid du Colombier if(!addr)
41201a344a2SDavid du Colombier return;
41301a344a2SDavid du Colombier pastlast = (ts == nil? 1: ts->pastlast);
41401a344a2SDavid du Colombier /*
41501a344a2SDavid du Colombier * if this is an indirect block, recurse and free any
41601a344a2SDavid du Colombier * suitable blocks within it (possibly via further indirect blocks).
41701a344a2SDavid du Colombier */
41801a344a2SDavid du Colombier if(d > 0) {
41901a344a2SDavid du Colombier d--;
42001a344a2SDavid du Colombier p = getbuf(dev, addr, Brd);
42101a344a2SDavid du Colombier if(p) {
42201a344a2SDavid du Colombier if (ts == nil) /* common case: create */
42301a344a2SDavid du Colombier for(i=INDPERBUF-1; i>=0; i--) {
42401a344a2SDavid du Colombier a = ((Off *)p->iobuf)[i];
42501a344a2SDavid du Colombier buffree(dev, a, d, nil);
42601a344a2SDavid du Colombier }
42701a344a2SDavid du Colombier else /* wstat truncation */
42801a344a2SDavid du Colombier for (i = 0; i < INDPERBUF; i++)
42901a344a2SDavid du Colombier truncfree(ts, dev, d, p, i);
43001a344a2SDavid du Colombier putbuf(p);
43101a344a2SDavid du Colombier }
43201a344a2SDavid du Colombier }
43301a344a2SDavid du Colombier if (!pastlast)
43401a344a2SDavid du Colombier return;
43501a344a2SDavid du Colombier /*
43601a344a2SDavid du Colombier * having zeroed the pointer to this block, add it to the free list.
43701a344a2SDavid du Colombier * stop outstanding i/o
43801a344a2SDavid du Colombier */
43901a344a2SDavid du Colombier p = getbuf(dev, addr, Bprobe);
44001a344a2SDavid du Colombier if(p) {
44101a344a2SDavid du Colombier p->flags &= ~(Bmod|Bimm);
44201a344a2SDavid du Colombier putbuf(p);
44301a344a2SDavid du Colombier }
44401a344a2SDavid du Colombier /*
44501a344a2SDavid du Colombier * dont put written worm
44601a344a2SDavid du Colombier * blocks into free list
44701a344a2SDavid du Colombier */
44801a344a2SDavid du Colombier if(dev->type == Devcw) {
44901a344a2SDavid du Colombier i = cwfree(dev, addr);
45001a344a2SDavid du Colombier if(i)
45101a344a2SDavid du Colombier return;
45201a344a2SDavid du Colombier }
45301a344a2SDavid du Colombier p = getbuf(dev, superaddr(dev), Brd|Bmod);
45401a344a2SDavid du Colombier if(!p || checktag(p, Tsuper, QPSUPER))
45501a344a2SDavid du Colombier panic("buffree: super block");
45601a344a2SDavid du Colombier addfree(dev, addr, (Superb*)p->iobuf);
45701a344a2SDavid du Colombier putbuf(p);
45801a344a2SDavid du Colombier }
45901a344a2SDavid du Colombier
46001a344a2SDavid du Colombier Off
bufalloc(Device * dev,int tag,long qid,int uid)46101a344a2SDavid du Colombier bufalloc(Device *dev, int tag, long qid, int uid)
46201a344a2SDavid du Colombier {
46301a344a2SDavid du Colombier Iobuf *bp, *p;
46401a344a2SDavid du Colombier Superb *sb;
46501a344a2SDavid du Colombier Off a, n;
46601a344a2SDavid du Colombier
46701a344a2SDavid du Colombier p = getbuf(dev, superaddr(dev), Brd|Bmod);
46801a344a2SDavid du Colombier if(!p || checktag(p, Tsuper, QPSUPER)) {
46901a344a2SDavid du Colombier print("bufalloc: super block\n");
47001a344a2SDavid du Colombier if(p)
47101a344a2SDavid du Colombier putbuf(p);
47201a344a2SDavid du Colombier return 0;
47301a344a2SDavid du Colombier }
47401a344a2SDavid du Colombier sb = (Superb*)p->iobuf;
47501a344a2SDavid du Colombier
47601a344a2SDavid du Colombier loop:
47701a344a2SDavid du Colombier n = --sb->fbuf.nfree;
47801a344a2SDavid du Colombier sb->tfree--;
47901a344a2SDavid du Colombier if(n < 0 || n >= FEPERBUF) {
48001a344a2SDavid du Colombier print("bufalloc: %Z: bad freelist\n", dev);
48101a344a2SDavid du Colombier n = 0;
48201a344a2SDavid du Colombier sb->fbuf.free[0] = 0;
48301a344a2SDavid du Colombier }
48401a344a2SDavid du Colombier a = sb->fbuf.free[n];
48501a344a2SDavid du Colombier if(n <= 0) {
48601a344a2SDavid du Colombier if(a == 0) {
48701a344a2SDavid du Colombier sb->tfree = 0;
48801a344a2SDavid du Colombier sb->fbuf.nfree = 1;
48901a344a2SDavid du Colombier if(dev->type == Devcw) {
49001a344a2SDavid du Colombier n = uid;
49101a344a2SDavid du Colombier if(n < 0 || n >= nelem(growacct))
49201a344a2SDavid du Colombier n = 0;
49301a344a2SDavid du Colombier growacct[n]++;
49401a344a2SDavid du Colombier if(cwgrow(dev, sb, uid))
49501a344a2SDavid du Colombier goto loop;
49601a344a2SDavid du Colombier }
49701a344a2SDavid du Colombier putbuf(p);
49801a344a2SDavid du Colombier print("fs %Z full uid=%d\n", dev, uid);
49901a344a2SDavid du Colombier return 0;
50001a344a2SDavid du Colombier }
50101a344a2SDavid du Colombier bp = getbuf(dev, a, Brd);
50201a344a2SDavid du Colombier if(!bp || checktag(bp, Tfree, QPNONE)) {
50301a344a2SDavid du Colombier if(bp)
50401a344a2SDavid du Colombier putbuf(bp);
50501a344a2SDavid du Colombier putbuf(p);
50601a344a2SDavid du Colombier return 0;
50701a344a2SDavid du Colombier }
50801a344a2SDavid du Colombier sb->fbuf = *(Fbuf*)bp->iobuf;
50901a344a2SDavid du Colombier putbuf(bp);
51001a344a2SDavid du Colombier }
51101a344a2SDavid du Colombier
51201a344a2SDavid du Colombier bp = getbuf(dev, a, Bmod);
51301a344a2SDavid du Colombier memset(bp->iobuf, 0, RBUFSIZE);
51401a344a2SDavid du Colombier settag(bp, tag, qid);
515*eba00c11SDavid du Colombier if(tag == Tind1 || tag == Tind2 ||
516*eba00c11SDavid du Colombier #ifndef COMPAT32
517*eba00c11SDavid du Colombier tag == Tind3 || tag == Tind4 || /* add more Tind tags here ... */
518*eba00c11SDavid du Colombier #endif
519*eba00c11SDavid du Colombier tag == Tdir)
52001a344a2SDavid du Colombier bp->flags |= Bimm;
52101a344a2SDavid du Colombier putbuf(bp);
52201a344a2SDavid du Colombier putbuf(p);
52301a344a2SDavid du Colombier return a;
52401a344a2SDavid du Colombier }
52501a344a2SDavid du Colombier
52601a344a2SDavid du Colombier /*
52701a344a2SDavid du Colombier * what are legal characters in a name?
52801a344a2SDavid du Colombier * only disallow control characters.
52901a344a2SDavid du Colombier * a) utf avoids control characters.
53001a344a2SDavid du Colombier * b) '/' may not be the separator
53101a344a2SDavid du Colombier */
53201a344a2SDavid du Colombier int
checkname(char * n)53301a344a2SDavid du Colombier checkname(char *n)
53401a344a2SDavid du Colombier {
53501a344a2SDavid du Colombier int i, c;
53601a344a2SDavid du Colombier
53701a344a2SDavid du Colombier for(i=0; i<NAMELEN; i++) {
53801a344a2SDavid du Colombier c = *n & 0xff;
53901a344a2SDavid du Colombier if(c == 0) {
54001a344a2SDavid du Colombier if(i == 0)
54101a344a2SDavid du Colombier return 1;
54201a344a2SDavid du Colombier memset(n, 0, NAMELEN-i);
54301a344a2SDavid du Colombier return 0;
54401a344a2SDavid du Colombier }
54501a344a2SDavid du Colombier if(c <= 040)
54601a344a2SDavid du Colombier return 1;
54701a344a2SDavid du Colombier n++;
54801a344a2SDavid du Colombier }
54901a344a2SDavid du Colombier return 1; /* too long */
55001a344a2SDavid du Colombier }
55101a344a2SDavid du Colombier
55201a344a2SDavid du Colombier void
addfree(Device * dev,Off addr,Superb * sb)55301a344a2SDavid du Colombier addfree(Device *dev, Off addr, Superb *sb)
55401a344a2SDavid du Colombier {
55501a344a2SDavid du Colombier int n;
55601a344a2SDavid du Colombier Iobuf *p;
55701a344a2SDavid du Colombier
55801a344a2SDavid du Colombier n = sb->fbuf.nfree;
55901a344a2SDavid du Colombier if(n < 0 || n > FEPERBUF)
56001a344a2SDavid du Colombier panic("addfree: bad freelist");
56101a344a2SDavid du Colombier if(n >= FEPERBUF) {
56201a344a2SDavid du Colombier p = getbuf(dev, addr, Bmod|Bimm);
56301a344a2SDavid du Colombier if(p == 0)
56401a344a2SDavid du Colombier panic("addfree: getbuf");
56501a344a2SDavid du Colombier *(Fbuf*)p->iobuf = sb->fbuf;
56601a344a2SDavid du Colombier settag(p, Tfree, QPNONE);
56701a344a2SDavid du Colombier putbuf(p);
56801a344a2SDavid du Colombier n = 0;
56901a344a2SDavid du Colombier }
57001a344a2SDavid du Colombier sb->fbuf.free[n++] = addr;
57101a344a2SDavid du Colombier sb->fbuf.nfree = n;
57201a344a2SDavid du Colombier sb->tfree++;
57301a344a2SDavid du Colombier if(addr >= sb->fsize)
57401a344a2SDavid du Colombier sb->fsize = addr+1;
57501a344a2SDavid du Colombier }
57601a344a2SDavid du Colombier
57701a344a2SDavid du Colombier /*
57801a344a2SDavid du Colombier static int
57901a344a2SDavid du Colombier Yfmt(Fmt* fmt)
58001a344a2SDavid du Colombier {
58101a344a2SDavid du Colombier Chan *cp;
58201a344a2SDavid du Colombier char s[20];
58301a344a2SDavid du Colombier
58401a344a2SDavid du Colombier cp = va_arg(fmt->args, Chan*);
58501a344a2SDavid du Colombier sprint(s, "C%d.%.3d", cp->type, cp->chan);
58601a344a2SDavid du Colombier return fmtstrcpy(fmt, s);
58701a344a2SDavid du Colombier }
58801a344a2SDavid du Colombier */
58901a344a2SDavid du Colombier
59001a344a2SDavid du Colombier static int
Zfmt(Fmt * fmt)59101a344a2SDavid du Colombier Zfmt(Fmt* fmt)
59201a344a2SDavid du Colombier {
59301a344a2SDavid du Colombier Device *d;
59401a344a2SDavid du Colombier int c, c1;
59501a344a2SDavid du Colombier char s[100];
59601a344a2SDavid du Colombier
59701a344a2SDavid du Colombier d = va_arg(fmt->args, Device*);
59801a344a2SDavid du Colombier if(d == nil) {
59901a344a2SDavid du Colombier sprint(s, "Z***");
60001a344a2SDavid du Colombier goto out;
60101a344a2SDavid du Colombier }
60201a344a2SDavid du Colombier c = c1 = '\0';
60301a344a2SDavid du Colombier switch(d->type) {
60401a344a2SDavid du Colombier default:
60501a344a2SDavid du Colombier sprint(s, "D%d", d->type);
60601a344a2SDavid du Colombier break;
60701a344a2SDavid du Colombier case Devwren:
60801a344a2SDavid du Colombier c = 'w';
60901a344a2SDavid du Colombier /* fallthrough */
61001a344a2SDavid du Colombier case Devworm:
61101a344a2SDavid du Colombier if (c == '\0')
61201a344a2SDavid du Colombier c = 'r';
61301a344a2SDavid du Colombier /* fallthrough */
61401a344a2SDavid du Colombier case Devlworm:
61501a344a2SDavid du Colombier if (c == '\0')
61601a344a2SDavid du Colombier c = 'l';
61701a344a2SDavid du Colombier if(d->wren.ctrl == 0 && d->wren.lun == 0)
61801a344a2SDavid du Colombier sprint(s, "%c%d", c, d->wren.targ);
61901a344a2SDavid du Colombier else
62001a344a2SDavid du Colombier sprint(s, "%c%d.%d.%d", c, d->wren.ctrl, d->wren.targ,
62101a344a2SDavid du Colombier d->wren.lun);
62201a344a2SDavid du Colombier break;
62301a344a2SDavid du Colombier case Devmcat:
62401a344a2SDavid du Colombier c = '(';
62501a344a2SDavid du Colombier c1 = ')';
62601a344a2SDavid du Colombier /* fallthrough */
62701a344a2SDavid du Colombier case Devmlev:
62801a344a2SDavid du Colombier if (c == '\0') {
62901a344a2SDavid du Colombier c = '[';
63001a344a2SDavid du Colombier c1 = ']';
63101a344a2SDavid du Colombier }
63201a344a2SDavid du Colombier /* fallthrough */
63301a344a2SDavid du Colombier case Devmirr:
63401a344a2SDavid du Colombier if (c == '\0') {
63501a344a2SDavid du Colombier c = '{';
63601a344a2SDavid du Colombier c1 = '}';
63701a344a2SDavid du Colombier }
63801a344a2SDavid du Colombier if(d->cat.first == d->cat.last)
63901a344a2SDavid du Colombier sprint(s, "%c%Z%c", c, d->cat.first, c1);
64001a344a2SDavid du Colombier else if(d->cat.first->link == d->cat.last)
64101a344a2SDavid du Colombier sprint(s, "%c%Z%Z%c", c, d->cat.first, d->cat.last, c1);
64201a344a2SDavid du Colombier else
64301a344a2SDavid du Colombier sprint(s, "%c%Z-%Z%c", c, d->cat.first, d->cat.last, c1);
64401a344a2SDavid du Colombier break;
64501a344a2SDavid du Colombier case Devro:
64601a344a2SDavid du Colombier sprint(s, "o%Z%Z", d->ro.parent->cw.c, d->ro.parent->cw.w);
64701a344a2SDavid du Colombier break;
64801a344a2SDavid du Colombier case Devcw:
64901a344a2SDavid du Colombier sprint(s, "c%Z%Z", d->cw.c, d->cw.w);
65001a344a2SDavid du Colombier break;
65101a344a2SDavid du Colombier case Devjuke:
65201a344a2SDavid du Colombier sprint(s, "j%Z%Z", d->j.j, d->j.m);
65301a344a2SDavid du Colombier break;
65401a344a2SDavid du Colombier case Devfworm:
65501a344a2SDavid du Colombier sprint(s, "f%Z", d->fw.fw);
65601a344a2SDavid du Colombier break;
65701a344a2SDavid du Colombier case Devpart:
65801a344a2SDavid du Colombier sprint(s, "p(%Z)%ld.%ld", d->part.d, d->part.base, d->part.size);
65901a344a2SDavid du Colombier break;
66001a344a2SDavid du Colombier case Devswab:
66101a344a2SDavid du Colombier sprint(s, "x%Z", d->swab.d);
66201a344a2SDavid du Colombier break;
66301a344a2SDavid du Colombier case Devnone:
66401a344a2SDavid du Colombier sprint(s, "n");
66501a344a2SDavid du Colombier break;
66601a344a2SDavid du Colombier }
66701a344a2SDavid du Colombier out:
66801a344a2SDavid du Colombier return fmtstrcpy(fmt, s);
66901a344a2SDavid du Colombier }
67001a344a2SDavid du Colombier
67101a344a2SDavid du Colombier static int
Gfmt(Fmt * fmt)67201a344a2SDavid du Colombier Gfmt(Fmt* fmt)
67301a344a2SDavid du Colombier {
67401a344a2SDavid du Colombier int t;
67501a344a2SDavid du Colombier char *s;
67601a344a2SDavid du Colombier
67701a344a2SDavid du Colombier t = va_arg(fmt->args, int);
67801a344a2SDavid du Colombier s = "<badtag>";
67901a344a2SDavid du Colombier if(t >= 0 && t < MAXTAG)
68001a344a2SDavid du Colombier s = tagnames[t];
68101a344a2SDavid du Colombier return fmtstrcpy(fmt, s);
68201a344a2SDavid du Colombier }
68301a344a2SDavid du Colombier
68401a344a2SDavid du Colombier void
formatinit(void)68501a344a2SDavid du Colombier formatinit(void)
68601a344a2SDavid du Colombier {
68701a344a2SDavid du Colombier quotefmtinstall();
68801a344a2SDavid du Colombier // fmtinstall('Y', Yfmt); /* print channels */
68901a344a2SDavid du Colombier fmtinstall('Z', Zfmt); /* print devices */
69001a344a2SDavid du Colombier fmtinstall('G', Gfmt); /* print tags */
69101a344a2SDavid du Colombier fmtinstall('T', Tfmt); /* print times */
69201a344a2SDavid du Colombier // fmtinstall('E', eipfmt); /* print ether addresses */
69301a344a2SDavid du Colombier fmtinstall('I', eipfmt); /* print ip addresses */
69401a344a2SDavid du Colombier }
69501a344a2SDavid du Colombier
69601a344a2SDavid du Colombier void
rootream(Device * dev,Off addr)69701a344a2SDavid du Colombier rootream(Device *dev, Off addr)
69801a344a2SDavid du Colombier {
69901a344a2SDavid du Colombier Iobuf *p;
70001a344a2SDavid du Colombier Dentry *d;
70101a344a2SDavid du Colombier
70201a344a2SDavid du Colombier p = getbuf(dev, addr, Bmod|Bimm);
70301a344a2SDavid du Colombier memset(p->iobuf, 0, RBUFSIZE);
70401a344a2SDavid du Colombier settag(p, Tdir, QPROOT);
70501a344a2SDavid du Colombier d = getdir(p, 0);
70601a344a2SDavid du Colombier strcpy(d->name, "/");
70701a344a2SDavid du Colombier d->uid = -1;
70801a344a2SDavid du Colombier d->gid = -1;
70901a344a2SDavid du Colombier d->mode = DALLOC | DDIR |
71001a344a2SDavid du Colombier ((DREAD|DEXEC) << 6) |
71101a344a2SDavid du Colombier ((DREAD|DEXEC) << 3) |
71201a344a2SDavid du Colombier ((DREAD|DEXEC) << 0);
71301a344a2SDavid du Colombier d->qid = QID9P1(QPROOT|QPDIR,0);
71401a344a2SDavid du Colombier d->atime = time(nil);
71501a344a2SDavid du Colombier d->mtime = d->atime;
71601a344a2SDavid du Colombier d->muid = 0;
71701a344a2SDavid du Colombier putbuf(p);
71801a344a2SDavid du Colombier }
71901a344a2SDavid du Colombier
72001a344a2SDavid du Colombier void
superream(Device * dev,Off addr)72101a344a2SDavid du Colombier superream(Device *dev, Off addr)
72201a344a2SDavid du Colombier {
72301a344a2SDavid du Colombier Iobuf *p;
72401a344a2SDavid du Colombier Superb *s;
72501a344a2SDavid du Colombier Off i;
72601a344a2SDavid du Colombier
72701a344a2SDavid du Colombier p = getbuf(dev, addr, Bmod|Bimm);
72801a344a2SDavid du Colombier memset(p->iobuf, 0, RBUFSIZE);
72901a344a2SDavid du Colombier settag(p, Tsuper, QPSUPER);
73001a344a2SDavid du Colombier
73101a344a2SDavid du Colombier s = (Superb*)p->iobuf;
73201a344a2SDavid du Colombier s->fstart = 2;
73301a344a2SDavid du Colombier s->fsize = devsize(dev);
73401a344a2SDavid du Colombier s->fbuf.nfree = 1;
73501a344a2SDavid du Colombier s->qidgen = 10;
73601a344a2SDavid du Colombier for(i = s->fsize-1; i >= addr+2; i--)
73701a344a2SDavid du Colombier addfree(dev, i, s);
73801a344a2SDavid du Colombier putbuf(p);
73901a344a2SDavid du Colombier }
74001a344a2SDavid du Colombier
74101a344a2SDavid du Colombier struct
74201a344a2SDavid du Colombier {
74301a344a2SDavid du Colombier Lock;
74401a344a2SDavid du Colombier Msgbuf *smsgbuf;
74501a344a2SDavid du Colombier Msgbuf *lmsgbuf;
74601a344a2SDavid du Colombier } msgalloc;
74701a344a2SDavid du Colombier
74801a344a2SDavid du Colombier /*
74901a344a2SDavid du Colombier * pre-allocate some message buffers at boot time.
75001a344a2SDavid du Colombier * if this supply is exhausted, more will be allocated as needed.
75101a344a2SDavid du Colombier */
75201a344a2SDavid du Colombier void
mbinit(void)75301a344a2SDavid du Colombier mbinit(void)
75401a344a2SDavid du Colombier {
75501a344a2SDavid du Colombier Msgbuf *mb;
75601a344a2SDavid du Colombier Rabuf *rb;
75701a344a2SDavid du Colombier int i;
75801a344a2SDavid du Colombier
75901a344a2SDavid du Colombier lock(&msgalloc);
76001a344a2SDavid du Colombier unlock(&msgalloc);
76101a344a2SDavid du Colombier msgalloc.lmsgbuf = 0;
76201a344a2SDavid du Colombier msgalloc.smsgbuf = 0;
76301a344a2SDavid du Colombier for(i=0; i<conf.nlgmsg; i++) {
76401a344a2SDavid du Colombier mb = malloc(sizeof(Msgbuf));
76501a344a2SDavid du Colombier mb->magic = Mbmagic;
76601a344a2SDavid du Colombier mb->xdata = malloc(LARGEBUF+Slop);
76701a344a2SDavid du Colombier mb->flags = LARGE;
76801a344a2SDavid du Colombier mbfree(mb);
76901a344a2SDavid du Colombier cons.nlarge++;
77001a344a2SDavid du Colombier }
77101a344a2SDavid du Colombier for(i=0; i<conf.nsmmsg; i++) {
77201a344a2SDavid du Colombier mb = malloc(sizeof(Msgbuf));
77301a344a2SDavid du Colombier mb->magic = Mbmagic;
77401a344a2SDavid du Colombier mb->xdata = malloc(SMALLBUF+Slop);
77501a344a2SDavid du Colombier mb->flags = 0;
77601a344a2SDavid du Colombier mbfree(mb);
77701a344a2SDavid du Colombier cons.nsmall++;
77801a344a2SDavid du Colombier }
77901a344a2SDavid du Colombier memset(mballocs, 0, sizeof(mballocs));
78001a344a2SDavid du Colombier
78101a344a2SDavid du Colombier lock(&rabuflock);
78201a344a2SDavid du Colombier unlock(&rabuflock);
78301a344a2SDavid du Colombier rabuffree = 0;
78401a344a2SDavid du Colombier for(i=0; i<1000; i++) {
78501a344a2SDavid du Colombier rb = malloc(sizeof(*rb));
78601a344a2SDavid du Colombier rb->link = rabuffree;
78701a344a2SDavid du Colombier rabuffree = rb;
78801a344a2SDavid du Colombier }
78901a344a2SDavid du Colombier }
79001a344a2SDavid du Colombier
79101a344a2SDavid du Colombier Msgbuf*
mballoc(int count,Chan * cp,int category)79201a344a2SDavid du Colombier mballoc(int count, Chan *cp, int category)
79301a344a2SDavid du Colombier {
79401a344a2SDavid du Colombier Msgbuf *mb;
79501a344a2SDavid du Colombier
79601a344a2SDavid du Colombier lock(&msgalloc);
79701a344a2SDavid du Colombier if(count > SMALLBUF) {
79801a344a2SDavid du Colombier if(count > LARGEBUF)
79901a344a2SDavid du Colombier panic("msgbuf count");
80001a344a2SDavid du Colombier mb = msgalloc.lmsgbuf;
80101a344a2SDavid du Colombier if(mb == nil) {
80201a344a2SDavid du Colombier mb = malloc(sizeof(Msgbuf));
80301a344a2SDavid du Colombier mb->xdata = malloc(LARGEBUF+Slop);
80401a344a2SDavid du Colombier cons.nlarge++;
80501a344a2SDavid du Colombier } else
80601a344a2SDavid du Colombier msgalloc.lmsgbuf = mb->next;
80701a344a2SDavid du Colombier mb->flags = LARGE;
80801a344a2SDavid du Colombier } else {
80901a344a2SDavid du Colombier mb = msgalloc.smsgbuf;
81001a344a2SDavid du Colombier if(mb == nil) {
81101a344a2SDavid du Colombier mb = malloc(sizeof(Msgbuf));
81201a344a2SDavid du Colombier mb->xdata = malloc(SMALLBUF+Slop);
81301a344a2SDavid du Colombier cons.nsmall++;
81401a344a2SDavid du Colombier } else
81501a344a2SDavid du Colombier msgalloc.smsgbuf = mb->next;
81601a344a2SDavid du Colombier mb->flags = 0;
81701a344a2SDavid du Colombier }
81801a344a2SDavid du Colombier mballocs[category]++;
81901a344a2SDavid du Colombier unlock(&msgalloc);
82001a344a2SDavid du Colombier mb->magic = Mbmagic;
82101a344a2SDavid du Colombier mb->count = count;
82201a344a2SDavid du Colombier mb->chan = cp;
82301a344a2SDavid du Colombier mb->next = 0;
82401a344a2SDavid du Colombier mb->param = 0;
82501a344a2SDavid du Colombier mb->category = category;
82601a344a2SDavid du Colombier mb->data = mb->xdata+Slop;
82701a344a2SDavid du Colombier return mb;
82801a344a2SDavid du Colombier }
82901a344a2SDavid du Colombier
83001a344a2SDavid du Colombier void
mbfree(Msgbuf * mb)83101a344a2SDavid du Colombier mbfree(Msgbuf *mb)
83201a344a2SDavid du Colombier {
83301a344a2SDavid du Colombier if(mb == nil)
83401a344a2SDavid du Colombier return;
83501a344a2SDavid du Colombier assert(mb->magic == Mbmagic);
83601a344a2SDavid du Colombier if (mb->magic != Mbmagic)
83701a344a2SDavid du Colombier panic("mbfree: bad magic 0x%lux", mb->magic);
83801a344a2SDavid du Colombier if(mb->flags & BTRACE)
83901a344a2SDavid du Colombier print("mbfree: BTRACE cat=%d flags=%ux, caller %#p\n",
84001a344a2SDavid du Colombier mb->category, mb->flags, getcallerpc(&mb));
84101a344a2SDavid du Colombier
84201a344a2SDavid du Colombier if(mb->flags & FREE)
84301a344a2SDavid du Colombier panic("mbfree already free");
84401a344a2SDavid du Colombier
84501a344a2SDavid du Colombier lock(&msgalloc);
84601a344a2SDavid du Colombier mballocs[mb->category]--;
84701a344a2SDavid du Colombier mb->flags |= FREE;
84801a344a2SDavid du Colombier if(mb->flags & LARGE) {
84901a344a2SDavid du Colombier mb->next = msgalloc.lmsgbuf;
85001a344a2SDavid du Colombier msgalloc.lmsgbuf = mb;
85101a344a2SDavid du Colombier } else {
85201a344a2SDavid du Colombier mb->next = msgalloc.smsgbuf;
85301a344a2SDavid du Colombier msgalloc.smsgbuf = mb;
85401a344a2SDavid du Colombier }
85501a344a2SDavid du Colombier mb->data = 0;
85601a344a2SDavid du Colombier mb->magic = 0;
85701a344a2SDavid du Colombier unlock(&msgalloc);
85801a344a2SDavid du Colombier }
85901a344a2SDavid du Colombier
86001a344a2SDavid du Colombier /*
86101a344a2SDavid du Colombier * returns 1 if n is prime
86201a344a2SDavid du Colombier * used for adjusting lengths
86301a344a2SDavid du Colombier * of hashing things.
86401a344a2SDavid du Colombier * there is no need to be clever
86501a344a2SDavid du Colombier */
86601a344a2SDavid du Colombier int
prime(vlong n)86701a344a2SDavid du Colombier prime(vlong n)
86801a344a2SDavid du Colombier {
86901a344a2SDavid du Colombier long i;
87001a344a2SDavid du Colombier
87101a344a2SDavid du Colombier if((n%2) == 0)
87201a344a2SDavid du Colombier return 0;
87301a344a2SDavid du Colombier for(i=3;; i+=2) {
87401a344a2SDavid du Colombier if((n%i) == 0)
87501a344a2SDavid du Colombier return 0;
87601a344a2SDavid du Colombier if((vlong)i*i >= n)
87701a344a2SDavid du Colombier return 1;
87801a344a2SDavid du Colombier }
87901a344a2SDavid du Colombier }
88001a344a2SDavid du Colombier
88101a344a2SDavid du Colombier char*
getwrd(char * word,char * line)88201a344a2SDavid du Colombier getwrd(char *word, char *line)
88301a344a2SDavid du Colombier {
88401a344a2SDavid du Colombier int c, n;
88501a344a2SDavid du Colombier
88601a344a2SDavid du Colombier while(isascii(*line) && isspace(*line) && *line != '\n')
88701a344a2SDavid du Colombier line++;
88801a344a2SDavid du Colombier for(n = 0; n < Maxword; n++) {
88901a344a2SDavid du Colombier c = *line;
89001a344a2SDavid du Colombier if(c == '\0' || isascii(c) && isspace(c))
89101a344a2SDavid du Colombier break;
89201a344a2SDavid du Colombier line++;
89301a344a2SDavid du Colombier *word++ = c;
89401a344a2SDavid du Colombier }
89501a344a2SDavid du Colombier *word = 0;
89601a344a2SDavid du Colombier return line;
89701a344a2SDavid du Colombier }
89801a344a2SDavid du Colombier
89901a344a2SDavid du Colombier void
hexdump(void * a,int n)90001a344a2SDavid du Colombier hexdump(void *a, int n)
90101a344a2SDavid du Colombier {
90201a344a2SDavid du Colombier char s1[30], s2[4];
90301a344a2SDavid du Colombier uchar *p;
90401a344a2SDavid du Colombier int i;
90501a344a2SDavid du Colombier
90601a344a2SDavid du Colombier p = a;
90701a344a2SDavid du Colombier s1[0] = 0;
90801a344a2SDavid du Colombier for(i = 0; i < n; i++) {
90901a344a2SDavid du Colombier sprint(s2, " %.2ux", p[i]);
91001a344a2SDavid du Colombier strcat(s1, s2);
91101a344a2SDavid du Colombier if((i&7) == 7) {
91201a344a2SDavid du Colombier print("%s\n", s1);
91301a344a2SDavid du Colombier s1[0] = 0;
91401a344a2SDavid du Colombier }
91501a344a2SDavid du Colombier }
91601a344a2SDavid du Colombier if(s1[0])
91701a344a2SDavid du Colombier print("%s\n", s1);
91801a344a2SDavid du Colombier }
91901a344a2SDavid du Colombier
92001a344a2SDavid du Colombier void*
fs_recv(Queue * q,int)92101a344a2SDavid du Colombier fs_recv(Queue *q, int)
92201a344a2SDavid du Colombier {
92301a344a2SDavid du Colombier void *a;
92401a344a2SDavid du Colombier int i, c;
92501a344a2SDavid du Colombier
92601a344a2SDavid du Colombier if(q == nil)
92701a344a2SDavid du Colombier panic("recv null q");
92801a344a2SDavid du Colombier qlock(q);
92901a344a2SDavid du Colombier q->waitedfor = 1;
93001a344a2SDavid du Colombier while((c = q->count) <= 0)
93101a344a2SDavid du Colombier rsleep(&q->empty);
93201a344a2SDavid du Colombier i = q->loc;
93301a344a2SDavid du Colombier a = q->args[i];
93401a344a2SDavid du Colombier i++;
93501a344a2SDavid du Colombier if(i >= q->size)
93601a344a2SDavid du Colombier i = 0;
93701a344a2SDavid du Colombier q->loc = i;
93801a344a2SDavid du Colombier q->count = c-1;
93901a344a2SDavid du Colombier rwakeup(&q->full); /* no longer full */
94001a344a2SDavid du Colombier qunlock(q);
94101a344a2SDavid du Colombier return a;
94201a344a2SDavid du Colombier }
94301a344a2SDavid du Colombier
94401a344a2SDavid du Colombier void
fs_send(Queue * q,void * a)94501a344a2SDavid du Colombier fs_send(Queue *q, void *a)
94601a344a2SDavid du Colombier {
94701a344a2SDavid du Colombier int i, c;
94801a344a2SDavid du Colombier
94901a344a2SDavid du Colombier if(q == nil)
95001a344a2SDavid du Colombier panic("send null q");
95101a344a2SDavid du Colombier if(!q->waitedfor) {
95201a344a2SDavid du Colombier for (i = 0; i < 5 && !q->waitedfor; i++)
95301a344a2SDavid du Colombier sleep(1000);
95401a344a2SDavid du Colombier if(!q->waitedfor) {
95501a344a2SDavid du Colombier /* likely a bug; don't wait forever */
95601a344a2SDavid du Colombier print("no readers yet for %s q\n", q->name);
95701a344a2SDavid du Colombier abort();
95801a344a2SDavid du Colombier }
95901a344a2SDavid du Colombier }
96001a344a2SDavid du Colombier qlock(q);
96101a344a2SDavid du Colombier while((c = q->count) >= q->size)
96201a344a2SDavid du Colombier rsleep(&q->full);
96301a344a2SDavid du Colombier i = q->loc + c;
96401a344a2SDavid du Colombier if(i >= q->size)
96501a344a2SDavid du Colombier i -= q->size;
96601a344a2SDavid du Colombier q->args[i] = a;
96701a344a2SDavid du Colombier q->count = c+1;
96801a344a2SDavid du Colombier rwakeup(&q->empty); /* no longer empty */
96901a344a2SDavid du Colombier qunlock(q);
97001a344a2SDavid du Colombier }
97101a344a2SDavid du Colombier
97201a344a2SDavid du Colombier Queue*
newqueue(int size,char * name)97301a344a2SDavid du Colombier newqueue(int size, char *name)
97401a344a2SDavid du Colombier {
97501a344a2SDavid du Colombier Queue *q;
97601a344a2SDavid du Colombier
97701a344a2SDavid du Colombier q = malloc(sizeof(Queue) + (size-1)*sizeof(void*));
97801a344a2SDavid du Colombier q->size = size;
97901a344a2SDavid du Colombier q->full.l = q->empty.l = &q->QLock;
98001a344a2SDavid du Colombier q->name = name;
98101a344a2SDavid du Colombier return q;
98201a344a2SDavid du Colombier }
98301a344a2SDavid du Colombier
98401a344a2SDavid du Colombier int
devread(Device * d,Off b,void * c)98501a344a2SDavid du Colombier devread(Device *d, Off b, void *c)
98601a344a2SDavid du Colombier {
98701a344a2SDavid du Colombier int e;
98801a344a2SDavid du Colombier
98901a344a2SDavid du Colombier for (;;)
99001a344a2SDavid du Colombier switch(d->type) {
99101a344a2SDavid du Colombier case Devcw:
99201a344a2SDavid du Colombier return cwread(d, b, c);
99301a344a2SDavid du Colombier
99401a344a2SDavid du Colombier case Devjuke:
99501a344a2SDavid du Colombier d = d->j.m;
99601a344a2SDavid du Colombier break;
99701a344a2SDavid du Colombier
99801a344a2SDavid du Colombier case Devro:
99901a344a2SDavid du Colombier return roread(d, b, c);
100001a344a2SDavid du Colombier
100101a344a2SDavid du Colombier case Devwren:
100201a344a2SDavid du Colombier return wrenread(d, b, c);
100301a344a2SDavid du Colombier
100401a344a2SDavid du Colombier case Devworm:
100501a344a2SDavid du Colombier case Devlworm:
100601a344a2SDavid du Colombier return wormread(d, b, c);
100701a344a2SDavid du Colombier
100801a344a2SDavid du Colombier case Devfworm:
100901a344a2SDavid du Colombier return fwormread(d, b, c);
101001a344a2SDavid du Colombier
101101a344a2SDavid du Colombier case Devmcat:
101201a344a2SDavid du Colombier return mcatread(d, b, c);
101301a344a2SDavid du Colombier
101401a344a2SDavid du Colombier case Devmlev:
101501a344a2SDavid du Colombier return mlevread(d, b, c);
101601a344a2SDavid du Colombier
101701a344a2SDavid du Colombier case Devmirr:
101801a344a2SDavid du Colombier return mirrread(d, b, c);
101901a344a2SDavid du Colombier
102001a344a2SDavid du Colombier case Devpart:
102101a344a2SDavid du Colombier return partread(d, b, c);
102201a344a2SDavid du Colombier
102301a344a2SDavid du Colombier case Devswab:
102401a344a2SDavid du Colombier e = devread(d->swab.d, b, c);
102501a344a2SDavid du Colombier if(e == 0)
102601a344a2SDavid du Colombier swab(c, 0);
102701a344a2SDavid du Colombier return e;
102801a344a2SDavid du Colombier
102901a344a2SDavid du Colombier case Devnone:
103001a344a2SDavid du Colombier print("read from device none(%lld)\n", (Wideoff)b);
103101a344a2SDavid du Colombier return 1;
103201a344a2SDavid du Colombier default:
103301a344a2SDavid du Colombier panic("illegal device in devread: %Z %lld",
103401a344a2SDavid du Colombier d, (Wideoff)b);
103501a344a2SDavid du Colombier return 1;
103601a344a2SDavid du Colombier }
103701a344a2SDavid du Colombier }
103801a344a2SDavid du Colombier
103901a344a2SDavid du Colombier int
devwrite(Device * d,Off b,void * c)104001a344a2SDavid du Colombier devwrite(Device *d, Off b, void *c)
104101a344a2SDavid du Colombier {
104201a344a2SDavid du Colombier int e;
104301a344a2SDavid du Colombier
104401a344a2SDavid du Colombier /*
104501a344a2SDavid du Colombier * set readonly to non-0 to prevent all writes;
104601a344a2SDavid du Colombier * mainly for trying dangerous experiments.
104701a344a2SDavid du Colombier */
104801a344a2SDavid du Colombier if (readonly)
104901a344a2SDavid du Colombier return 0;
105001a344a2SDavid du Colombier for (;;)
105101a344a2SDavid du Colombier switch(d->type) {
105201a344a2SDavid du Colombier case Devcw:
105301a344a2SDavid du Colombier return cwwrite(d, b, c);
105401a344a2SDavid du Colombier
105501a344a2SDavid du Colombier case Devjuke:
105601a344a2SDavid du Colombier d = d->j.m;
105701a344a2SDavid du Colombier break;
105801a344a2SDavid du Colombier
105901a344a2SDavid du Colombier case Devro:
106001a344a2SDavid du Colombier print("write to ro device %Z(%lld)\n", d, (Wideoff)b);
106101a344a2SDavid du Colombier return 1;
106201a344a2SDavid du Colombier
106301a344a2SDavid du Colombier case Devwren:
106401a344a2SDavid du Colombier return wrenwrite(d, b, c);
106501a344a2SDavid du Colombier
106601a344a2SDavid du Colombier case Devworm:
106701a344a2SDavid du Colombier case Devlworm:
106801a344a2SDavid du Colombier return wormwrite(d, b, c);
106901a344a2SDavid du Colombier
107001a344a2SDavid du Colombier case Devfworm:
107101a344a2SDavid du Colombier return fwormwrite(d, b, c);
107201a344a2SDavid du Colombier
107301a344a2SDavid du Colombier case Devmcat:
107401a344a2SDavid du Colombier return mcatwrite(d, b, c);
107501a344a2SDavid du Colombier
107601a344a2SDavid du Colombier case Devmlev:
107701a344a2SDavid du Colombier return mlevwrite(d, b, c);
107801a344a2SDavid du Colombier
107901a344a2SDavid du Colombier case Devmirr:
108001a344a2SDavid du Colombier return mirrwrite(d, b, c);
108101a344a2SDavid du Colombier
108201a344a2SDavid du Colombier case Devpart:
108301a344a2SDavid du Colombier return partwrite(d, b, c);
108401a344a2SDavid du Colombier
108501a344a2SDavid du Colombier case Devswab:
108601a344a2SDavid du Colombier swab(c, 1);
108701a344a2SDavid du Colombier e = devwrite(d->swab.d, b, c);
108801a344a2SDavid du Colombier swab(c, 0);
108901a344a2SDavid du Colombier return e;
109001a344a2SDavid du Colombier
109101a344a2SDavid du Colombier case Devnone:
109201a344a2SDavid du Colombier /* checktag() can generate blocks with type devnone */
109301a344a2SDavid du Colombier return 0;
109401a344a2SDavid du Colombier default:
109501a344a2SDavid du Colombier panic("illegal device in devwrite: %Z %lld",
109601a344a2SDavid du Colombier d, (Wideoff)b);
109701a344a2SDavid du Colombier return 1;
109801a344a2SDavid du Colombier }
109901a344a2SDavid du Colombier }
110001a344a2SDavid du Colombier
110101a344a2SDavid du Colombier Devsize
devsize(Device * d)110201a344a2SDavid du Colombier devsize(Device *d)
110301a344a2SDavid du Colombier {
110401a344a2SDavid du Colombier for (;;)
110501a344a2SDavid du Colombier switch(d->type) {
110601a344a2SDavid du Colombier case Devcw:
110701a344a2SDavid du Colombier case Devro:
110801a344a2SDavid du Colombier return cwsize(d);
110901a344a2SDavid du Colombier
111001a344a2SDavid du Colombier case Devjuke:
111101a344a2SDavid du Colombier d = d->j.m;
111201a344a2SDavid du Colombier break;
111301a344a2SDavid du Colombier
111401a344a2SDavid du Colombier case Devwren:
111501a344a2SDavid du Colombier return wrensize(d);
111601a344a2SDavid du Colombier
111701a344a2SDavid du Colombier case Devworm:
111801a344a2SDavid du Colombier case Devlworm:
111901a344a2SDavid du Colombier return wormsize(d);
112001a344a2SDavid du Colombier
112101a344a2SDavid du Colombier case Devfworm:
112201a344a2SDavid du Colombier return fwormsize(d);
112301a344a2SDavid du Colombier
112401a344a2SDavid du Colombier case Devmcat:
112501a344a2SDavid du Colombier return mcatsize(d);
112601a344a2SDavid du Colombier
112701a344a2SDavid du Colombier case Devmlev:
112801a344a2SDavid du Colombier return mlevsize(d);
112901a344a2SDavid du Colombier
113001a344a2SDavid du Colombier case Devmirr:
113101a344a2SDavid du Colombier return mirrsize(d);
113201a344a2SDavid du Colombier
113301a344a2SDavid du Colombier case Devpart:
113401a344a2SDavid du Colombier return partsize(d);
113501a344a2SDavid du Colombier
113601a344a2SDavid du Colombier case Devswab:
113701a344a2SDavid du Colombier d = d->swab.d;
113801a344a2SDavid du Colombier break;
113901a344a2SDavid du Colombier default:
114001a344a2SDavid du Colombier panic("illegal device in devsize: %Z", d);
114101a344a2SDavid du Colombier return 0;
114201a344a2SDavid du Colombier }
114301a344a2SDavid du Colombier }
114401a344a2SDavid du Colombier
114501a344a2SDavid du Colombier /* result is malloced */
114601a344a2SDavid du Colombier char *
sdof(Device * d)114701a344a2SDavid du Colombier sdof(Device *d)
114801a344a2SDavid du Colombier {
114901a344a2SDavid du Colombier static char name[256];
115001a344a2SDavid du Colombier
115101a344a2SDavid du Colombier for (;;)
115201a344a2SDavid du Colombier switch(d->type) {
115301a344a2SDavid du Colombier case Devjuke:
115401a344a2SDavid du Colombier d = d->j.j; /* robotics */
115501a344a2SDavid du Colombier break;
115601a344a2SDavid du Colombier case Devwren:
115701a344a2SDavid du Colombier snprint(name, sizeof name, "/dev/sd%d%d", d->wren.ctrl,
115801a344a2SDavid du Colombier d->wren.targ);
115901a344a2SDavid du Colombier return strdup(name);
116001a344a2SDavid du Colombier case Devswab:
116101a344a2SDavid du Colombier d = d->swab.d;
116201a344a2SDavid du Colombier break;
116301a344a2SDavid du Colombier default:
116401a344a2SDavid du Colombier panic("illegal device in sdof: %Z", d);
116501a344a2SDavid du Colombier return nil;
116601a344a2SDavid du Colombier }
116701a344a2SDavid du Colombier }
116801a344a2SDavid du Colombier
116901a344a2SDavid du Colombier Off
superaddr(Device * d)117001a344a2SDavid du Colombier superaddr(Device *d)
117101a344a2SDavid du Colombier {
117201a344a2SDavid du Colombier for (;;)
117301a344a2SDavid du Colombier switch(d->type) {
117401a344a2SDavid du Colombier default:
117501a344a2SDavid du Colombier return SUPER_ADDR;
117601a344a2SDavid du Colombier case Devcw:
117701a344a2SDavid du Colombier case Devro:
117801a344a2SDavid du Colombier return cwsaddr(d);
117901a344a2SDavid du Colombier case Devswab:
118001a344a2SDavid du Colombier d = d->swab.d;
118101a344a2SDavid du Colombier break;
118201a344a2SDavid du Colombier }
118301a344a2SDavid du Colombier }
118401a344a2SDavid du Colombier
118501a344a2SDavid du Colombier Off
getraddr(Device * d)118601a344a2SDavid du Colombier getraddr(Device *d)
118701a344a2SDavid du Colombier {
118801a344a2SDavid du Colombier for (;;)
118901a344a2SDavid du Colombier switch(d->type) {
119001a344a2SDavid du Colombier default:
119101a344a2SDavid du Colombier return ROOT_ADDR;
119201a344a2SDavid du Colombier case Devcw:
119301a344a2SDavid du Colombier case Devro:
119401a344a2SDavid du Colombier return cwraddr(d);
119501a344a2SDavid du Colombier case Devswab:
119601a344a2SDavid du Colombier d = d->swab.d;
119701a344a2SDavid du Colombier break;
119801a344a2SDavid du Colombier }
119901a344a2SDavid du Colombier }
120001a344a2SDavid du Colombier
120101a344a2SDavid du Colombier void
devream(Device * d,int top)120201a344a2SDavid du Colombier devream(Device *d, int top)
120301a344a2SDavid du Colombier {
120401a344a2SDavid du Colombier Device *l;
120501a344a2SDavid du Colombier
120601a344a2SDavid du Colombier loop:
120701a344a2SDavid du Colombier print("\tdevream: %Z %d\n", d, top);
120801a344a2SDavid du Colombier switch(d->type) {
120901a344a2SDavid du Colombier default:
121001a344a2SDavid du Colombier print("ream: unknown dev type %Z\n", d);
121101a344a2SDavid du Colombier return;
121201a344a2SDavid du Colombier
121301a344a2SDavid du Colombier case Devcw:
121401a344a2SDavid du Colombier devream(d->cw.w, 0);
121501a344a2SDavid du Colombier devream(d->cw.c, 0);
121601a344a2SDavid du Colombier if(top) {
121701a344a2SDavid du Colombier wlock(&mainlock);
121801a344a2SDavid du Colombier cwream(d);
121901a344a2SDavid du Colombier wunlock(&mainlock);
122001a344a2SDavid du Colombier }
122101a344a2SDavid du Colombier devinit(d);
122201a344a2SDavid du Colombier return;
122301a344a2SDavid du Colombier
122401a344a2SDavid du Colombier case Devfworm:
122501a344a2SDavid du Colombier devream(d->fw.fw, 0);
122601a344a2SDavid du Colombier fwormream(d);
122701a344a2SDavid du Colombier break;
122801a344a2SDavid du Colombier
122901a344a2SDavid du Colombier case Devpart:
123001a344a2SDavid du Colombier devream(d->part.d, 0);
123101a344a2SDavid du Colombier break;
123201a344a2SDavid du Colombier
123301a344a2SDavid du Colombier case Devmlev:
123401a344a2SDavid du Colombier case Devmcat:
123501a344a2SDavid du Colombier case Devmirr:
123601a344a2SDavid du Colombier for(l=d->cat.first; l; l=l->link)
123701a344a2SDavid du Colombier devream(l, 0);
123801a344a2SDavid du Colombier break;
123901a344a2SDavid du Colombier
124001a344a2SDavid du Colombier case Devjuke:
124101a344a2SDavid du Colombier case Devworm:
124201a344a2SDavid du Colombier case Devlworm:
124301a344a2SDavid du Colombier case Devwren:
124401a344a2SDavid du Colombier break;
124501a344a2SDavid du Colombier
124601a344a2SDavid du Colombier case Devswab:
124701a344a2SDavid du Colombier d = d->swab.d;
124801a344a2SDavid du Colombier goto loop;
124901a344a2SDavid du Colombier }
125001a344a2SDavid du Colombier devinit(d);
125101a344a2SDavid du Colombier if(top) {
125201a344a2SDavid du Colombier wlock(&mainlock);
125301a344a2SDavid du Colombier rootream(d, ROOT_ADDR);
125401a344a2SDavid du Colombier superream(d, SUPER_ADDR);
125501a344a2SDavid du Colombier wunlock(&mainlock);
125601a344a2SDavid du Colombier }
125701a344a2SDavid du Colombier }
125801a344a2SDavid du Colombier
125901a344a2SDavid du Colombier void
devrecover(Device * d)126001a344a2SDavid du Colombier devrecover(Device *d)
126101a344a2SDavid du Colombier {
126201a344a2SDavid du Colombier for (;;) {
126301a344a2SDavid du Colombier print("recover: %Z\n", d);
126401a344a2SDavid du Colombier switch(d->type) {
126501a344a2SDavid du Colombier default:
126601a344a2SDavid du Colombier print("recover: unknown dev type %Z\n", d);
126701a344a2SDavid du Colombier return;
126801a344a2SDavid du Colombier
126901a344a2SDavid du Colombier case Devcw:
127001a344a2SDavid du Colombier wlock(&mainlock); /* recover */
127101a344a2SDavid du Colombier cwrecover(d);
127201a344a2SDavid du Colombier wunlock(&mainlock);
127301a344a2SDavid du Colombier return;
127401a344a2SDavid du Colombier
127501a344a2SDavid du Colombier case Devswab:
127601a344a2SDavid du Colombier d = d->swab.d;
127701a344a2SDavid du Colombier break;
127801a344a2SDavid du Colombier }
127901a344a2SDavid du Colombier }
128001a344a2SDavid du Colombier }
128101a344a2SDavid du Colombier
128201a344a2SDavid du Colombier void
devinit(Device * d)128301a344a2SDavid du Colombier devinit(Device *d)
128401a344a2SDavid du Colombier {
128501a344a2SDavid du Colombier for (;;) {
128601a344a2SDavid du Colombier if(d->init)
128701a344a2SDavid du Colombier return;
128801a344a2SDavid du Colombier d->init = 1;
128901a344a2SDavid du Colombier print("\tdevinit %Z\n", d);
129001a344a2SDavid du Colombier switch(d->type) {
129101a344a2SDavid du Colombier default:
129201a344a2SDavid du Colombier print("devinit unknown device %Z\n", d);
129301a344a2SDavid du Colombier return;
129401a344a2SDavid du Colombier
129501a344a2SDavid du Colombier case Devro:
129601a344a2SDavid du Colombier cwinit(d->ro.parent);
129701a344a2SDavid du Colombier return;
129801a344a2SDavid du Colombier
129901a344a2SDavid du Colombier case Devcw:
130001a344a2SDavid du Colombier cwinit(d);
130101a344a2SDavid du Colombier return;
130201a344a2SDavid du Colombier
130301a344a2SDavid du Colombier case Devjuke:
130401a344a2SDavid du Colombier jukeinit(d);
130501a344a2SDavid du Colombier return;
130601a344a2SDavid du Colombier
130701a344a2SDavid du Colombier case Devwren:
130801a344a2SDavid du Colombier wreninit(d);
130901a344a2SDavid du Colombier return;
131001a344a2SDavid du Colombier
131101a344a2SDavid du Colombier case Devworm:
131201a344a2SDavid du Colombier case Devlworm:
131301a344a2SDavid du Colombier return;
131401a344a2SDavid du Colombier
131501a344a2SDavid du Colombier case Devfworm:
131601a344a2SDavid du Colombier fworminit(d);
131701a344a2SDavid du Colombier return;
131801a344a2SDavid du Colombier
131901a344a2SDavid du Colombier case Devmcat:
132001a344a2SDavid du Colombier mcatinit(d);
132101a344a2SDavid du Colombier return;
132201a344a2SDavid du Colombier
132301a344a2SDavid du Colombier case Devmlev:
132401a344a2SDavid du Colombier mlevinit(d);
132501a344a2SDavid du Colombier return;
132601a344a2SDavid du Colombier
132701a344a2SDavid du Colombier case Devmirr:
132801a344a2SDavid du Colombier mirrinit(d);
132901a344a2SDavid du Colombier return;
133001a344a2SDavid du Colombier
133101a344a2SDavid du Colombier case Devpart:
133201a344a2SDavid du Colombier partinit(d);
133301a344a2SDavid du Colombier return;
133401a344a2SDavid du Colombier
133501a344a2SDavid du Colombier case Devswab:
133601a344a2SDavid du Colombier d = d->swab.d;
133701a344a2SDavid du Colombier break;
133801a344a2SDavid du Colombier
133901a344a2SDavid du Colombier case Devnone:
134001a344a2SDavid du Colombier print("devinit of Devnone\n");
134101a344a2SDavid du Colombier return;
134201a344a2SDavid du Colombier }
134301a344a2SDavid du Colombier }
134401a344a2SDavid du Colombier }
134501a344a2SDavid du Colombier
134601a344a2SDavid du Colombier void
swab2(void * c)134701a344a2SDavid du Colombier swab2(void *c)
134801a344a2SDavid du Colombier {
134901a344a2SDavid du Colombier uchar *p;
135001a344a2SDavid du Colombier int t;
135101a344a2SDavid du Colombier
135201a344a2SDavid du Colombier p = c;
135301a344a2SDavid du Colombier
135401a344a2SDavid du Colombier t = p[0];
135501a344a2SDavid du Colombier p[0] = p[1];
135601a344a2SDavid du Colombier p[1] = t;
135701a344a2SDavid du Colombier }
135801a344a2SDavid du Colombier
135901a344a2SDavid du Colombier void
swab4(void * c)136001a344a2SDavid du Colombier swab4(void *c)
136101a344a2SDavid du Colombier {
136201a344a2SDavid du Colombier uchar *p;
136301a344a2SDavid du Colombier int t;
136401a344a2SDavid du Colombier
136501a344a2SDavid du Colombier p = c;
136601a344a2SDavid du Colombier
136701a344a2SDavid du Colombier t = p[0];
136801a344a2SDavid du Colombier p[0] = p[3];
136901a344a2SDavid du Colombier p[3] = t;
137001a344a2SDavid du Colombier
137101a344a2SDavid du Colombier t = p[1];
137201a344a2SDavid du Colombier p[1] = p[2];
137301a344a2SDavid du Colombier p[2] = t;
137401a344a2SDavid du Colombier }
137501a344a2SDavid du Colombier
137601a344a2SDavid du Colombier void
swab8(void * c)137701a344a2SDavid du Colombier swab8(void *c)
137801a344a2SDavid du Colombier {
137901a344a2SDavid du Colombier uchar *p;
138001a344a2SDavid du Colombier int t;
138101a344a2SDavid du Colombier
138201a344a2SDavid du Colombier p = c;
138301a344a2SDavid du Colombier
138401a344a2SDavid du Colombier t = p[0];
138501a344a2SDavid du Colombier p[0] = p[7];
138601a344a2SDavid du Colombier p[7] = t;
138701a344a2SDavid du Colombier
138801a344a2SDavid du Colombier t = p[1];
138901a344a2SDavid du Colombier p[1] = p[6];
139001a344a2SDavid du Colombier p[6] = t;
139101a344a2SDavid du Colombier
139201a344a2SDavid du Colombier t = p[2];
139301a344a2SDavid du Colombier p[2] = p[5];
139401a344a2SDavid du Colombier p[5] = t;
139501a344a2SDavid du Colombier
139601a344a2SDavid du Colombier t = p[3];
139701a344a2SDavid du Colombier p[3] = p[4];
139801a344a2SDavid du Colombier p[4] = t;
139901a344a2SDavid du Colombier }
140001a344a2SDavid du Colombier
140101a344a2SDavid du Colombier /*
140201a344a2SDavid du Colombier * swab a block
140301a344a2SDavid du Colombier * flag = 0 -- convert from foreign to native
140401a344a2SDavid du Colombier * flag = 1 -- convert from native to foreign
140501a344a2SDavid du Colombier */
140601a344a2SDavid du Colombier void
swab(void * c,int flag)140701a344a2SDavid du Colombier swab(void *c, int flag)
140801a344a2SDavid du Colombier {
140901a344a2SDavid du Colombier uchar *p;
141001a344a2SDavid du Colombier Tag *t;
141101a344a2SDavid du Colombier int i, j;
141201a344a2SDavid du Colombier Dentry *d;
141301a344a2SDavid du Colombier Cache *h;
141401a344a2SDavid du Colombier Bucket *b;
141501a344a2SDavid du Colombier Superb *s;
141601a344a2SDavid du Colombier Fbuf *f;
141701a344a2SDavid du Colombier Off *l;
141801a344a2SDavid du Colombier
141901a344a2SDavid du Colombier /* swab the tag */
142001a344a2SDavid du Colombier p = (uchar*)c;
142101a344a2SDavid du Colombier t = (Tag*)(p + BUFSIZE);
142201a344a2SDavid du Colombier if(!flag) {
142301a344a2SDavid du Colombier swab2(&t->pad);
142401a344a2SDavid du Colombier swab2(&t->tag);
142501a344a2SDavid du Colombier swaboff(&t->path);
142601a344a2SDavid du Colombier }
142701a344a2SDavid du Colombier
142801a344a2SDavid du Colombier /* swab each block type */
142901a344a2SDavid du Colombier switch(t->tag) {
143001a344a2SDavid du Colombier
143101a344a2SDavid du Colombier default:
143201a344a2SDavid du Colombier print("no swab for tag=%G rw=%d\n", t->tag, flag);
143301a344a2SDavid du Colombier for(j=0; j<16; j++)
143401a344a2SDavid du Colombier print(" %.2x", p[BUFSIZE+j]);
143501a344a2SDavid du Colombier print("\n");
143601a344a2SDavid du Colombier for(i=0; i<16; i++) {
143701a344a2SDavid du Colombier print("%.4x", i*16);
143801a344a2SDavid du Colombier for(j=0; j<16; j++)
143901a344a2SDavid du Colombier print(" %.2x", p[i*16+j]);
144001a344a2SDavid du Colombier print("\n");
144101a344a2SDavid du Colombier }
144201a344a2SDavid du Colombier panic("swab");
144301a344a2SDavid du Colombier break;
144401a344a2SDavid du Colombier
144501a344a2SDavid du Colombier case Tsuper:
144601a344a2SDavid du Colombier s = (Superb*)p;
144701a344a2SDavid du Colombier swaboff(&s->fbuf.nfree);
144801a344a2SDavid du Colombier for(i=0; i<FEPERBUF; i++)
144901a344a2SDavid du Colombier swaboff(&s->fbuf.free[i]);
145001a344a2SDavid du Colombier swaboff(&s->fstart);
145101a344a2SDavid du Colombier swaboff(&s->fsize);
145201a344a2SDavid du Colombier swaboff(&s->tfree);
145301a344a2SDavid du Colombier swaboff(&s->qidgen);
145401a344a2SDavid du Colombier swaboff(&s->cwraddr);
145501a344a2SDavid du Colombier swaboff(&s->roraddr);
145601a344a2SDavid du Colombier swaboff(&s->last);
145701a344a2SDavid du Colombier swaboff(&s->next);
145801a344a2SDavid du Colombier break;
145901a344a2SDavid du Colombier
146001a344a2SDavid du Colombier case Tdir:
146101a344a2SDavid du Colombier for(i=0; i<DIRPERBUF; i++) {
146201a344a2SDavid du Colombier d = (Dentry*)p + i;
146301a344a2SDavid du Colombier swab2(&d->uid);
146401a344a2SDavid du Colombier swab2(&d->gid);
146501a344a2SDavid du Colombier swab2(&d->mode);
146601a344a2SDavid du Colombier swab2(&d->muid);
146701a344a2SDavid du Colombier swaboff(&d->qid.path);
146801a344a2SDavid du Colombier swab4(&d->qid.version);
146901a344a2SDavid du Colombier swaboff(&d->size);
147001a344a2SDavid du Colombier for(j=0; j<NDBLOCK; j++)
147101a344a2SDavid du Colombier swaboff(&d->dblock[j]);
147201a344a2SDavid du Colombier for (j = 0; j < NIBLOCK; j++)
147301a344a2SDavid du Colombier swaboff(&d->iblocks[j]);
147401a344a2SDavid du Colombier swab4(&d->atime);
147501a344a2SDavid du Colombier swab4(&d->mtime);
147601a344a2SDavid du Colombier }
147701a344a2SDavid du Colombier break;
147801a344a2SDavid du Colombier
147901a344a2SDavid du Colombier case Tind1:
148001a344a2SDavid du Colombier case Tind2:
148101a344a2SDavid du Colombier #ifndef COMPAT32
148201a344a2SDavid du Colombier case Tind3:
148301a344a2SDavid du Colombier case Tind4:
148401a344a2SDavid du Colombier /* add more Tind tags here ... */
148501a344a2SDavid du Colombier #endif
148601a344a2SDavid du Colombier l = (Off *)p;
148701a344a2SDavid du Colombier for(i=0; i<INDPERBUF; i++) {
148801a344a2SDavid du Colombier swaboff(l);
148901a344a2SDavid du Colombier l++;
149001a344a2SDavid du Colombier }
149101a344a2SDavid du Colombier break;
149201a344a2SDavid du Colombier
149301a344a2SDavid du Colombier case Tfree:
149401a344a2SDavid du Colombier f = (Fbuf*)p;
149501a344a2SDavid du Colombier swaboff(&f->nfree);
149601a344a2SDavid du Colombier for(i=0; i<FEPERBUF; i++)
149701a344a2SDavid du Colombier swaboff(&f->free[i]);
149801a344a2SDavid du Colombier break;
149901a344a2SDavid du Colombier
150001a344a2SDavid du Colombier case Tbuck:
150101a344a2SDavid du Colombier for(i=0; i<BKPERBLK; i++) {
150201a344a2SDavid du Colombier b = (Bucket*)p + i;
150301a344a2SDavid du Colombier swab4(&b->agegen);
150401a344a2SDavid du Colombier for(j=0; j<CEPERBK; j++) {
150501a344a2SDavid du Colombier swab2(&b->entry[j].age);
150601a344a2SDavid du Colombier swab2(&b->entry[j].state);
150701a344a2SDavid du Colombier swaboff(&b->entry[j].waddr);
150801a344a2SDavid du Colombier }
150901a344a2SDavid du Colombier }
151001a344a2SDavid du Colombier break;
151101a344a2SDavid du Colombier
151201a344a2SDavid du Colombier case Tcache:
151301a344a2SDavid du Colombier h = (Cache*)p;
151401a344a2SDavid du Colombier swaboff(&h->maddr);
151501a344a2SDavid du Colombier swaboff(&h->msize);
151601a344a2SDavid du Colombier swaboff(&h->caddr);
151701a344a2SDavid du Colombier swaboff(&h->csize);
151801a344a2SDavid du Colombier swaboff(&h->fsize);
151901a344a2SDavid du Colombier swaboff(&h->wsize);
152001a344a2SDavid du Colombier swaboff(&h->wmax);
152101a344a2SDavid du Colombier swaboff(&h->sbaddr);
152201a344a2SDavid du Colombier swaboff(&h->cwraddr);
152301a344a2SDavid du Colombier swaboff(&h->roraddr);
152401a344a2SDavid du Colombier swab4(&h->toytime);
152501a344a2SDavid du Colombier swab4(&h->time);
152601a344a2SDavid du Colombier break;
152701a344a2SDavid du Colombier
152801a344a2SDavid du Colombier case Tnone: // unitialized
152901a344a2SDavid du Colombier case Tfile: // someone elses problem
153001a344a2SDavid du Colombier case Tvirgo: // bit map -- all bytes
153101a344a2SDavid du Colombier case Tconfig: // configuration string -- all bytes
153201a344a2SDavid du Colombier break;
153301a344a2SDavid du Colombier }
153401a344a2SDavid du Colombier
153501a344a2SDavid du Colombier /* swab the tag */
153601a344a2SDavid du Colombier if(flag) {
153701a344a2SDavid du Colombier swab2(&t->pad);
153801a344a2SDavid du Colombier swab2(&t->tag);
153901a344a2SDavid du Colombier swaboff(&t->path);
154001a344a2SDavid du Colombier }
154101a344a2SDavid du Colombier }
1542