⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cw.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
	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 + -