Browse Source

Plan 9 from Bell Labs 2003-03-15

David du Colombier 21 years ago
parent
commit
9588eb132e

+ 6 - 6
dist/replica/plan9.db

@@ -10658,7 +10658,7 @@ sys/src/fs/choline/io.h - 664 sys sys 1037805081 6576
 sys/src/fs/choline/mem.h - 664 sys sys 1015110108 2865
 sys/src/fs/choline/mkfile - 664 sys sys 1045536422 1673
 sys/src/fs/dev - 20000000775 sys sys 1015109978 0
-sys/src/fs/dev/cw.c - 664 sys sys 1045502886 41997
+sys/src/fs/dev/cw.c - 664 sys sys 1047663897 42252
 sys/src/fs/dev/fworm.c - 664 sys sys 1015109971 1737
 sys/src/fs/dev/juke.c - 664 sys sys 1040567254 22891
 sys/src/fs/dev/mkfile - 664 sys sys 1015109974 132
@@ -10705,7 +10705,7 @@ sys/src/fs/pc/etherif.c - 664 sys sys 1037805117 6324
 sys/src/fs/pc/etherif.h - 664 sys sys 1015110057 730
 sys/src/fs/pc/ethermii.c - 664 sys sys 1037805117 1247
 sys/src/fs/pc/ethermii.h - 664 sys sys 1037805117 980
-sys/src/fs/pc/floppy.c - 664 sys sys 1037805117 13814
+sys/src/fs/pc/floppy.c - 664 sys sys 1047663990 13993
 sys/src/fs/pc/kbd.c - 664 sys sys 1015110060 6030
 sys/src/fs/pc/l.s - 664 sys sys 1032062001 10656
 sys/src/fs/pc/lock.c - 664 sys sys 1045502910 3591
@@ -10713,7 +10713,7 @@ sys/src/fs/pc/malloc.c - 664 sys sys 1037805118 2854
 sys/src/fs/pc/mkfile - 664 sys sys 1037805118 369
 sys/src/fs/pc/mmu.c - 664 sys sys 1015110065 8414
 sys/src/fs/pc/nvr.c - 664 sys sys 1015110066 669
-sys/src/fs/pc/pc.c - 664 sys sys 1037805118 7937
+sys/src/fs/pc/pc.c - 664 sys sys 1047663991 7938
 sys/src/fs/pc/pci.c - 664 sys sys 1037805118 11638
 sys/src/fs/pc/script.i - 664 sys sys 1015110072 27323
 sys/src/fs/pc/scsi.c - 664 sys sys 1037805118 8667
@@ -10728,10 +10728,10 @@ sys/src/fs/port/9p1lib.c - 664 sys sys 1015109996 7629
 sys/src/fs/port/9p2.c - 664 sys sys 1044290935 36142
 sys/src/fs/port/all.h - 664 sys sys 1045502862 1927
 sys/src/fs/port/auth.c - 664 sys sys 1041361345 7608
-sys/src/fs/port/chk.c - 664 sys sys 1037805158 13882
+sys/src/fs/port/chk.c - 664 sys sys 1047663951 14533
 sys/src/fs/port/clock.c - 664 sys sys 1015110006 4033
 sys/src/fs/port/con.c - 664 sys sys 1037805158 16254
-sys/src/fs/port/config.c - 664 sys sys 1045502863 15760
+sys/src/fs/port/config.c - 664 sys sys 1047663951 18054
 sys/src/fs/port/console.c - 664 sys sys 1015110011 4821
 sys/src/fs/port/data.c - 664 sys sys 1041361346 4411
 sys/src/fs/port/dentry.c - 664 sys sys 1015110013 3801
@@ -10739,7 +10739,7 @@ sys/src/fs/port/devcons.c - 664 sys sys 1015110014 4329
 sys/src/fs/port/fcmd.c - 664 sys sys 1015110015 1266
 sys/src/fs/port/iobuf.c - 664 sys sys 1045502864 4845
 sys/src/fs/port/lib.h - 664 sys sys 1015110017 3335
-sys/src/fs/port/main.c - 664 sys sys 1037805158 5694
+sys/src/fs/port/main.c - 664 sys sys 1047663952 5698
 sys/src/fs/port/mkfile - 664 sys sys 1015110018 189
 sys/src/fs/port/portdat.h - 664 sys sys 1045502865 16642
 sys/src/fs/port/portfns.h - 664 sys sys 1037805159 7454

