예제 #1
0
파일: rtest.c 프로젝트: AustenConrad/plan-9
void
main(int argc, char *argv[])
{
	VtSession *z;
	int i, j, t;
	int start;
	uchar buf[BlockSize];

	srand(time(0));

	ARGBEGIN{
	case 'r':
		rflag++;
		break;
	case 'n':
		nblock = atoi(ARGF());
		break;
	}ARGEND

	for(i=0; i<nblock; i++)
		perm[i] = i;

	if(rflag) {
		for(i=0; i<nblock; i++) {
			j = nrand(nblock);
			t = perm[j];
			perm[j] = perm[i];
			perm[i] = t;
		}
	}

	if(readn(0, data, VtScoreSize*nblock) < VtScoreSize*nblock)
		sysfatal("read failed: %r");

	vtAttach();

	z = vtDial("iolaire2");
	if(z == nil)
		sysfatal("cound not connect to venti");
	if(!vtConnect(z, 0))
		vtFatal("vtConnect: %s", vtGetError());

	print("starting\n");

	start = times(0);

	if(rflag && nblock > 10000)
		nblock = 10000;

	for(i=0; i<nblock; i++) {
		if(vtRead(z, data+perm[i]*VtScoreSize, VtDataType, buf, BlockSize) < 0)
			vtFatal("vtRead failed: %d: %s", i, vtGetError());
	}

	print("time = %f\n", (times(0) - start)*0.001);

	vtClose(z);
	vtDetach();
}
예제 #2
0
static void
partition(int fd, int bsize, Header *h)
{
	ulong nblock, ndata, nlabel;
	ulong lpb;

	if(bsize % 512 != 0)
		sysfatal("block size must be a multiple of 512 bytes");
	if(bsize > VtMaxLumpSize)
		sysfatal("block size must be less than %d", VtMaxLumpSize);

	memset(h, 0, sizeof(*h));
	h->blockSize = bsize;

	lpb = bsize/LabelSize;

	nblock = fdsize(fd)/bsize;

	/* sanity check */
	if(nblock < (HeaderOffset*10)/bsize)
		vtFatal("file too small");

	h->super = (HeaderOffset + 2*bsize)/bsize;
	h->label = h->super + 1;
	ndata = ((u64int)lpb)*(nblock - h->label)/(lpb+1);
	nlabel = (ndata + lpb - 1)/lpb;
	h->data = h->label + nlabel;
	h->end = h->data + ndata;

}
예제 #3
0
static void
addFile(File *root, char *name, uint mode)
{
	File *f;

	f = fileCreate(root, name, mode | ModeDir, "adm");
	if(f == nil)
		vtFatal("could not create file: %s: %r", name);
	fileDecRef(f);
}
예제 #4
0
static int
ventiRead(uchar score[VtScoreSize], int type)
{
	int n;

	n = vtRead(z, score, type, buf, bsize);
	if(n < 0)
		vtFatal("ventiRead %V (%d) failed: %R", score, type);
	vtZeroExtend(type, buf, n, bsize);
	return n;
}
예제 #5
0
파일: plan9-io.c 프로젝트: npe9/harvey
void *
vtMemRealloc(void *p, int size)
{
	if(p == nil)
		return vtMemAlloc(size);
	p = realloc(p, size);
	if(p == 0)
		vtFatal("vtRealloc: out of memory");
	setrealloctag(p, getcallerpc(&size));
	return p;
}
예제 #6
0
파일: plan9-io.c 프로젝트: npe9/harvey
void *
vtMemAlloc(int size)
{
	void *p;

	p = malloc(size);
	if(p == 0)
		vtFatal("vtMemAlloc: out of memory");
	setmalloctag(p, getcallerpc(&size));
	return p;
}
예제 #7
0
static u64int
fdsize(int fd)
{
	Dir *dir;
	u64int size;

	dir = dirfstat(fd);
	if(dir == nil)
		vtFatal("could not stat file: %r");
	size = dir->length;
	free(dir);
	return size;
}
예제 #8
0
static void
topLevel(char *name)
{
	Fs *fs;
	File *root;

	/* ok, now we can open as a fs */
	fs = fsOpen(name, z, 100, OReadWrite);
	if(fs == nil)
		vtFatal("could not open file system: %r");
	vtRLock(fs->elk);
	root = fsGetRoot(fs);
	if(root == nil)
		vtFatal("could not open root: %r");
	addFile(root, "active", 0555);
	addFile(root, "archive", 0555);
	addFile(root, "snapshot", 0555);
	fileDecRef(root);
	if(iso9660file)
		iso9660copy(fs);
	vtRUnlock(fs->elk);
	fsClose(fs);
}
예제 #9
0
static u32int
blockAlloc(int type, u32int tag)
{
	static u32int addr;
	Label l;
	int lpb;

	lpb = bsize/LabelSize;

	blockRead(PartLabel, addr/lpb);
	if(!labelUnpack(&l, buf, addr % lpb))
		vtFatal("bad label: %r");
	if(l.state != BsFree)
		vtFatal("want to allocate block already in use");
	l.epoch = 1;
	l.epochClose = ~(u32int)0;
	l.type = type;
	l.state = BsAlloc;
	l.tag = tag;
	labelPack(&l, buf, addr % lpb);
	blockWrite(PartLabel, addr/lpb);
	return addr++;
}
예제 #10
0
파일: plan9-thread.c 프로젝트: npe9/harvey
static void
vtThreadInit(void)
{
	static Lock lk;

	lock(&lk);
	if(vtRock != nil) {
		unlock(&lk);
		return;
	}
	vtRock = privalloc();
	if(vtRock == nil)
		vtFatal("can't allocate thread-private storage");
	unlock(&lk);
}
예제 #11
0
파일: fs.c 프로젝트: bhanug/harvey
void
fsClose(Fs *fs)
{
	vtRLock(fs->elk);
	periodicKill(fs->metaFlush);
	snapClose(fs->snap);
	if(fs->file){
		fileMetaFlush(fs->file, 0);
		if(!fileDecRef(fs->file))
			vtFatal("fsClose: files still in use: %r\n");
	}
	fs->file = nil;
	sourceClose(fs->source);
	cacheFree(fs->cache);
	if(fs->arch)
		archFree(fs->arch);
	vtMemFree(fs->name);
	vtRUnlock(fs->elk);
	vtLockFree(fs->elk);
	memset(fs, ~0, sizeof(Fs));
	vtMemFree(fs);
}
예제 #12
0
void
main(int argc, char *argv[])
{
	int fd, force;
	Header h;
	ulong bn;
	Entry e;
	char *label = "vfs";
	char *host = nil;
	char *score = nil;
	u32int root;
	Dir *d;

	force = 0;
	ARGBEGIN{
	default:
		usage();
	case 'b':
		bsize = unittoull(EARGF(usage()));
		if(bsize == ~0)
			usage();
		break;
	case 'h':
		host = EARGF(usage());
		break;
	case 'i':
		iso9660file = EARGF(usage());
		iso9660off = atoi(EARGF(usage()));
		break;
	case 'l':
		label = EARGF(usage());
		break;
	case 'v':
		score = EARGF(usage());
		break;

	/*
	 * This is -y instead of -f because flchk has a
	 * (frequently used) -f option.  I type flfmt instead
	 * of flchk all the time, and want to make it hard
	 * to reformat my file system accidentally.
	 */
	case 'y':
		force = 1;
		break;
	}ARGEND

	if(argc != 1)
		usage();

	if(iso9660file && score)
		vtFatal("cannot use -i with -v");

	vtAttach();

	fmtinstall('V', scoreFmt);
	fmtinstall('R', vtErrFmt);
	fmtinstall('L', labelFmt);

	fd = open(argv[0], ORDWR);
	if(fd < 0)
		vtFatal("could not open file: %s: %r", argv[0]);

	buf = vtMemAllocZ(bsize);
	if(pread(fd, buf, bsize, HeaderOffset) != bsize)
		vtFatal("could not read fs header block: %r");

	if(headerUnpack(&h, buf) && !force
	&& !confirm("fs header block already exists; are you sure?"))
		goto Out;

	if((d = dirfstat(fd)) == nil)
		vtFatal("dirfstat: %r");

	if(d->type == 'M' && !force
	&& !confirm("fs file is mounted via devmnt (is not a kernel device); are you sure?"))
		goto Out;

	partition(fd, bsize, &h);
	headerPack(&h, buf);
	if(pwrite(fd, buf, bsize, HeaderOffset) < bsize)
		vtFatal("could not write fs header: %r");

	disk = diskAlloc(fd);
	if(disk == nil)
		vtFatal("could not open disk: %r");

	if(iso9660file)
		iso9660init(fd, &h, iso9660file, iso9660off);

	/* zero labels */
	memset(buf, 0, bsize);
	for(bn = 0; bn < diskSize(disk, PartLabel); bn++)
		blockWrite(PartLabel, bn);

	if(iso9660file)
		iso9660labels(disk, buf, blockWrite);

	if(score)
		root = ventiRoot(host, score);
	else{
		rootMetaInit(&e);
		root = rootInit(&e);
	}

	superInit(label, root, vtZeroScore);
	diskFree(disk);

	if(score == nil)
		topLevel(argv[0]);

Out:
	vtDetach();
	exits(0);
}
예제 #13
0
static u32int
ventiRoot(char *host, char *s)
{
	int i, n;
	uchar score[VtScoreSize];
	u32int addr, tag;
	DirEntry de;
	MetaBlock mb;
	MetaEntry me;
	Entry e;
	VtRoot root;

	if(!parseScore(score, s))
		vtFatal("bad score '%s'", s);

	if((z = vtDial(host, 0)) == nil
	|| !vtConnect(z, nil))
		vtFatal("connect to venti: %R");

	tag = tagGen();
	addr = blockAlloc(BtDir, tag);

	ventiRead(score, VtRootType);
	if(!vtRootUnpack(&root, buf))
		vtFatal("corrupted root: vtRootUnpack");
	n = ventiRead(root.score, VtDirType);

	/*
	 * Fossil's vac archives start with an extra layer of source,
	 * but vac's don't.
	 */
	if(n <= 2*VtEntrySize){
		if(!entryUnpack(&e, buf, 0))
			vtFatal("bad root: top entry");
		n = ventiRead(e.score, VtDirType);
	}

	/*
	 * There should be three root sources (and nothing else) here.
	 */
	for(i=0; i<3; i++){
		if(!entryUnpack(&e, buf, i)
		|| !(e.flags&VtEntryActive)
		|| e.psize < 256
		|| e.dsize < 256)
			vtFatal("bad root: entry %d", i);
		fprint(2, "%V\n", e.score);
	}
	if(n > 3*VtEntrySize)
		vtFatal("bad root: entry count");

	blockWrite(PartData, addr);

	/*
	 * Maximum qid is recorded in root's msource, entry #2 (conveniently in e).
	 */
	ventiRead(e.score, VtDataType);
	if(!mbUnpack(&mb, buf, bsize))
		vtFatal("bad root: mbUnpack");
	meUnpack(&me, &mb, 0);
	if(!deUnpack(&de, &me))
		vtFatal("bad root: dirUnpack");
	if(!de.qidSpace)
		vtFatal("bad root: no qidSpace");
	qid = de.qidMax;

	/*
	 * Recreate the top layer of source.
	 */
	entryInit(&e);
	e.flags |= VtEntryLocal|VtEntryDir;
	e.size = VtEntrySize*3;
	e.tag = tag;
	localToGlobal(addr, e.score);

	addr = blockAlloc(BtDir, RootTag);
	memset(buf, 0, bsize);
	entryPack(&e, buf, 0);
	blockWrite(PartData, addr);

	return addr;
}
예제 #14
0
static void
blockWrite(int part, u32int addr)
{
	if(!diskWriteRaw(disk, part, addr, buf))
		vtFatal("write failed: %r");
}
예제 #15
0
static void
blockRead(int part, u32int addr)
{
	if(!diskReadRaw(disk, part, addr, buf))
		vtFatal("read failed: %r");
}