예제 #1
0
Tnode*
initxsuper(void)
{
    Block *b;
    Tnode *t;

    b = readBlock(PartSuper, 0);
    if(b == nil)
        return stringnode("reading super: %r");
    if(!superUnpack(&super, b->data)) {
        blockPut(b);
        return stringnode("unpacking super: %r");
    }
    blockPut(b);
    t = stringnode("super "
                   "version=%#ux "
                   "epoch=[%#ux,%#ux) "
                   "qid=%#llux "
                   "active=%#x "
                   "next=%#x "
                   "current=%#x "
                   "last=%V "
                   "name=%s",
                   super.version, super.epochLow, super.epochHigh,
                   super.qid, super.active, super.next, super.current,
                   super.last, super.name);
    t->expand = xsuperexpand;
    return t;
}
예제 #2
0
파일: fs.c 프로젝트: bhanug/harvey
Block*
superGet(Cache *c, Super* super)
{
	Block *b;

	if((b = cacheLocal(c, PartSuper, 0, OReadWrite)) == nil){
		fprint(2, "%s: superGet: cacheLocal failed: %R\n", argv0);
		return nil;
	}
	if(!superUnpack(super, b->data)){
		fprint(2, "%s: superGet: superUnpack failed: %R\n", argv0);
		blockPut(b);
		return nil;
	}

	return b;
}
예제 #3
0
파일: epoch.c 프로젝트: AustenConrad/plan-9
void
main(int argc, char **argv)
{
	int fd;
	Header h;
	Super s;

	ARGBEGIN{
	default:
		usage();
	}ARGEND

	if(argc == 0 || argc > 2)
		usage();

	if((fd = open(argv[0], argc==2 ? ORDWR : OREAD)) < 0)
		sysfatal("open %s: %r", argv[0]);

	if(pread(fd, buf, HeaderSize, HeaderOffset) != HeaderSize)
		sysfatal("reading header: %r");
	if(!headerUnpack(&h, buf))
		sysfatal("unpacking header: %r");

	if(pread(fd, buf, h.blockSize, (vlong)h.super*h.blockSize) != h.blockSize)
		sysfatal("reading super block: %r");

	if(!superUnpack(&s, buf))
		sysfatal("unpacking super block: %r");

	print("epoch %d\n", s.epochLow);
	if(argc == 2){
		s.epochLow = strtoul(argv[1], 0, 0);
		superPack(&s, buf);
		if(pwrite(fd, buf, h.blockSize, (vlong)h.super*h.blockSize) != h.blockSize)
			sysfatal("writing super block: %r");
	}
	exits(0);
}
예제 #4
0
파일: fs.c 프로젝트: bhanug/harvey
Fs *
fsOpen(char *file, VtSession *z, int32_t ncache, int mode)
{
	int fd, m;
	uint8_t oscore[VtScoreSize];
	Block *b, *bs;
	Disk *disk;
	Fs *fs;
	Super super;

	switch(mode){
	default:
		vtSetError(EBadMode);
		return nil;
	case OReadOnly:
		m = OREAD;
		break;
	case OReadWrite:
		m = ORDWR;
		break;
	}
	fd = open(file, m);
	if(fd < 0){
		vtSetError("open %s: %r", file);
		return nil;
	}

	bwatchInit();
	disk = diskAlloc(fd);
	if(disk == nil){
		vtSetError("diskAlloc: %R");
		close(fd);
		return nil;
	}

	fs = vtMemAllocZ(sizeof(Fs));
	fs->mode = mode;
	fs->name = vtStrDup(file);
	fs->blockSize = diskBlockSize(disk);
	fs->elk = vtLockAlloc();
	fs->cache = cacheAlloc(disk, z, ncache, mode);
	if(mode == OReadWrite && z)
		fs->arch = archInit(fs->cache, disk, fs, z);
	fs->z = z;

	b = cacheLocal(fs->cache, PartSuper, 0, mode);
	if(b == nil)
		goto Err;
	if(!superUnpack(&super, b->data)){
		blockPut(b);
		vtSetError("bad super block");
		goto Err;
	}
	blockPut(b);

	fs->ehi = super.epochHigh;
	fs->elo = super.epochLow;

//fprint(2, "%s: fs->ehi %d fs->elo %d active=%d\n", argv0, fs->ehi, fs->elo, super.active);

	fs->source = sourceRoot(fs, super.active, mode);
	if(fs->source == nil){
		/*
		 * Perhaps it failed because the block is copy-on-write.
		 * Do the copy and try again.
		 */
		if(mode == OReadOnly || strcmp(vtGetError(), EBadRoot) != 0)
			goto Err;
		b = cacheLocalData(fs->cache, super.active, BtDir, RootTag,
			OReadWrite, 0);
		if(b == nil){
			vtSetError("cacheLocalData: %R");
			goto Err;
		}
		if(b->l.epoch == fs->ehi){
			blockPut(b);
			vtSetError("bad root source block");
			goto Err;
		}
		b = blockCopy(b, RootTag, fs->ehi, fs->elo);
		if(b == nil)
			goto Err;
		localToGlobal(super.active, oscore);
		super.active = b->addr;
		bs = cacheLocal(fs->cache, PartSuper, 0, OReadWrite);
		if(bs == nil){
			blockPut(b);
			vtSetError("cacheLocal: %R");
			goto Err;
		}
		superPack(&super, bs->data);
		blockDependency(bs, b, 0, oscore, nil);
		blockPut(b);
		blockDirty(bs);
		blockRemoveLink(bs, globalToLocal(oscore), BtDir, RootTag, 0);
		blockPut(bs);
		fs->source = sourceRoot(fs, super.active, mode);
		if(fs->source == nil){
			vtSetError("sourceRoot: %R");
			goto Err;
		}
	}

//fprint(2, "%s: got fs source\n", argv0);

	vtRLock(fs->elk);
	fs->file = fileRoot(fs->source);
	fs->source->file = fs->file;		/* point back */
	vtRUnlock(fs->elk);
	if(fs->file == nil){
		vtSetError("fileRoot: %R");
		goto Err;
	}

//fprint(2, "%s: got file root\n", argv0);

	if(mode == OReadWrite){
		fs->metaFlush = periodicAlloc(fsMetaFlush, fs, 1000);
		fs->snap = snapInit(fs);
	}
	return fs;

Err:
fprint(2, "%s: fsOpen error\n", argv0);
	fsClose(fs);
	return nil;
}