+ 6 - 0
dist/replica/plan9.log

@@ -18583,3 +18583,9 @@
 1047502864 0 c sys/games/lib/fortunes - 664 sys sys 1047502111 238601
 1047513673 0 c sys/src/cmd/vnc/compat.h - 664 sys sys 1047512521 3425
 1047513673 1 c sys/src/cmd/vnc/kbdv.c - 664 sys sys 1047512524 3513
+1047664890 0 c sys/src/fs/dev/cw.c - 664 sys sys 1047663897 42252
+1047664890 1 c sys/src/fs/pc/floppy.c - 664 sys sys 1047663990 13993
+1047664890 2 c sys/src/fs/pc/pc.c - 664 sys sys 1047663991 7938
+1047664890 3 c sys/src/fs/port/chk.c - 664 sys sys 1047663951 14533
+1047664890 4 c sys/src/fs/port/config.c - 664 sys sys 1047663951 18054
+1047664890 5 c sys/src/fs/port/main.c - 664 sys sys 1047663952 5698

+ 18 - 16
sys/src/fs/dev/cw.c

@@ -571,7 +571,7 @@ cwio(Device *dev, long addr, void *buf, int opcode)
 	c = getcentry(b, addr);
 	if(c == 0) {
 		putbuf(p);
-		print("disk cache bucket %ld is full\n", a1);
+		print("%Z disk cache bucket %ld is full\n", cw->cdev, a1);
 		return Cerror;
 	}
 	a2 += c - b->entry;
@@ -684,8 +684,8 @@ cwio(Device *dev, long addr, void *buf, int opcode)
 
 	case Ogrow:
 		if(state != Cnone) {
-			print("cwgrow with state = %s\n",
-				cwnames[state]);
+			print("%Z for block %ld cwgrow with state = %s\n",
+				cw->cdev, addr, cwnames[state]);
 			break;
 		}
 		c->state = Cdirty;
@@ -693,8 +693,8 @@ cwio(Device *dev, long addr, void *buf, int opcode)
 
 	case Odump:
 		if(state != Cdirty) {	/* BOTCH */
-			print("cwdump with state = %s\n",
-				cwnames[state]);
+			print("%Z for block %ld cwdump with state = %s\n",
+				cw->cdev, addr, cwnames[state]);
 			break;
 		}
 		c->state = Cdump;
@@ -704,8 +704,8 @@ cwio(Device *dev, long addr, void *buf, int opcode)
 	case Orele:
 		if(state != Cwrite) {
 			if(state != Cdump1)
-				print("cwrele with state = %s\n",
-					cwnames[state]);
+				print("%Z for block %ld cwrele with state = %s\n",
+					cw->cdev, addr, cwnames[state]);
 			break;
 		}
 		c->state = Cnone;
@@ -717,8 +717,8 @@ cwio(Device *dev, long addr, void *buf, int opcode)
 		break;
 	}
 	if(DEBUG)
-		print("cwio: %ld s=%s o=%s ns=%s\n",
-			addr, cwnames[state],
+		print("cwio: %Z %ld s=%s o=%s ns=%s\n",
+			dev, addr, cwnames[state],
 			cwnames[opcode],
 			cwnames[c->state]);
 	putbuf(p);
@@ -732,8 +732,8 @@ cwio(Device *dev, long addr, void *buf, int opcode)
 	return state;
 
 bad:
-	print("cw state = %s; cw opcode = %s",
-		cwnames[state], cwnames[opcode]);
+	print("%Z block %ld cw state = %s; cw opcode = %s",
+		dev, addr, cwnames[state], cwnames[opcode]);
 	return Cerror;
 }
 
@@ -990,14 +990,14 @@ getstartsb(Device *dev)
 	for(f=filsys; f->name; f++)
 		if(devcmpr(f->dev, dev) == 0)
 			goto found;
-print("getstartsb: not found 1 %Z\n", dev);
+print("getstartsb: no filsys for device %Z\n", dev);
 	return FIRST;
 
 found:
 	for(s=startsb; s->name; s++)
 		if(strcmp(f->name, s->name) == 0)
 			return s->startsb;
