13e12c5d1SDavid du Colombier #include "all.h"
23e12c5d1SDavid du Colombier
39a747e4fSDavid du Colombier Lock wpathlock;
49a747e4fSDavid du Colombier
57dd7cddfSDavid du Colombier struct {
67dd7cddfSDavid du Colombier Lock flock;
77dd7cddfSDavid du Colombier File* ffree; /* free file structures */
87dd7cddfSDavid du Colombier Wpath* wfree;
97dd7cddfSDavid du Colombier } suballoc;
107dd7cddfSDavid du Colombier
117dd7cddfSDavid du Colombier enum{
127dd7cddfSDavid du Colombier Finc= 128, /* allocation chunksize for files */
137dd7cddfSDavid du Colombier Fmax= 10000, /* maximum file structures to be allocated */
147dd7cddfSDavid du Colombier
157dd7cddfSDavid du Colombier Winc= 8*128, /* allocation chunksize for wpath */
167dd7cddfSDavid du Colombier Wmax= 8*10000, /* maximum wpath structures to be allocated */
177dd7cddfSDavid du Colombier };
187dd7cddfSDavid du Colombier
197dd7cddfSDavid du Colombier
203e12c5d1SDavid du Colombier Filsys*
fsstr(char * p)213e12c5d1SDavid du Colombier fsstr(char *p)
223e12c5d1SDavid du Colombier {
233e12c5d1SDavid du Colombier Filsys *fs;
243e12c5d1SDavid du Colombier
257dd7cddfSDavid du Colombier for(fs=filesys; fs->name; fs++)
263e12c5d1SDavid du Colombier if(strcmp(fs->name, p) == 0)
273e12c5d1SDavid du Colombier return fs;
283e12c5d1SDavid du Colombier return 0;
293e12c5d1SDavid du Colombier }
303e12c5d1SDavid du Colombier
313e12c5d1SDavid du Colombier void
fileinit(Chan * cp)323e12c5d1SDavid du Colombier fileinit(Chan *cp)
333e12c5d1SDavid du Colombier {
343e12c5d1SDavid du Colombier File *f;
353e12c5d1SDavid du Colombier Tlock *t;
363e12c5d1SDavid du Colombier
373e12c5d1SDavid du Colombier loop:
383e12c5d1SDavid du Colombier lock(&cp->flock);
393e12c5d1SDavid du Colombier f = cp->flist;
403e12c5d1SDavid du Colombier if(!f) {
413e12c5d1SDavid du Colombier unlock(&cp->flock);
423e12c5d1SDavid du Colombier return;
433e12c5d1SDavid du Colombier }
443e12c5d1SDavid du Colombier cp->flist = f->next;
453e12c5d1SDavid du Colombier unlock(&cp->flock);
463e12c5d1SDavid du Colombier
473e12c5d1SDavid du Colombier qlock(f);
483e12c5d1SDavid du Colombier if(t = f->tlock) {
493e12c5d1SDavid du Colombier t->time = 0;
503e12c5d1SDavid du Colombier f->tlock = 0;
513e12c5d1SDavid du Colombier }
523e12c5d1SDavid du Colombier if(f->open & FREMOV)
533e12c5d1SDavid du Colombier doremove(f, 0);
543e12c5d1SDavid du Colombier freewp(f->wpath);
553e12c5d1SDavid du Colombier f->open = 0;
563e12c5d1SDavid du Colombier f->cp = 0;
573e12c5d1SDavid du Colombier qunlock(f);
583e12c5d1SDavid du Colombier
593e12c5d1SDavid du Colombier goto loop;
603e12c5d1SDavid du Colombier }
613e12c5d1SDavid du Colombier
623e12c5d1SDavid du Colombier /*
633e12c5d1SDavid du Colombier * returns a locked file structure
643e12c5d1SDavid du Colombier */
653e12c5d1SDavid du Colombier File*
filep(Chan * cp,int fid,int flag)663e12c5d1SDavid du Colombier filep(Chan *cp, int fid, int flag)
673e12c5d1SDavid du Colombier {
683e12c5d1SDavid du Colombier File *f, *prev;
693e12c5d1SDavid du Colombier
703e12c5d1SDavid du Colombier if(fid == NOF)
713e12c5d1SDavid du Colombier return 0;
723e12c5d1SDavid du Colombier
733e12c5d1SDavid du Colombier loop:
743e12c5d1SDavid du Colombier lock(&cp->flock);
753e12c5d1SDavid du Colombier for(prev=0,f=cp->flist; f; prev=f,f=f->next) {
763e12c5d1SDavid du Colombier if(f->fid != fid)
773e12c5d1SDavid du Colombier continue;
783e12c5d1SDavid du Colombier if(prev) {
793e12c5d1SDavid du Colombier prev->next = f->next;
803e12c5d1SDavid du Colombier f->next = cp->flist;
813e12c5d1SDavid du Colombier cp->flist = f;
823e12c5d1SDavid du Colombier }
833e12c5d1SDavid du Colombier goto out;
843e12c5d1SDavid du Colombier }
853e12c5d1SDavid du Colombier if(flag) {
863e12c5d1SDavid du Colombier f = newfp(cp);
873e12c5d1SDavid du Colombier if(f) {
883e12c5d1SDavid du Colombier f->fid = fid;
893e12c5d1SDavid du Colombier goto out;
903e12c5d1SDavid du Colombier }
913e12c5d1SDavid du Colombier }
929a747e4fSDavid du Colombier else print("cannot find %p.%d (list=%p)\n", cp, fid, cp->flist);
933e12c5d1SDavid du Colombier unlock(&cp->flock);
943e12c5d1SDavid du Colombier return 0;
953e12c5d1SDavid du Colombier
963e12c5d1SDavid du Colombier out:
973e12c5d1SDavid du Colombier unlock(&cp->flock);
983e12c5d1SDavid du Colombier qlock(f);
993e12c5d1SDavid du Colombier if(f->fid != fid) {
1003e12c5d1SDavid du Colombier qunlock(f);
1013e12c5d1SDavid du Colombier goto loop;
1023e12c5d1SDavid du Colombier }
1033e12c5d1SDavid du Colombier return f;
1043e12c5d1SDavid du Colombier }
1053e12c5d1SDavid du Colombier
1067dd7cddfSDavid du Colombier void
sublockinit(void)1077dd7cddfSDavid du Colombier sublockinit(void)
1087dd7cddfSDavid du Colombier {
1097dd7cddfSDavid du Colombier lock(&suballoc.flock);
1109a747e4fSDavid du Colombier lock(&wpathlock);
1117dd7cddfSDavid du Colombier conf.nfile = 0;
1127dd7cddfSDavid du Colombier conf.nwpath = 0;
1137dd7cddfSDavid du Colombier unlock(&suballoc.flock);
1149a747e4fSDavid du Colombier unlock(&wpathlock);
1157dd7cddfSDavid du Colombier }
1167dd7cddfSDavid du Colombier
1173e12c5d1SDavid du Colombier /*
1183e12c5d1SDavid du Colombier * always called with cp->flock locked
1193e12c5d1SDavid du Colombier */
1203e12c5d1SDavid du Colombier File*
newfp(Chan * cp)1213e12c5d1SDavid du Colombier newfp(Chan *cp)
1223e12c5d1SDavid du Colombier {
1237dd7cddfSDavid du Colombier File *f, *e;
1243e12c5d1SDavid du Colombier
1257dd7cddfSDavid du Colombier retry:
1267dd7cddfSDavid du Colombier lock(&suballoc.flock);
1277dd7cddfSDavid du Colombier f = suballoc.ffree;
1287dd7cddfSDavid du Colombier if(f != nil){
1297dd7cddfSDavid du Colombier suballoc.ffree = f->list;
1307dd7cddfSDavid du Colombier unlock(&suballoc.flock);
1317dd7cddfSDavid du Colombier f->list = 0;
1323e12c5d1SDavid du Colombier f->cp = cp;
1333e12c5d1SDavid du Colombier f->next = cp->flist;
1343e12c5d1SDavid du Colombier f->wpath = 0;
1353e12c5d1SDavid du Colombier f->tlock = 0;
1369a747e4fSDavid du Colombier f->dslot = 0;
1379a747e4fSDavid du Colombier f->doffset = 0;
1385d459b5aSDavid du Colombier f->uid = 0;
1395d459b5aSDavid du Colombier f->cuid = 0;
1403e12c5d1SDavid du Colombier cp->flist = f;
1413e12c5d1SDavid du Colombier return f;
1427dd7cddfSDavid du Colombier }
1437dd7cddfSDavid du Colombier unlock(&suballoc.flock);
1443e12c5d1SDavid du Colombier
1457dd7cddfSDavid du Colombier if(conf.nfile > Fmax){
1463e12c5d1SDavid du Colombier print("%d: out of files\n", cp->chan);
1473e12c5d1SDavid du Colombier return 0;
1483e12c5d1SDavid du Colombier }
1493e12c5d1SDavid du Colombier
1507dd7cddfSDavid du Colombier /*
1517dd7cddfSDavid du Colombier * create a few new files
1527dd7cddfSDavid du Colombier */
1537dd7cddfSDavid du Colombier f = malloc(Finc*sizeof(*f));
1547dd7cddfSDavid du Colombier memset(f, 0, Finc*sizeof(*f));
1557dd7cddfSDavid du Colombier lock(&suballoc.flock);
1567dd7cddfSDavid du Colombier for(e = f+Finc; f < e; f++){
1577dd7cddfSDavid du Colombier qlock(f);
1587dd7cddfSDavid du Colombier qunlock(f);
1597dd7cddfSDavid du Colombier f->list = suballoc.ffree;
1607dd7cddfSDavid du Colombier suballoc.ffree = f;
1617dd7cddfSDavid du Colombier }
1627dd7cddfSDavid du Colombier conf.nfile += Finc;
1637dd7cddfSDavid du Colombier unlock(&suballoc.flock);
1647dd7cddfSDavid du Colombier goto retry;
1657dd7cddfSDavid du Colombier }
1667dd7cddfSDavid du Colombier
1673e12c5d1SDavid du Colombier void
freefp(File * fp)1683e12c5d1SDavid du Colombier freefp(File *fp)
1693e12c5d1SDavid du Colombier {
1703e12c5d1SDavid du Colombier Chan *cp;
1713e12c5d1SDavid du Colombier File *f, *prev;
1723e12c5d1SDavid du Colombier
1733e12c5d1SDavid du Colombier if(!fp || !(cp = fp->cp))
1743e12c5d1SDavid du Colombier return;
175b7b24591SDavid du Colombier authfree(fp);
1763e12c5d1SDavid du Colombier lock(&cp->flock);
1773e12c5d1SDavid du Colombier for(prev=0,f=cp->flist; f; prev=f,f=f->next) {
1783e12c5d1SDavid du Colombier if(f != fp)
1793e12c5d1SDavid du Colombier continue;
1803e12c5d1SDavid du Colombier if(prev)
1813e12c5d1SDavid du Colombier prev->next = f->next;
1823e12c5d1SDavid du Colombier else
1833e12c5d1SDavid du Colombier cp->flist = f->next;
1843e12c5d1SDavid du Colombier f->cp = 0;
1857dd7cddfSDavid du Colombier lock(&suballoc.flock);
1867dd7cddfSDavid du Colombier f->list = suballoc.ffree;
1877dd7cddfSDavid du Colombier suballoc.ffree = f;
1887dd7cddfSDavid du Colombier unlock(&suballoc.flock);
1893e12c5d1SDavid du Colombier break;
1903e12c5d1SDavid du Colombier }
1913e12c5d1SDavid du Colombier unlock(&cp->flock);
1923e12c5d1SDavid du Colombier }
1933e12c5d1SDavid du Colombier
1947dd7cddfSDavid du Colombier Wpath*
newwp(void)1957dd7cddfSDavid du Colombier newwp(void)
1967dd7cddfSDavid du Colombier {
1977dd7cddfSDavid du Colombier Wpath *w, *e;
1987dd7cddfSDavid du Colombier
1997dd7cddfSDavid du Colombier retry:
2009a747e4fSDavid du Colombier lock(&wpathlock);
2017dd7cddfSDavid du Colombier w = suballoc.wfree;
2027dd7cddfSDavid du Colombier if(w != nil){
2037dd7cddfSDavid du Colombier suballoc.wfree = w->list;
2049a747e4fSDavid du Colombier unlock(&wpathlock);
2057dd7cddfSDavid du Colombier memset(w, 0, sizeof(*w));
2067dd7cddfSDavid du Colombier w->refs = 1;
2077dd7cddfSDavid du Colombier w->up = 0;
2087dd7cddfSDavid du Colombier return w;
2097dd7cddfSDavid du Colombier }
2109a747e4fSDavid du Colombier unlock(&wpathlock);
2117dd7cddfSDavid du Colombier
2127dd7cddfSDavid du Colombier if(conf.nwpath > Wmax){
2137dd7cddfSDavid du Colombier print("out of wpaths\n");
2147dd7cddfSDavid du Colombier return 0;
2157dd7cddfSDavid du Colombier }
2167dd7cddfSDavid du Colombier
2177dd7cddfSDavid du Colombier /*
2187dd7cddfSDavid du Colombier * create a few new wpaths
2197dd7cddfSDavid du Colombier */
2207dd7cddfSDavid du Colombier w = malloc(Winc*sizeof(*w));
2217dd7cddfSDavid du Colombier memset(w, 0, Winc*sizeof(*w));
2229a747e4fSDavid du Colombier lock(&wpathlock);
2237dd7cddfSDavid du Colombier for(e = w+Winc; w < e; w++){
2247dd7cddfSDavid du Colombier w->list = suballoc.wfree;
2257dd7cddfSDavid du Colombier suballoc.wfree = w;
2267dd7cddfSDavid du Colombier }
2277dd7cddfSDavid du Colombier conf.nwpath += Winc;
2289a747e4fSDavid du Colombier unlock(&wpathlock);
2297dd7cddfSDavid du Colombier goto retry;
2307dd7cddfSDavid du Colombier }
2317dd7cddfSDavid du Colombier
2327dd7cddfSDavid du Colombier /*
2337dd7cddfSDavid du Colombier * increment the references for the whole path
2347dd7cddfSDavid du Colombier */
2357dd7cddfSDavid du Colombier Wpath*
getwp(Wpath * w)2367dd7cddfSDavid du Colombier getwp(Wpath *w)
2377dd7cddfSDavid du Colombier {
2387dd7cddfSDavid du Colombier Wpath *nw;
2397dd7cddfSDavid du Colombier
2409a747e4fSDavid du Colombier lock(&wpathlock);
2417dd7cddfSDavid du Colombier for(nw = w; nw; nw=nw->up)
2427dd7cddfSDavid du Colombier nw->refs++;
2439a747e4fSDavid du Colombier unlock(&wpathlock);
2447dd7cddfSDavid du Colombier return w;
2457dd7cddfSDavid du Colombier }
2467dd7cddfSDavid du Colombier
2477dd7cddfSDavid du Colombier /*
2487dd7cddfSDavid du Colombier * decrement the reference for each element of the path
2497dd7cddfSDavid du Colombier */
2507dd7cddfSDavid du Colombier void
freewp(Wpath * w)2517dd7cddfSDavid du Colombier freewp(Wpath *w)
2527dd7cddfSDavid du Colombier {
2539a747e4fSDavid du Colombier lock(&wpathlock);
2547dd7cddfSDavid du Colombier for(; w; w=w->up){
2557dd7cddfSDavid du Colombier w->refs--;
2567dd7cddfSDavid du Colombier if(w->refs == 0){
2577dd7cddfSDavid du Colombier w->list = suballoc.wfree;
2587dd7cddfSDavid du Colombier suballoc.wfree = w;
2597dd7cddfSDavid du Colombier }
2607dd7cddfSDavid du Colombier }
2619a747e4fSDavid du Colombier unlock(&wpathlock);
2627dd7cddfSDavid du Colombier }
2637dd7cddfSDavid du Colombier
2647dd7cddfSDavid du Colombier /*
2657dd7cddfSDavid du Colombier * decrement the reference for just this element
2667dd7cddfSDavid du Colombier */
2677dd7cddfSDavid du Colombier void
putwp(Wpath * w)2687dd7cddfSDavid du Colombier putwp(Wpath *w)
2697dd7cddfSDavid du Colombier {
2709a747e4fSDavid du Colombier lock(&wpathlock);
2717dd7cddfSDavid du Colombier w->refs--;
2727dd7cddfSDavid du Colombier if(w->refs == 0){
2737dd7cddfSDavid du Colombier w->list = suballoc.wfree;
2747dd7cddfSDavid du Colombier suballoc.wfree = w;
2757dd7cddfSDavid du Colombier }
2769a747e4fSDavid du Colombier unlock(&wpathlock);
2777dd7cddfSDavid du Colombier }
2787dd7cddfSDavid du Colombier
2793e12c5d1SDavid du Colombier int
iaccess(File * f,Dentry * d,int m)2803e12c5d1SDavid du Colombier iaccess(File *f, Dentry *d, int m)
2813e12c5d1SDavid du Colombier {
282bd389b36SDavid du Colombier if(wstatallow)
2833e12c5d1SDavid du Colombier return 0;
2849a747e4fSDavid du Colombier
2853e12c5d1SDavid du Colombier /*
2863e12c5d1SDavid du Colombier * owner is next
2873e12c5d1SDavid du Colombier */
2883e12c5d1SDavid du Colombier if(f->uid == d->uid)
2893e12c5d1SDavid du Colombier if((m<<6) & d->mode)
2903e12c5d1SDavid du Colombier return 0;
2913e12c5d1SDavid du Colombier /*
2923e12c5d1SDavid du Colombier * group membership is hard
2933e12c5d1SDavid du Colombier */
2943e12c5d1SDavid du Colombier if(ingroup(f->uid, d->gid))
2953e12c5d1SDavid du Colombier if((m<<3) & d->mode)
2963e12c5d1SDavid du Colombier return 0;
2975d459b5aSDavid du Colombier /*
2985d459b5aSDavid du Colombier * other access for everyone except members of group 9999
2995d459b5aSDavid du Colombier */
3005d459b5aSDavid du Colombier if(m & d->mode){
3015d459b5aSDavid du Colombier /*
3025d459b5aSDavid du Colombier * walk directories regardless.
3035d459b5aSDavid du Colombier * otherwise its impossible to get
3045d459b5aSDavid du Colombier * from the root to noworld's directories.
3055d459b5aSDavid du Colombier */
3065d459b5aSDavid du Colombier if((d->mode & DDIR) && (m == DEXEC))
3075d459b5aSDavid du Colombier return 0;
3085d459b5aSDavid du Colombier if(!ingroup(f->uid, 9999))
3095d459b5aSDavid du Colombier return 0;
3105d459b5aSDavid du Colombier }
3113e12c5d1SDavid du Colombier return 1;
3123e12c5d1SDavid du Colombier }
3133e12c5d1SDavid du Colombier
3143e12c5d1SDavid du Colombier Tlock*
tlocked(Iobuf * p,Dentry * d)3153e12c5d1SDavid du Colombier tlocked(Iobuf *p, Dentry *d)
3163e12c5d1SDavid du Colombier {
3173e12c5d1SDavid du Colombier Tlock *t, *t1;
3183e12c5d1SDavid du Colombier long qpath, tim;
3193e12c5d1SDavid du Colombier Device dev;
3203e12c5d1SDavid du Colombier
3217dd7cddfSDavid du Colombier tim = time(0);
3223e12c5d1SDavid du Colombier qpath = d->qid.path;
3233e12c5d1SDavid du Colombier dev = p->dev;
3243e12c5d1SDavid du Colombier t1 = 0;
3253e12c5d1SDavid du Colombier for(t=tlocks+NTLOCK-1; t>=tlocks; t--) {
3263e12c5d1SDavid du Colombier if(t->qpath == qpath)
3273e12c5d1SDavid du Colombier if(t->time >= tim)
3283e12c5d1SDavid du Colombier if(devcmp(t->dev, dev) == 0)
3293e12c5d1SDavid du Colombier return 0; /* its locked */
3303e12c5d1SDavid du Colombier if(!t1 && t->time < tim)
3313e12c5d1SDavid du Colombier t1 = t; /* steal first lock */
3323e12c5d1SDavid du Colombier }
3333e12c5d1SDavid du Colombier if(t1) {
3343e12c5d1SDavid du Colombier t1->dev = dev;
3353e12c5d1SDavid du Colombier t1->qpath = qpath;
3363e12c5d1SDavid du Colombier t1->time = tim + TLOCK;
3373e12c5d1SDavid du Colombier }
3383e12c5d1SDavid du Colombier /* botch
3393e12c5d1SDavid du Colombier * out of tlock nodes simulates
3403e12c5d1SDavid du Colombier * a locked file
3413e12c5d1SDavid du Colombier */
3423e12c5d1SDavid du Colombier return t1;
3433e12c5d1SDavid du Colombier }
3443e12c5d1SDavid du Colombier
3453e12c5d1SDavid du Colombier Qid
newqid(Device dev)3463e12c5d1SDavid du Colombier newqid(Device dev)
3473e12c5d1SDavid du Colombier {
3483e12c5d1SDavid du Colombier Iobuf *p;
3493e12c5d1SDavid du Colombier Superb *sb;
3503e12c5d1SDavid du Colombier Qid qid;
3513e12c5d1SDavid du Colombier
3523e12c5d1SDavid du Colombier p = getbuf(dev, superaddr(dev), Bread|Bmod);
3533e12c5d1SDavid du Colombier if(!p || checktag(p, Tsuper, QPSUPER))
3543e12c5d1SDavid du Colombier panic("newqid: super block");
3553e12c5d1SDavid du Colombier sb = (Superb*)p->iobuf;
3563e12c5d1SDavid du Colombier sb->qidgen++;
3573e12c5d1SDavid du Colombier qid.path = sb->qidgen;
3587dd7cddfSDavid du Colombier qid.vers = 0;
359*2bef681aSDavid du Colombier qid.type = 0;
3603e12c5d1SDavid du Colombier putbuf(p);
3613e12c5d1SDavid du Colombier return qid;
3623e12c5d1SDavid du Colombier }
3633e12c5d1SDavid du Colombier
3643e12c5d1SDavid du Colombier /*
3653e12c5d1SDavid du Colombier * what are legal characters in a name?
3663e12c5d1SDavid du Colombier * only disallow control characters.
3673e12c5d1SDavid du Colombier * a) utf avoids control characters.
3683e12c5d1SDavid du Colombier * b) '/' may not be the separator
3693e12c5d1SDavid du Colombier */
3703e12c5d1SDavid du Colombier int
checkname(char * n)3713e12c5d1SDavid du Colombier checkname(char *n)
3723e12c5d1SDavid du Colombier {
3733e12c5d1SDavid du Colombier int i, c;
3743e12c5d1SDavid du Colombier
3753e12c5d1SDavid du Colombier for(i=0; i<NAMELEN; i++) {
3763e12c5d1SDavid du Colombier c = *n & 0xff;
3773e12c5d1SDavid du Colombier if(c == 0) {
3783e12c5d1SDavid du Colombier if(i == 0)
3793e12c5d1SDavid du Colombier return 1;
3803e12c5d1SDavid du Colombier memset(n, 0, NAMELEN-i);
3813e12c5d1SDavid du Colombier return 0;
3823e12c5d1SDavid du Colombier }
3833e12c5d1SDavid du Colombier if(c <= 040)
3843e12c5d1SDavid du Colombier return 1;
3853e12c5d1SDavid du Colombier n++;
3863e12c5d1SDavid du Colombier }
3873e12c5d1SDavid du Colombier return 1; /* too long */
3883e12c5d1SDavid du Colombier }
3893e12c5d1SDavid du Colombier
3903e12c5d1SDavid du Colombier void
bfree(Device dev,long addr,int d)3913e12c5d1SDavid du Colombier bfree(Device dev, long addr, int d)
3923e12c5d1SDavid du Colombier {
3933e12c5d1SDavid du Colombier Iobuf *p;
3943e12c5d1SDavid du Colombier long a;
3953e12c5d1SDavid du Colombier int i;
3963e12c5d1SDavid du Colombier
3973e12c5d1SDavid du Colombier if(!addr)
3983e12c5d1SDavid du Colombier return;
3993e12c5d1SDavid du Colombier if(d > 0) {
4003e12c5d1SDavid du Colombier d--;
4013e12c5d1SDavid du Colombier p = getbuf(dev, addr, Bread);
4023e12c5d1SDavid du Colombier if(p) {
4033e12c5d1SDavid du Colombier for(i=INDPERBUF-1; i>=0; i--) {
4043e12c5d1SDavid du Colombier a = ((long*)p->iobuf)[i];
4053e12c5d1SDavid du Colombier bfree(dev, a, d);
4063e12c5d1SDavid du Colombier }
4073e12c5d1SDavid du Colombier putbuf(p);
4083e12c5d1SDavid du Colombier }
4093e12c5d1SDavid du Colombier }
4103e12c5d1SDavid du Colombier /*
4113e12c5d1SDavid du Colombier * stop outstanding i/o
4123e12c5d1SDavid du Colombier */
4133e12c5d1SDavid du Colombier p = getbuf(dev, addr, Bprobe);
4143e12c5d1SDavid du Colombier if(p) {
4153e12c5d1SDavid du Colombier p->flags &= ~(Bmod|Bimm);
4163e12c5d1SDavid du Colombier putbuf(p);
4173e12c5d1SDavid du Colombier }
4183e12c5d1SDavid du Colombier /*
4193e12c5d1SDavid du Colombier * dont put written worm
4203e12c5d1SDavid du Colombier * blocks into free list
4213e12c5d1SDavid du Colombier */
4223e12c5d1SDavid du Colombier if(nofree(dev, addr))
4233e12c5d1SDavid du Colombier return;
4243e12c5d1SDavid du Colombier p = getbuf(dev, superaddr(dev), Bread|Bmod);
4253e12c5d1SDavid du Colombier if(!p || checktag(p, Tsuper, QPSUPER))
4263e12c5d1SDavid du Colombier panic("bfree: super block");
4273e12c5d1SDavid du Colombier addfree(dev, addr, (Superb*)p->iobuf);
4283e12c5d1SDavid du Colombier putbuf(p);
4293e12c5d1SDavid du Colombier }
4303e12c5d1SDavid du Colombier
4313e12c5d1SDavid du Colombier long
balloc(Device dev,int tag,long qid)4323e12c5d1SDavid du Colombier balloc(Device dev, int tag, long qid)
4333e12c5d1SDavid du Colombier {
4343e12c5d1SDavid du Colombier Iobuf *bp, *p;
4353e12c5d1SDavid du Colombier Superb *sb;
4363e12c5d1SDavid du Colombier long a;
4373e12c5d1SDavid du Colombier int n;
4383e12c5d1SDavid du Colombier
4393e12c5d1SDavid du Colombier p = getbuf(dev, superaddr(dev), Bread|Bmod);
4403e12c5d1SDavid du Colombier if(!p || checktag(p, Tsuper, QPSUPER))
4413e12c5d1SDavid du Colombier panic("balloc: super block");
4423e12c5d1SDavid du Colombier sb = (Superb*)p->iobuf;
4433e12c5d1SDavid du Colombier
4443e12c5d1SDavid du Colombier loop:
4453e12c5d1SDavid du Colombier n = --sb->fbuf.nfree;
4463e12c5d1SDavid du Colombier sb->tfree--;
4473e12c5d1SDavid du Colombier if(n < 0 || n >= FEPERBUF)
4483e12c5d1SDavid du Colombier panic("balloc: bad freelist");
4493e12c5d1SDavid du Colombier a = sb->fbuf.free[n];
4503e12c5d1SDavid du Colombier if(n <= 0) {
4513e12c5d1SDavid du Colombier if(a == 0) {
4523e12c5d1SDavid du Colombier sb->tfree = 0;
4533e12c5d1SDavid du Colombier sb->fbuf.nfree = 1;
4543e12c5d1SDavid du Colombier if(devgrow(dev, sb))
4553e12c5d1SDavid du Colombier goto loop;
4563e12c5d1SDavid du Colombier putbuf(p);
4573e12c5d1SDavid du Colombier return 0;
4583e12c5d1SDavid du Colombier }
4593e12c5d1SDavid du Colombier bp = getbuf(dev, a, Bread);
4603e12c5d1SDavid du Colombier if(!bp || checktag(bp, Tfree, QPNONE)) {
4613e12c5d1SDavid du Colombier if(bp)
4623e12c5d1SDavid du Colombier putbuf(bp);
4633e12c5d1SDavid du Colombier putbuf(p);
4643e12c5d1SDavid du Colombier return 0;
4653e12c5d1SDavid du Colombier }
466bd389b36SDavid du Colombier memmove(&sb->fbuf, bp->iobuf, (FEPERBUF+1)*sizeof(long));
4673e12c5d1SDavid du Colombier putbuf(bp);
4683e12c5d1SDavid du Colombier }
4693e12c5d1SDavid du Colombier bp = getbuf(dev, a, Bmod);
4703e12c5d1SDavid du Colombier memset(bp->iobuf, 0, RBUFSIZE);
4713e12c5d1SDavid du Colombier settag(bp, tag, qid);
4723e12c5d1SDavid du Colombier if(tag == Tind1 || tag == Tind2 || tag == Tdir)
4733e12c5d1SDavid du Colombier bp->flags |= Bimm;
4743e12c5d1SDavid du Colombier putbuf(bp);
4753e12c5d1SDavid du Colombier putbuf(p);
4763e12c5d1SDavid du Colombier return a;
4773e12c5d1SDavid du Colombier }
4783e12c5d1SDavid du Colombier
4793e12c5d1SDavid du Colombier void
addfree(Device dev,long addr,Superb * sb)4803e12c5d1SDavid du Colombier addfree(Device dev, long addr, Superb *sb)
4813e12c5d1SDavid du Colombier {
4823e12c5d1SDavid du Colombier int n;
4833e12c5d1SDavid du Colombier Iobuf *p;
4843e12c5d1SDavid du Colombier
4853e12c5d1SDavid du Colombier if(addr >= sb->fsize){
4863e12c5d1SDavid du Colombier print("addfree: bad addr %lux\n", addr);
4873e12c5d1SDavid du Colombier return;
4883e12c5d1SDavid du Colombier }
4893e12c5d1SDavid du Colombier n = sb->fbuf.nfree;
4903e12c5d1SDavid du Colombier if(n < 0 || n > FEPERBUF)
4913e12c5d1SDavid du Colombier panic("addfree: bad freelist");
4923e12c5d1SDavid du Colombier if(n >= FEPERBUF) {
4933e12c5d1SDavid du Colombier p = getbuf(dev, addr, Bmod);
4943e12c5d1SDavid du Colombier if(p == 0)
4953e12c5d1SDavid du Colombier panic("addfree: getbuf");
496bd389b36SDavid du Colombier memmove(p->iobuf, &sb->fbuf, (FEPERBUF+1)*sizeof(long));
4973e12c5d1SDavid du Colombier settag(p, Tfree, QPNONE);
4983e12c5d1SDavid du Colombier putbuf(p);
4993e12c5d1SDavid du Colombier n = 0;
5003e12c5d1SDavid du Colombier }
5013e12c5d1SDavid du Colombier sb->fbuf.free[n++] = addr;
5023e12c5d1SDavid du Colombier sb->fbuf.nfree = n;
5033e12c5d1SDavid du Colombier sb->tfree++;
5043e12c5d1SDavid du Colombier if(addr >= sb->fsize)
5053e12c5d1SDavid du Colombier sb->fsize = addr+1;
5063e12c5d1SDavid du Colombier }
5073e12c5d1SDavid du Colombier
5083e12c5d1SDavid du Colombier int
Cfmt(Fmt * f1)5099a747e4fSDavid du Colombier Cfmt(Fmt *f1)
5103e12c5d1SDavid du Colombier {
5113e12c5d1SDavid du Colombier Chan *cp;
5123e12c5d1SDavid du Colombier
5139a747e4fSDavid du Colombier cp = va_arg(f1->args, Chan*);
5149a747e4fSDavid du Colombier return fmtprint(f1, "C%d.%.3d", cp->type, cp->chan);
5153e12c5d1SDavid du Colombier }
5163e12c5d1SDavid du Colombier
5173e12c5d1SDavid du Colombier int
Dfmt(Fmt * f1)5189a747e4fSDavid du Colombier Dfmt(Fmt *f1)
5193e12c5d1SDavid du Colombier {
5203e12c5d1SDavid du Colombier Device d;
5213e12c5d1SDavid du Colombier
5229a747e4fSDavid du Colombier d = va_arg(f1->args, Device);
5239a747e4fSDavid du Colombier return fmtprint(f1, "D%d.%d.%d.%d", d.type, d.ctrl, d.unit, d.part);
5243e12c5d1SDavid du Colombier }
5253e12c5d1SDavid du Colombier
5263e12c5d1SDavid du Colombier int
Afmt(Fmt * f1)5279a747e4fSDavid du Colombier Afmt(Fmt *f1)
5283e12c5d1SDavid du Colombier {
5293e12c5d1SDavid du Colombier Filta a;
5303e12c5d1SDavid du Colombier
5319a747e4fSDavid du Colombier a = va_arg(f1->args, Filta);
5329a747e4fSDavid du Colombier return fmtprint(f1, "%6lud %6lud %6lud",
5333e12c5d1SDavid du Colombier fdf(a.f->filter[0], a.scale*60),
5343e12c5d1SDavid du Colombier fdf(a.f->filter[1], a.scale*600),
5353e12c5d1SDavid du Colombier fdf(a.f->filter[2], a.scale*6000));
5363e12c5d1SDavid du Colombier }
5373e12c5d1SDavid du Colombier
5383e12c5d1SDavid du Colombier int
Gfmt(Fmt * f1)5399a747e4fSDavid du Colombier Gfmt(Fmt *f1)
5403e12c5d1SDavid du Colombier {
5413e12c5d1SDavid du Colombier int t;
5423e12c5d1SDavid du Colombier
5439a747e4fSDavid du Colombier t = va_arg(f1->args, int);
5443e12c5d1SDavid du Colombier if(t >= 0 && t < MAXTAG)
5459a747e4fSDavid du Colombier return fmtstrcpy(f1, tagnames[t]);
5469a747e4fSDavid du Colombier else
5479a747e4fSDavid du Colombier return fmtprint(f1, "<badtag %d>", t);
5487dd7cddfSDavid du Colombier }
5497dd7cddfSDavid du Colombier
5503e12c5d1SDavid du Colombier void
formatinit(void)5513e12c5d1SDavid du Colombier formatinit(void)
5523e12c5d1SDavid du Colombier {
5533e12c5d1SDavid du Colombier
5549a747e4fSDavid du Colombier fmtinstall('C', Cfmt); /* print channels */
5559a747e4fSDavid du Colombier fmtinstall('D', Dfmt); /* print devices */
5569a747e4fSDavid du Colombier fmtinstall('A', Afmt); /* print filters */
5579a747e4fSDavid du Colombier fmtinstall('G', Gfmt); /* print tags */
5589a747e4fSDavid du Colombier fmtinstall('T', Tfmt); /* print times */
5599a747e4fSDavid du Colombier fmtinstall('O', ofcallfmt); /* print old fcalls */
5603e12c5d1SDavid du Colombier }
5613e12c5d1SDavid du Colombier int
devcmp(Device d1,Device d2)5623e12c5d1SDavid du Colombier devcmp(Device d1, Device d2)
5633e12c5d1SDavid du Colombier {
5643e12c5d1SDavid du Colombier
5653e12c5d1SDavid du Colombier if(d1.type == d2.type)
5663e12c5d1SDavid du Colombier if(d1.ctrl == d2.ctrl)
5673e12c5d1SDavid du Colombier if(d1.unit == d2.unit)
5683e12c5d1SDavid du Colombier if(d1.part == d2.part)
5693e12c5d1SDavid du Colombier return 0;
5703e12c5d1SDavid du Colombier return 1;
5713e12c5d1SDavid du Colombier }
5723e12c5d1SDavid du Colombier
5733e12c5d1SDavid du Colombier void
rootream(Device dev,long addr)5743e12c5d1SDavid du Colombier rootream(Device dev, long addr)
5753e12c5d1SDavid du Colombier {
5763e12c5d1SDavid du Colombier Iobuf *p;
5773e12c5d1SDavid du Colombier Dentry *d;
5783e12c5d1SDavid du Colombier
5793e12c5d1SDavid du Colombier p = getbuf(dev, addr, Bmod|Bimm);
5803e12c5d1SDavid du Colombier memset(p->iobuf, 0, RBUFSIZE);
5813e12c5d1SDavid du Colombier settag(p, Tdir, QPROOT);
5823e12c5d1SDavid du Colombier d = getdir(p, 0);
5833e12c5d1SDavid du Colombier strcpy(d->name, "/");
5843e12c5d1SDavid du Colombier d->uid = -1;
5853e12c5d1SDavid du Colombier d->gid = -1;
5863e12c5d1SDavid du Colombier d->mode = DALLOC | DDIR |
5873e12c5d1SDavid du Colombier ((DREAD|DWRITE|DEXEC) << 6) |
5883e12c5d1SDavid du Colombier ((DREAD|DWRITE|DEXEC) << 3) |
5893e12c5d1SDavid du Colombier ((DREAD|DWRITE|DEXEC) << 0);
5909a747e4fSDavid du Colombier d->qid = QID9P1(QPROOT|QPDIR,0);
5917dd7cddfSDavid du Colombier d->atime = time(0);
5923e12c5d1SDavid du Colombier d->mtime = d->atime;
5933e12c5d1SDavid du Colombier putbuf(p);
5943e12c5d1SDavid du Colombier }
5953e12c5d1SDavid du Colombier
596219b2ee8SDavid du Colombier int
superok(Device dev,long addr,int set)597219b2ee8SDavid du Colombier superok(Device dev, long addr, int set)
598219b2ee8SDavid du Colombier {
599219b2ee8SDavid du Colombier Iobuf *p;
600219b2ee8SDavid du Colombier Superb *s;
601219b2ee8SDavid du Colombier int ok;
602219b2ee8SDavid du Colombier
603219b2ee8SDavid du Colombier p = getbuf(dev, addr, Bread|Bmod|Bimm);
604219b2ee8SDavid du Colombier s = (Superb*)p->iobuf;
605219b2ee8SDavid du Colombier ok = s->fsok;
606219b2ee8SDavid du Colombier s->fsok = set;
607219b2ee8SDavid du Colombier putbuf(p);
608219b2ee8SDavid du Colombier return ok;
609219b2ee8SDavid du Colombier }
610219b2ee8SDavid du Colombier
6113e12c5d1SDavid du Colombier void
superream(Device dev,long addr)6123e12c5d1SDavid du Colombier superream(Device dev, long addr)
6133e12c5d1SDavid du Colombier {
6143e12c5d1SDavid du Colombier Iobuf *p;
6153e12c5d1SDavid du Colombier Superb *s;
6163e12c5d1SDavid du Colombier long i;
6173e12c5d1SDavid du Colombier
6183e12c5d1SDavid du Colombier p = getbuf(dev, addr, Bmod|Bimm);
6193e12c5d1SDavid du Colombier memset(p->iobuf, 0, RBUFSIZE);
6203e12c5d1SDavid du Colombier settag(p, Tsuper, QPSUPER);
6213e12c5d1SDavid du Colombier
6223e12c5d1SDavid du Colombier s = (Superb*)p->iobuf;
6233e12c5d1SDavid du Colombier s->fstart = 1;
6243e12c5d1SDavid du Colombier s->fsize = devsize(dev);
6253e12c5d1SDavid du Colombier s->fbuf.nfree = 1;
6263e12c5d1SDavid du Colombier s->qidgen = 10;
6273e12c5d1SDavid du Colombier for(i=s->fsize-1; i>=addr+2; i--)
6283e12c5d1SDavid du Colombier addfree(dev, i, s);
6293e12c5d1SDavid du Colombier putbuf(p);
6303e12c5d1SDavid du Colombier }
6313e12c5d1SDavid du Colombier
6323e12c5d1SDavid du Colombier /*
6333e12c5d1SDavid du Colombier * returns 1 if n is prime
6343e12c5d1SDavid du Colombier * used for adjusting lengths
6353e12c5d1SDavid du Colombier * of hashing things.
6363e12c5d1SDavid du Colombier * there is no need to be clever
6373e12c5d1SDavid du Colombier */
6383e12c5d1SDavid du Colombier int
prime(long n)6393e12c5d1SDavid du Colombier prime(long n)
6403e12c5d1SDavid du Colombier {
6413e12c5d1SDavid du Colombier long i;
6423e12c5d1SDavid du Colombier
6433e12c5d1SDavid du Colombier if((n%2) == 0)
6443e12c5d1SDavid du Colombier return 0;
6453e12c5d1SDavid du Colombier for(i=3;; i+=2) {
6463e12c5d1SDavid du Colombier if((n%i) == 0)
6473e12c5d1SDavid du Colombier return 0;
6483e12c5d1SDavid du Colombier if(i*i >= n)
6493e12c5d1SDavid du Colombier return 1;
6503e12c5d1SDavid du Colombier }
6513e12c5d1SDavid du Colombier }
6523e12c5d1SDavid du Colombier
6533e12c5d1SDavid du Colombier void
hexdump(void * a,int n)6543e12c5d1SDavid du Colombier hexdump(void *a, int n)
6553e12c5d1SDavid du Colombier {
6563e12c5d1SDavid du Colombier char s1[30], s2[4];
6573e12c5d1SDavid du Colombier uchar *p;
6583e12c5d1SDavid du Colombier int i;
6593e12c5d1SDavid du Colombier
6603e12c5d1SDavid du Colombier p = a;
6613e12c5d1SDavid du Colombier s1[0] = 0;
6623e12c5d1SDavid du Colombier for(i=0; i<n; i++) {
6633e12c5d1SDavid du Colombier sprint(s2, " %.2ux", p[i]);
6643e12c5d1SDavid du Colombier strcat(s1, s2);
6653e12c5d1SDavid du Colombier if((i&7) == 7) {
6663e12c5d1SDavid du Colombier print("%s\n", s1);
6673e12c5d1SDavid du Colombier s1[0] = 0;
6683e12c5d1SDavid du Colombier }
6693e12c5d1SDavid du Colombier }
6703e12c5d1SDavid du Colombier if(s1[0])
6713e12c5d1SDavid du Colombier print("%s\n", s1);
6723e12c5d1SDavid du Colombier }
6739a747e4fSDavid du Colombier
6749a747e4fSDavid du Colombier long
qidpathgen(Device * dev)6759a747e4fSDavid du Colombier qidpathgen(Device *dev)
6769a747e4fSDavid du Colombier {
6779a747e4fSDavid du Colombier Iobuf *p;
6789a747e4fSDavid du Colombier Superb *sb;
6799a747e4fSDavid du Colombier long path;
6809a747e4fSDavid du Colombier
6819a747e4fSDavid du Colombier p = getbuf(*dev, superaddr((*dev)), Bread|Bmod);
6829a747e4fSDavid du Colombier if(!p || checktag(p, Tsuper, QPSUPER))
6839a747e4fSDavid du Colombier panic("newqid: super block");
6849a747e4fSDavid du Colombier sb = (Superb*)p->iobuf;
6859a747e4fSDavid du Colombier sb->qidgen++;
6869a747e4fSDavid du Colombier path = sb->qidgen;
6879a747e4fSDavid du Colombier putbuf(p);
6889a747e4fSDavid du Colombier return path;
6899a747e4fSDavid du Colombier }
6909a747e4fSDavid du Colombier
691