/* * return the number of the highest-numbered block actually written, plus 1. * 0 indicates an error. */ static Devsize writtensize(Device *worm) { Devsize lim = devsize(worm); Iobuf *p; print("devsize(%Z) = %lld\n", worm, (Wideoff)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, Brd); if (p != 0) { /* actually read one okay? */ putbuf(p); break; } } print("limit(%Z) = %lld\n", worm, (Wideoff)lim); if (lim <= 0) return 0; return lim + 1; }
int fwormwrite(Device *d, Off b, void *c) { Iobuf *p; Device *fdev; Devsize l; if(DEBUG) print("fworm write %lld\n", (Wideoff)b); fdev = FDEV(d); l = devsize(fdev); l -= l/(BUFSIZE*8) + 1; if(b >= l) panic("fworm: wbounds %lld", (Wideoff)b); l += b/(BUFSIZE*8); p = getbuf(fdev, l, Brd|Bmod|Bres); if(!p || checktag(p, Tvirgo, l)) panic("fworm: checktag %lld", (Wideoff)l); l = b % (BUFSIZE*8); if((p->iobuf[l/8] & (1<<(l%8)))) { putbuf(p); print("fworm: write %lld\n", (Wideoff)b); return 1; } p->iobuf[l/8] |= 1<<(l%8); putbuf(p); return devwrite(fdev, b, c); }
int fwormread(Device *d, Off b, void *c) { Iobuf *p; Device *fdev; Devsize l; if(chatty > 1) fprint(2, "fworm read %lld\n", (Wideoff)b); fdev = FDEV(d); l = devsize(fdev); l -= l/(BUFSIZE*8) + 1; if(b >= l) panic("fworm: rbounds %lld", (Wideoff)b); l += b/(BUFSIZE*8); p = getbuf(fdev, l, Brd|Bres); if(!p || checktag(p, Tvirgo, l)) panic("fworm: checktag %lld", (Wideoff)l); l = b % (BUFSIZE*8); if(!(p->iobuf[l/8] & (1<<(l%8)))) { putbuf(p); fprint(2, "fworm: read %lld\n", (Wideoff)b); return 1; } putbuf(p); return devread(fdev, b, c); }
void fwormream(Device *d) { Iobuf *p; Device *fdev; Off a, b; if(chatty) print("fworm ream\n"); devinit(d); fdev = FDEV(d); a = fwormsize(d); b = devsize(fdev); if(chatty){ print("\tfwsize = %lld\n", (Wideoff)a); print("\tbwsize = %lld\n", (Wideoff)b-a); } for(; a < b; a++) { p = getbuf(fdev, a, Bmod|Bres); if(!p) panic("fworm: init"); memset(p->iobuf, 0, RBUFSIZE); settag(p, Tvirgo, a); putbuf(p); } }
Devsize fwormsize(Device *d) { Devsize l; l = devsize(FDEV(d)); l -= l/(BUFSIZE*8) + 1; return l; }
void superream(Device dev, long addr) { Iobuf *p; Superb *s; long i; p = getbuf(dev, addr, Bmod|Bimm); memset(p->iobuf, 0, RBUFSIZE); settag(p, Tsuper, QPSUPER); s = (Superb*)p->iobuf; s->fstart = 1; s->fsize = devsize(dev); s->fbuf.nfree = 1; s->qidgen = 10; for(i=s->fsize-1; i>=addr+2; i--) addfree(dev, i, s); putbuf(p); }
/* copy device from src to dest */ static int dodevcopy(void) { Device *from, *to; Iobuf *p; Off a; Devsize lim, tosize; /* * convert config strings into Devices. */ from = iconfig(src); if(f.error || from == nil) { print("bad src device %s\n", src); return -1; } to = iconfig(dest); if(f.error || to == nil) { print("bad dest device %s\n", dest); return -1; } /* * initialise devices, size them, more sanity checking. */ devinit(from); lim = devsize(from); if(lim == 0) panic("no blocks to copy on %Z", from); devinit(to); tosize = devsize(to); if(tosize == 0) panic("no blocks to copy on %Z", to); /* use smaller of the device sizes */ if (tosize < lim) lim = tosize; print("copy %Z to %Z in 8 seconds\n", from, to); delay(8000); if (userabort("preparing to copy")) return -1; print("copying dev: %lld blocks from %Z to %Z\n", (Wideoff)lim, from, to); /* * Copy all blocks, a block at a time. */ for (a = 0; a < lim; a++) { if (userabort("copy")) break; p = getbuf(from, a, Brd); /* * 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("%lld not written yet; can't read\n", (Wideoff)a); continue; } if (to != 0 && devwrite(to, p->addr, p->iobuf) != 0) { print("out block %lld: write error; bailing", (Wideoff)a); break; } putbuf(p); if(a % 20000 == 0) print("block %lld %T\n", (Wideoff)a, time(nil)); } /* * wrap up: sync target */ print("copied %lld blocks from %Z to %Z\n", (Wideoff)a, from, to); sync("devcopy"); return 0; }