-print("getstartsb: not found 2 %Z %s\n", dev, f->name);
+print("getstartsb: no special starting superblock for %Z %s\n", dev, f->name);
 	return FIRST;
 }
 
@@ -1734,9 +1734,10 @@ touchsb(Device *dev)
 	memset(p->iobuf, 0, RBUFSIZE);
 	if(devread(WDEV(dev), m, p->iobuf) ||
 	   checktag(p, Tsuper, QPSUPER))
-		print("WORM SUPER BLOCK READ FAILED\n");
+		print("%Z block %ld WORM SUPER BLOCK READ FAILED\n",
+			WDEV(dev), m);
 	else
-		print("touch superblock %ld\n", m);
+		print("%Z touch superblock %ld\n", WDEV(dev), m);
 	putbuf(p);
 }
 
@@ -1819,7 +1820,8 @@ storesb(Device *dev, long last, int doit)
 
 	if(doit)
 	if(devwrite(WDEV(dev), sbaddr, ps->iobuf))
-		print("WORM SUPER BLOCK WRITE FAILED\n");
+		print("%Z block %ld WORM SUPER BLOCK WRITE FAILED\n",
+			WDEV(dev), sbaddr);
 	ps->flags = 0;
 	putbuf(ps);
 }

+ 12 - 0
sys/src/fs/pc/floppy.c

@@ -225,6 +225,18 @@ floppystop(Floppy *dp)
 	outb(Pdor, fl.motor | Fintena | Fena | dp->dev);
 }
 
+void
+floppyhalt(void)
+{
+	Floppy *dp;
+
+	for(dp = fl.d; dp < &fl.d[Maxfloppy]; dp++)
+		if((fl.motor&MOTORBIT(dp->dev)) && canqlock(&fl)){
+			floppystop(dp);
+			qunlock(&fl);
+		}
+}
+
 static void
 floppyalarm(Alarm* a, void *arg)
 {

+ 1 - 1
sys/src/fs/pc/pc.c

@@ -371,7 +371,7 @@ firmware(void)
 	 */
 	if((p = getconf("reset")) && cistrcmp(p, "manual") == 0){
 		predawn = 1;
-		print("\Hit Reset\n");
+		print("\nHit Reset\n");
 		for(;;);
 	}
 	pcireset();

+ 20 - 4
sys/src/fs/port/chk.c

@@ -1,4 +1,5 @@
 #include	"all.h"
+#include	"mem.h"		/* for KZERO for PADDR */
 
 static	char*	abits;
 static	long	sizabits;
@@ -45,17 +46,19 @@ static	void	qmark(long);
 static	void*	malloc(ulong);
 static	Iobuf*	xtag(long, int, long);
 
+/* copied from ../pc/etherif.h; should probably be in all.h */
+#define	HOWMANY(x, y)	(((x)+((y)-1))/(y))
+#define ROUNDUP(x, y)	(HOWMANY((x), (y))*(y))
+
 static
 void*
 malloc(ulong n)
 {
 	char *p, *q;
 
-	p = calloc;
-	while((ulong)p & 3)
-		p++;
+	p = (char *)ROUNDUP((ulong)calloc, BY2WD);
 	q = p+n;
-	if(((ulong)q&0x0fffffffL) >= conf.mem)
+	if(PADDR(q) >= conf.mem)
 		panic("check: mem size");
 	calloc = q;
 	memset(p, 0, n);
@@ -76,6 +79,7 @@ enum
 	Cream	= (1<<6),	/* clear all bad tags */
 	Cbad	= (1<<7),	/* clear all bad blocks */
 	Ctouch	= (1<<8),	/* touch old dir and indir */
+	Ctrim	= (1<<9),   /* trim fsize back to fit when checking free list */
 };
 
 static
@@ -94,6 +98,7 @@ struct
 	"ream",		Cream,
 	"bad",		Cbad,
 	"touch",	Ctouch,
+	"trim",		Ctrim,
 	0,
 };
 
@@ -126,6 +131,12 @@ cmd_check(int argc, char *argv[])
 	cwflag = (dev->type == Devcw) | (dev->type == Devro);
 	if(!ronly)
 		wlock(&mainlock);		/* check */
