📄 cw.c
字号:
for(a=0;; a++) { p1 = dnodebuf(pr, dr, a, Tdir, 0); if(!p1) goto bad; n++; for(i=0; i<DIRPERBUF; i++) { d1 = getdir(p1, i); if(!d1) goto bad; if(!(d1->mode & DALLOC)) goto found1; if(!memcmp(d1->name, tstr, 4)) goto found2; /* found entry */ } putbuf(p1); } /* * no year directory, create one */found1: p = getbuf(cw->dev, rba, Bread); d = getdir(p, 0); d1->qid = d->qid; d1->qid.version += n; memmove(d1->name, tstr, 4); d1->mode = d->mode; d1->uid = d->uid; d1->gid = d->gid; putbuf(p); accessdir(p1, d1, FWRITE, 0); /* * put mmdd[count] in year directory */found2: accessdir(p1, d1, FREAD, 0); putbuf(pr); pr = p1; dr = d1; n = 0; m = 0; for(a=0;; a++) { p1 = dnodebuf(pr, dr, a, Tdir, 0); if(!p1) goto bad; n++; for(i=0; i<DIRPERBUF; i++) { d1 = getdir(p1, i); if(!d1) goto bad; if(!(d1->mode & DALLOC)) goto found; if(!memcmp(d1->name, tstr+4, 4)) m++; } putbuf(p1); } /* * empty slot put in root */found: if(m) /* how many dumps this date */ sprint(tstr+8, "%ld", m); p = getbuf(cw->dev, rba, Bread); d = getdir(p, 0); *d1 = *d; /* qid is QPROOT */ putbuf(p); strcpy(d1->name, tstr+4); d1->qid.version += n; accessdir(p1, d1, FWRITE, 0); putbuf(p1); putbuf(pr); cw->fsize = cwsize(cw->dev); oroa = cwraddr(cw->rodev); /* probably redundant */ print("roroot %lld", (Wideoff)oroa); cons.noage = 0; cw->all = 0; roa = cwrecur(cw, oroa, Tsuper, 0, QPROOT); if(roa == 0) { print("[same]"); roa = oroa; } print("->%lld /%.4s/%s\n", (Wideoff)roa, tstr, tstr+4); sync("after ro"); /* * final super block */ a = cwsaddr(cw->dev); print("sblock %lld", (Wideoff)a); p = getbuf(cw->dev, a, Bread|Bmod|Bimm); s = (Superb*)p->iobuf; s->last = a; sba = s->next; s->next = cw->fsize; cw->fsize++; s->fsize = cw->fsize; s->roraddr = roa;#ifdef AUTOSWAB s->magic = 0x123456789abcdef0;#endif cwio(cw->dev, sba, 0, Ogrow); cwio(cw->dev, sba, p->iobuf, Owrite); cwio(cw->dev, sba, 0, Odump); print("->%lld (->%lld)\n", (Wideoff)sba, (Wideoff)s->next); putbuf(p); /* * final cache block */ p = getbuf(cw->cdev, CACHE_ADDR, Bread|Bmod|Bimm|Bres); h = (Cache*)p->iobuf; h->fsize = cw->fsize; h->roraddr = roa; h->sbaddr = sba; putbuf(p); rewalk(cw); sync("all done"); print("%lld blocks queued for worm\n", (Wideoff)cw->ndump); print("%lld falsehits\n", (Wideoff)cw->falsehits); cw->nodump = 0; /* * extend all of the locks */ tim = toytime() - tim; for(i=0; i<NTLOCK; i++) if(tlocks[i].time > 0) tlocks[i].time += tim; wunlock(&mainlock); nextdump(time()); return;bad: panic("dump: bad");}voidmvstates(Device *dev, int s1, int s2, int side){ Iobuf *p, *cb; Cache *h; Bucket *b; Centry *c, *ce; Off m, lo, hi, msize, maddr; Cw *cw; cw = dev->private; lo = 0; hi = lo + devsize(dev->cw.w); /* size of all sides totalled */ if(side >= 0) { /* operate on only a single disc side */ Sidestarts ss; wormsidestarts(dev, side, &ss); lo = ss.sstart; hi = ss.s1start; } cb = getbuf(cw->cdev, CACHE_ADDR, Bread|Bres); if(!cb || checktag(cb, Tcache, QPSUPER)) panic("cwstats: checktag c bucket"); h = (Cache*)cb->iobuf; msize = h->msize; maddr = h->maddr; putbuf(cb); for(m=0; m<msize; m++) { p = getbuf(cw->cdev, maddr + m/BKPERBLK, Bread|Bmod); if(!p || checktag(p, Tbuck, maddr + m/BKPERBLK)) panic("cwtest: checktag c bucket"); b = (Bucket*)p->iobuf + m%BKPERBLK; ce = b->entry + CEPERBK; for(c=b->entry; c<ce; c++) if(c->state == s1 && c->waddr >= lo && c->waddr < hi) c->state = s2; putbuf(p); }}voidprchain(Device *dev, Off m, int flg){ Iobuf *p; Superb *s; if(m == 0) { if(flg) m = cwsaddr(dev); else m = getstartsb(dev); } p = getbuf(devnone, Cwxx2, 0); s = (Superb*)p->iobuf; for(;;) { memset(p->iobuf, 0, RBUFSIZE); if(devread(WDEV(dev), m, p->iobuf) || checktag(p, Tsuper, QPSUPER)) break; if(flg) { print("dump %lld is good; %lld prev\n", (Wideoff)m, (Wideoff)s->last); print("\t%lld cwroot; %lld roroot\n", (Wideoff)s->cwraddr, (Wideoff)s->roraddr); if(m <= s->last) break; m = s->last; } else { print("dump %lld is good; %lld next\n", (Wideoff)m, (Wideoff)s->next); print("\t%lld cwroot; %lld roroot\n", (Wideoff)s->cwraddr, (Wideoff)s->roraddr); if(m >= s->next) break; m = s->next; } } putbuf(p);}voidtouchsb(Device *dev){ Iobuf *p; Off m; m = cwsaddr(dev); p = getbuf(devnone, Cwxx2, 0); memset(p->iobuf, 0, RBUFSIZE); if(devread(WDEV(dev), m, p->iobuf) || checktag(p, Tsuper, QPSUPER)) print("%Z block %lld WORM SUPER BLOCK READ FAILED\n", WDEV(dev), (Wideoff)m); else print("%Z touch superblock %lld\n", WDEV(dev), (Wideoff)m); putbuf(p);}voidstoresb(Device *dev, Off last, int doit){ Iobuf *ph, *ps; Cache *h; Superb *s; Off sbaddr, qidgen; sbaddr = cwsaddr(dev); ps = getbuf(devnone, Cwxx2, 0); if(!ps) { print("sbstore: getbuf\n"); return; } /* * try to read last sb */ memset(ps->iobuf, 0, RBUFSIZE); if(devread(WDEV(dev), last, ps->iobuf) || checktag(ps, Tsuper, QPSUPER)) print("read last failed\n"); else print("read last succeeded\n"); s = (Superb*)ps->iobuf; qidgen = s->qidgen; if(qidgen == 0) qidgen = 0x31415; qidgen += 1000; if(s->next != sbaddr) print("next(last) is not sbaddr %lld %lld\n", (Wideoff)s->next, (Wideoff)sbaddr); else print("next(last) is sbaddr\n"); /* * read cached superblock */ ph = getbuf(CDEV(dev), CACHE_ADDR, Bread|Bres); if(!ph || checktag(ph, Tcache, QPSUPER)) { print("cwstats: checktag c bucket\n"); if(ph) putbuf(ph); putbuf(ps); return; } else print("read cached sb succeeded\n"); h = (Cache*)ph->iobuf; memset(ps->iobuf, 0, RBUFSIZE); settag(ps, Tsuper, QPSUPER); ps->flags = 0; s = (Superb*)ps->iobuf; s->cwraddr = h->cwraddr; s->roraddr = h->roraddr; s->fsize = h->fsize; s->fstart = 2; s->last = last; s->next = h->roraddr+1; s->qidgen = qidgen;#ifdef AUTOSWAB s->magic = 0x123456789abcdef0;#endif putbuf(ph); if(s->fsize-1 != s->next || s->fsize-2 != s->roraddr || s->fsize-5 != s->cwraddr) { print("addrs not in relationship %lld %lld %lld %lld\n", (Wideoff)s->cwraddr, (Wideoff)s->roraddr, (Wideoff)s->next, (Wideoff)s->fsize); putbuf(ps); return; } else print("addresses in relation\n"); if(doit) if(devwrite(WDEV(dev), sbaddr, ps->iobuf)) print("%Z block %lld WORM SUPER BLOCK WRITE FAILED\n", WDEV(dev), (Wideoff)sbaddr); ps->flags = 0; putbuf(ps);}voidsavecache(Device *dev){ Iobuf *p, *cb; Cache *h; Bucket *b; Centry *c, *ce; long n, left; Off m, maddr, msize, *longp, nbyte; Device *cdev; if(walkto("/adm/cache") || con_open(FID2, OWRITE|OTRUNC)) { print("cant open /adm/cache\n"); return; } cdev = CDEV(dev); cb = getbuf(cdev, CACHE_ADDR, Bread|Bres); if(!cb || checktag(cb, Tcache, QPSUPER)) panic("savecache: checktag c bucket"); h = (Cache*)cb->iobuf; msize = h->msize; maddr = h->maddr; putbuf(cb); n = BUFSIZE; /* calculate write size */ if(n > MAXDAT) n = MAXDAT; cb = getbuf(devnone, Cwxx4, 0); longp = (Off *)cb->iobuf; left = n/sizeof(Off); cons.offset = 0; for(m=0; m<msize; m++) { if(left < BKPERBLK) { nbyte = (n/sizeof(Off) - left) * sizeof(Off); con_write(FID2, cb->iobuf, cons.offset, nbyte); cons.offset += nbyte; longp = (Off *)cb->iobuf; left = n/sizeof(Off); } p = getbuf(cdev, maddr + m/BKPERBLK, Bread); if(!p || checktag(p, Tbuck, maddr + m/BKPERBLK)) panic("cwtest: checktag c bucket"); b = (Bucket*)p->iobuf + m%BKPERBLK; ce = b->entry + CEPERBK; for(c = b->entry; c < ce; c++) if(c->state == Cread) { *longp++ = c->waddr; left--; } putbuf(p); } nbyte = (n/sizeof(Off) - left) * sizeof(Off); con_write(FID2, cb->iobuf, cons.offset, nbyte); putbuf(cb);}voidloadcache(Device *dev, int dskno){ Iobuf *p, *cb; Off m, nbyte, *longp, count; Sidestarts ss; if(walkto("/adm/cache") || con_open(FID2, OREAD)) { print("cant open /adm/cache\n"); return; } cb = getbuf(devnone, Cwxx4, 0); cons.offset = 0; count = 0; if (dskno >= 0) wormsidestarts(dev, dskno, &ss); for(;;) { memset(cb->iobuf, 0, BUFSIZE); nbyte = con_read(FID2, cb->iobuf, cons.offset, 100) / sizeof(Off); if(nbyte <= 0) break; cons.offset += nbyte * sizeof(Off); longp = (Off *)cb->iobuf; while(nbyte > 0) { m = *longp++; nbyte--; if(m == 0) continue; /* if given a diskno, restrict to just that disc side */ if(dskno < 0 || m >= ss.sstart && m < ss.s1start) { p = getbuf(dev, m, Bread); if(p) putbuf(p); count++; } } } putbuf(cb); print("%lld blocks loaded from worm %d\n", (Wideoff)count, dskno);}voidmorecache(Device *dev, int dskno, Off size){ Iobuf *p; Off m, ml, mh, mm, count; Cache *h; Sidestarts ss; p = getbuf(CDEV(dev), CACHE_ADDR, Bread|Bres); if(!p || checktag(p, Tcache, QPSUPER)) panic("savecache: checktag c bucket"); h = (Cache*)p->iobuf; mm = h->wmax; putbuf(p); wormsidestarts(dev, dskno, &ss); ml = ss.sstart; /* start at beginning of disc side #dskno */ mh = ml + size; if(mh > mm) { mh = mm; print("limited to %lld\n", (Wideoff)mh-ml); } count = 0; for(m=ml; m < mh; m++) { p = getbuf(dev, m, Bread); if(p) putbuf(p); count++; } print("%lld blocks loaded from worm %d\n", (Wideoff)count, dskno);}voidblockcmp(Device *dev, Off wa, Off ca){ Iobuf *p1, *p2; int i, c; p1 = getbuf(WDEV(dev), wa, Bread); if(!p1) { print("blockcmp: wdev error\n"); return; } p2 = getbuf(CDEV(dev), ca, Bread); if(!p2) { print("blockcmp: cdev error\n"); putbuf(p1); return; } c = 0; for(i=0; i<RBUFSIZE; i++) if(p1->iobuf[i] != p2->iobuf[i]) { print("%4d: %.2x %.2x\n", i, p1->iobuf[i]&0xff, p2->iobuf[i]&0xff); c++; if(c >= 10) break; } if(c == 0) print("no error\n"); putbuf(p1); putbuf(p2);}voidwblock(Device *dev, Off addr){ Iobuf *p1; int i; p1 = getbuf(dev, addr, Bread); if(p1) { i = devwrite(WDEV(dev), addr, p1->iobuf); print("i = %d\n", i); putbuf(p1); }}voidcwtest(Device*){}#ifdef XXX/* garbage to change sb size * probably will need it someday */ fsz = number(0, 0, 10); count = 0; if(fsz == number(0, -1, 10)) count = -1; /* really do it */ print("fsize = %ld\n", fsz); cdev = CDEV(dev); cb = getbuf(cdev, CACHE_ADDR, Bread|Bres); if(!cb || checktag(cb, Tcache, QPSUPER)) panic("cwstats: checktag c bucket"); h = (Cache*)cb->iobuf; for(m=0; m<h->msize; m++) { p = getbuf(cdev, h->maddr + m/BKPERBLK, Bread|Bmod); if(!p || checktag(p, Tbuck, h->maddr + m/BKPERBLK)) panic("cwtest: checktag c bucket"); b = (Bucket*)p->iobuf + m%BKPERBLK; ce = b->entry + CEPERBK; for(c=b->entry; c<ce; c++) { if(c->waddr < fsz) continue; if(count < 0) { c->state = Cnone; continue; } if(c->state != Cdirty) count++; } putbuf(p); } if(count < 0) { print("old cache hsize = %ld\n", h->fsize); h->fsize = fsz; cb->flags |= Bmod; p = getbuf(dev, h->sbaddr, Bread|Bmod); s = (Superb*)p->iobuf; print("old super hsize = %ld\n", s->fsize); s->fsize = fsz; putbuf(p); } putbuf(cb); print("count = %lld\n", (Wideoff)count);#endifintconvstate(char *name){ int i; for(i=0; i<nelem(cwnames); i++) if(cwnames[i]) if(strcmp(cwnames[i], name) == 0) return i; return -1;}voidsearchtag(Device *d, Off a, int tag, int n){ Iobuf *p; Tag *t; int i; if(a == 0) a = getstartsb(d); p = getbuf(devnone, Cwxx2, 0); t = (Tag*)(p->iobuf+BUFSIZE); for(i=0; i<n; i++) { memset(p->iobuf, 0, RBUFSIZE); if(devread(WDEV(d), a+i, p->iobuf)) { if(n == 1000) break; continue; } if(t->tag == tag) { print("tag %d found at %Z %lld\n", tag, d, (Wideoff)a+i); break; } } putbuf(p);}voidcmd_cwcmd(int argc, char *argv[]){ Device *dev; char *arg; char str[28]; Off s1, s2, a, b, n; Cw *cw; if(argc <= 1) { print(" cwcmd mvstate state1 state2 [platter]\n"); print(" cwcmd prchain [start] [bakflg]\n"); print(" cwcmd searchtag [start] [tag] [blocks]\n"); print(" cwcmd touchsb\n"); print(" cwcmd savecache\n"); print(" cwcmd loadcache [dskno]\n"); print(" cwcmd morecache dskno [count]\n"); print(" cwcmd blockcmp wbno cbno\n"); print(" cwcmd startdump [01]\n"); print(" cwcmd acct\n"); print(" cwcmd clearacct\n"); return; } arg = argv[1]; /* * items not depend on a cw filesystem */ if(strcmp(arg, "acct") == 0) { for(a=0; a<nelem(growacct); a++) { b = growacct[a]; if(b) { uidtostr(str, a, 1); print("%10lld %s\n", ((Wideoff)b*ADDFREE*RBUFSIZE+500000)/1000000, str); } } return; } if(strcmp(arg, "clearacct") == 0) { memset(growacct, 0, sizeof(growacct)); return; } /* * items depend on cw filesystem */ dev = cons.curfs->dev; if(dev == 0 || dev->type != Devcw || dev->private == 0) { print("cfs not a cw filesystem: %Z\n", dev); return; } cw = dev->private; if(strcmp(arg, "searchtag") == 0) { a = 0; if(argc > 2) a = number(argv[2], 0, 10); b = Tsuper; if(argc > 3) b = number(argv[3], 0, 10); n = 1000; if(argc > 4) n = number(argv[4], 0, 10); searchtag(dev, a, b, n); } else if(strcmp(arg, "mvstate") == 0) { if(argc < 4) goto bad; s1 = convstate(argv[2]); s2 = convstate(argv[3]); if(s1 < 0 || s2 < 0) goto bad; a = -1; if(argc > 4) a = number(argv[4], 0, 10); mvstates(dev, s1, s2, a); return; bad: print("cwcmd mvstate: bad args\n"); } else if(strcmp(arg, "prchain") == 0) { a = 0; if(argc > 2) a = number(argv[2], 0, 10); s1 = 0; if(argc > 3) s1 = number(argv[3], 0, 10); prchain(dev, a, s1); } else if(strcmp(arg, "touchsb") == 0) touchsb(dev); else if(strcmp(arg, "savecache") == 0) savecache(dev); else if(strcmp(arg, "loadcache") == 0) { s1 = -1; if(argc > 2) s1 = number(argv[2], 0, 10); loadcache(dev, s1); } else if(strcmp(arg, "morecache") == 0) { if(argc <= 2) { print("arg count\n"); return; } s1 = number(argv[2], 0, 10); if(argc > 3) s2 = number(argv[3], 0, 10); else s2 = wormsizeside(dev, s1); /* default to 1 disc side */ morecache(dev, s1, s2); } else if(strcmp(arg, "blockcmp") == 0) { if(argc < 4) { print("cannot arg count\n"); return; } s1 = number(argv[2], 0, 10); s2 = number(argv[3], 0, 10); blockcmp(dev, s1, s2); } else if(strcmp(arg, "startdump") == 0) { if(argc > 2) cw->nodump = number(argv[2], 0, 10); cw->nodump = !cw->nodump; if(cw->nodump) print("dump stopped\n"); else print("dump allowed\n"); } else if(strcmp(arg, "allflag") == 0) { if(argc > 2) cw->allflag = number(argv[2], 0, 10); else cw->allflag = !cw->allflag; print("allflag = %d; falsehits = %lld\n", cw->allflag, (Wideoff)cw->falsehits); } else if(strcmp(arg, "storesb") == 0) { a = 4168344; b = 0; if(argc > 2) a = number(argv[2], 4168344, 10); if(argc > 3) b = number(argv[3], 0, 10); storesb(dev, a, b); } else if(strcmp(arg, "test") == 0) cwtest(dev); else print("unknown cwcmd %s\n", arg);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -