Example #1
0
bool CipherFileIO::writeOneBlock(const IORequest &req) {

  if (haveHeader && fsConfig->reverseEncryption) {
    VLOG(1)
        << "writing to a reverse mount with per-file IVs is not implemented";
    return false;
  }

  int bs = blockSize();
  off_t blockNum = req.offset / bs;

  if (haveHeader && fileIV == 0) initHeader();

  bool ok;
  if (req.dataLen != bs) {
    ok = streamWrite(req.data, (int)req.dataLen, blockNum ^ fileIV);
  } else {
    ok = blockWrite(req.data, (int)req.dataLen, blockNum ^ fileIV);
  }

  if (ok) {
    if (haveHeader) {
      IORequest tmpReq = req;
      tmpReq.offset += HEADER_SIZE;
      ok = base->write(tmpReq);
    } else
      ok = base->write(req);
  } else {
    VLOG(1) << "encodeBlock failed for block " << blockNum << ", size "
            << req.dataLen;
    ok = false;
  }
  return ok;
}
Example #2
0
static u32int
rootInit(Entry *e)
{
	ulong addr;
	u32int tag;

	tag = tagGen();

	addr = blockAlloc(BtDir, tag);
	memset(buf, 0, bsize);

	/* root meta data is in the third entry */
	entryPack(e, buf, 2);

	entryInit(e);
	e->flags |= VtEntryDir;
	entryPack(e, buf, 0);

	entryInit(e);
	entryPack(e, buf, 1);

	blockWrite(PartData, addr);

	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;
}
Example #3
0
static void
rootMetaInit(Entry *e)
{
	u32int addr;
	u32int tag;
	DirEntry de;
	MetaBlock mb;
	MetaEntry me;

	memset(&de, 0, sizeof(de));
	de.elem = vtStrDup("root");
	de.entry = 0;
	de.gen = 0;
	de.mentry = 1;
	de.mgen = 0;
	de.size = 0;
	de.qid = qid++;
	de.uid = vtStrDup("adm");
	de.gid = vtStrDup("adm");
	de.mid = vtStrDup("adm");
	de.mtime = time(0);
	de.mcount = 0;
	de.ctime = time(0);
	de.atime = time(0);
	de.mode = ModeDir | 0555;

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

	/* build up meta block */
	memset(buf, 0, bsize);
	mbInit(&mb, buf, bsize, bsize/100);
	me.size = deSize(&de);
	me.p = mbAlloc(&mb, me.size);
	assert(me.p != nil);
	dePack(&de, &me);
	mbInsert(&mb, 0, &me);
	mbPack(&mb);
	blockWrite(PartData, addr);
	deCleanup(&de);

	/* build up entry for meta block */
	entryInit(e);
	e->flags |= VtEntryLocal;
 	e->size = bsize;
	e->tag = tag;
	localToGlobal(addr, e->score);
}
Example #4
0
static void
superInit(char *label, u32int root, uchar score[VtScoreSize])
{
	Super s;

	memset(buf, 0, bsize);
	memset(&s, 0, sizeof(s));
	s.version = SuperVersion;
	s.epochLow = 1;
	s.epochHigh = 1;
	s.qid = qid;
	s.active = root;
	s.next = NilBlock;
	s.current = NilBlock;
	strecpy(s.name, s.name+sizeof(s.name), label);
	memmove(s.last, score, VtScoreSize);

	superPack(&s, buf);
	blockWrite(PartSuper, 0);
}
Example #5
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++;
}
Example #6
0
File: fs.c Project: bhanug/harvey
void
superWrite(Block* b, Super* super, int forceWrite)
{
	superPack(super, b->data);
	blockDirty(b);
	if(forceWrite){
		while(!blockWrite(b, Waitlock)){
			/* this should no longer happen */
			fprint(2, "%s: could not write super block; "
				"waiting 10 seconds\n", argv0);
			sleep(10*1000);
		}
		while(b->iostate != BioClean && b->iostate != BioDirty){
			assert(b->iostate == BioWriting);
			vtSleep(b->ioready);
		}
		/*
		 * it's okay that b might still be dirty.
		 * that means it got written out but with an old root pointer,
		 * but the other fields went out, and those are the ones
		 * we really care about.  (specifically, epochHigh; see fsSnapshot).
		 */
	}
}
Example #7
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);
}
Example #8
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;
}