+	/*
+	 * ialloc(0, 1) doesn't actually allocate any storage, and may
+	 * return the same address each time.  see iobufinit().
+	 * check assumes that the rest of memory, from ialloc(0, 1)
+	 * up, is available to it, but does at least check in malloc().
+	 */
 	calloc = (char*)ialloc(0, 1) + 100000;
 	flags = flag;
 
@@ -604,6 +615,11 @@ ckfreelist(Superb *sb)
 	}
 	if(p)
 		putbuf(p);
+	if (flags & Ctrim) {
+		sb->fsize = fsize = hi--;	/* fsize = hi + 1 */
+		mod++;
+		print("set fsize to %ld\n", fsize);
+	}
 	print("lo = %ld; hi = %ld\n", lo, hi);
 }
 

+ 145 - 38
sys/src/fs/port/config.c

@@ -483,6 +483,8 @@ cmd_printconf(int, char *[])
 	putbuf(iob);
 }
 
+extern void floppyhalt(void);
+
 void
 sysinit(void)
 {
@@ -617,74 +619,177 @@ loop:
 		devinit(fs->dev);
 	}
 
-	if (copyworm)
-		dowormcopy();		/* no return */
+	floppyhalt();			/* don't wear out the floppy */
+	if (copyworm) {
+		dowormcopy();		/* can return if user quits early */
+		panic("copyworm bailed out!");
+	}
+}
+
+/* an unfinished idea.  a non-blocking rawchar() would help. */
+static int
+userabort(char *msg)
+{
+#ifdef IdeaIsFinished
+	if (consgetcifany() == 'q') {
+		print("aborting %s\n", msg);
+		return 1;
+	}
+#else
+	USED(msg);
+#endif /* IdeaIsFinished */
+	return 0;
+}
+
+static int
+blockok(Device *d, long a)
+{
+	Iobuf *p = getbuf(d, a, Bread);
+
+	if (p == 0) {
+		print("i/o error reading %Z block %ld\n", d, a);
+		return 0;
+	}
+	putbuf(p);
+	return 1;
+}
+
+/*
+ * special case for fake worms only:
+ * we need to size the inner cw's worm device.
+ * in particular, we want to avoid copying the fake-worm bitmap
+ * at the end of the device.
+ *
+ * N.B.: for real worms (e.g. cw jukes), we need to compute devsize(cw(juke)),
+ * *NOT* devsize(juke).
+ */
+static Device *
+wormof(Device *dev)
+{
+	Device *worm = dev, *cw;
+
+	if (dev->type == Devfworm) {
+		cw = dev->fw.fw;
+		if (cw != nil && cw->type == Devcw)
+			worm = cw->cw.w;
+	}
+	// print("wormof(%Z)=%Z\n", dev, worm);
+	return worm;
+}
+
+/*
+ * return the number of the highest-numbered block actually written, plus 1.
+ * 0 indicates an error.
+ */
+static long
+writtensize(Device *worm)
+{
+	long lim = devsize(worm);
+	Iobuf *p;
+
+	print("devsize(%Z) = %ld\n", worm, lim);
+	if (!blockok(worm, 0) || !blockok(worm, lim-1))
+		return 0;
+	delay(5*1000);
+	if (userabort("sanity checks"))
+		return 0;
+
+	/* find worm's last valid block in case "worm" is an (f)worm */
+	while (lim > 0) {
+		if (userabort("sizing")) {
+			lim = 0;		/* you lose */
+			break;
+		}
+		--lim;
+		p = getbuf(worm, lim, Bread);
+		if (p != 0) {			/* actually read one okay? */
+			putbuf(p);
+			break;
+		}
+	}
+	print("limit(%Z) = %ld\n", worm, lim);
+	return lim <= 0? 0: lim + 1;
 }
 
 extern int devatadebug, devataidedebug;
 
-/* copy worm fs from "main" to "output" */
+/* copy worm fs from "main"'s inner worm to "output" */
 static void
 dowormcopy(void)
 {
 	Filsys *f1, *f2;
-	Device *from, *to;
+	Device *fdev, *from, *to = nil;
 	Iobuf *p;
 	long a, lim;
 
-	/* find source and target file systems */
+	/*
+	 * convert file system names into Filsyss and Devices.
+	 */
+
 	f1 = fsstr("main");
 	if(f1 == nil)
 		panic("main file system missing");
+	fdev = f1->dev;
+	from = wormof(fdev);			/* fake worm special */
+
 	f2 = fsstr("output");
-	if(f2 == nil)
-		print("no output file system - check only");
-	from = f1->dev;
-	if(from->type == Devcw)
-		from = from->cw.w;
-	if (f2) {
+	if(f2 == nil) {
+		print("no output file system - check only\n\n");
+		print("reading worm from %Z (worm %Z)\n", fdev, from);
+	} else {
 		to = f2->dev;
-		print("copying worm from %Z to %Z, starting in 8 seconds\n",
-			from, to);
+		print("\ncopying worm from %Z (worm %Z) to %Z, starting in 8 seconds\n",
+			fdev, from, to);
 		delay(8000);
-	} else {
-		to = nil;
-		print("reading worm from %Z\n", from);
 	}
+	if (userabort("preparing to copy"))
+		return;
+
+	/*
+	 * initialise devices, size them, more sanity checking.
+	 */
 
-	/* ream target file system; initialise both fs's */
 	devinit(from);
-	if(to) {
+	if (0 && fdev != from) {
+		devinit(fdev);
+		print("debugging, sizing %Z first\n", fdev);
+		writtensize(fdev);
+	}
+	lim = writtensize(from);
+	if(lim == 0)
+		panic("no blocks to copy on %Z", from);
+	if (to) {
 		print("reaming %Z in 8 seconds\n", to);
 		delay(8000);
+		if (userabort("preparing to ream & copy"))
+			return;
 		devream(to, 0);
 		devinit(to);
+		print("copying worm: %ld blocks from %Z to %Z\n",
+			lim, from, to);
 	}
+	/* can't read to's blocks in case to is a real WORM device */
 
-	/* find last valid block in case fworm */
-	for (lim = devsize(from); lim != 0; lim--) {
-		p = getbuf(from, lim-1, Bread);
-		if (p != 0) {
-			putbuf(p);
-			break;
-		}
-	}
-	if(lim == 0)
-		panic("no blocks to copy on %Z", from);
-	print("limit %ld\n", lim);
+	/*
+	 * Copy written fs blocks, a block at a time (or just read
+	 * if no "output" fs).
+	 */
 
-	/* copy written fs blocks from source to target */
-	if (to)
-		print("copying worm\n");
-// devatadebug = 1;
-// devataidedebug = 1;
+	// devatadebug = 1; devataidedebug = 1;
 	for (a = 0; a < lim; a++) {
+		if (userabort("copy"))
+			break;
 		p = getbuf(from, a, Bread);
+		/*
+		 * if from is a real WORM device, we'll get errors trying to
+		 * read unwritten blocks, but the unwritten blocks need not
+		 * be contiguous.
+		 */
 		if (p == 0) {
-			print("%ld not written\n", a);
+			print("%ld not written yet; can't read\n", a);
 			continue;
 		}
-		if (to != 0 && devwrite(to, p->addr, p->iobuf)) {
+		if (to != 0 && devwrite(to, p->addr, p->iobuf) != 0) {
 			print("out block %ld: write error; bailing", a);
 			break;
 		}
@@ -693,10 +798,12 @@ dowormcopy(void)
 			print("block %ld %T\n", a, time());
 	}
 
-	/* sync target, loop */
+	/*
+	 * wrap up: sync target, loop
+	 */
 	print("copied %ld blocks from %Z to %Z\n", a, from, to);
 	sync("wormcopy");
-	delay(1000);
+	delay(2000);
 	print("looping; reset the machine at any time.\n");
 	for (; ; )
 		continue;		/* await reset */

+ 1 - 1
sys/src/fs/port/main.c

@@ -88,7 +88,7 @@ main(void)
 		gidspace = ialloc(conf.gidspace * sizeof(*gidspace), 0);
 		authinit();
 
-		print("Plan 9 v4 file server: IDE, mirror, wormcopy, allow, pcihinv, memory\n");
+		print("Plan 9 v4 file server: allow copyworm IDE memory mirror pcihinv readonly\n");
 		print("iobufinit\n");
 		iobufinit();