#include "stdinc.h"
#include "vac.h"
#include "dat.h"
#include "fns.h"
#include "error.h"

#define debug 0

/*
 * Vac file system.  This is a simplified version of the same code in Fossil.
 * 
 * The locking order in the tree is upward: a thread can hold the lock
 * for a VacFile and then acquire the lock of f->up (the parent),
 * but not vice-versa.
 * 
 * A vac file is one or two venti files.  Plain data files are one venti file,
 * while directores are two: a venti data file containing traditional
 * directory entries, and a venti directory file containing venti 
 * directory entries.  The traditional directory entries in the data file
 * contain integers indexing into the venti directory entry file.
 * It's a little complicated, but it makes the data usable by standard
 * tools like venti/copy.
 *
 */
 
static int filemetaflush(VacFile*, char*);

struct VacFile
{
	VacFs	*fs;	/* immutable */

	/* meta data for file: protected by the lk in the parent */
	int		ref;	/* holds this data structure up */

	int		partial;	/* file was never really open */
	int		removed;	/* file has been removed */
	int		dirty;	/* dir is dirty with respect to meta data in block */
	u32int	boff;		/* block offset within msource for this file's metadata */
	VacDir	dir;		/* metadata for this file */
	VacFile	*up;		/* parent file */
	VacFile	*next;	/* sibling */

	RWLock	lk;		/* lock for the following */
	VtFile	*source;	/* actual data */
	VtFile	*msource;	/* metadata for children in a directory */
	VacFile	*down;	/* children */
	int		mode;
	
	uvlong	qidoffset;	/* qid offset */
};

static VacFile*
filealloc(VacFs *fs)
{
	VacFile *f;

	f = vtmallocz(sizeof(VacFile));
	f->ref = 1;
	f->fs = fs;
	f->boff = NilBlock;
	f->mode = fs->mode;
	return f;
}

static void
filefree(VacFile *f)
{
	vtfileclose(f->source);
	vtfileclose(f->msource);
	vdcleanup(&f->dir);
	memset(f, ~0, sizeof *f);	/* paranoia */
	vtfree(f);
}

static int
chksource(VacFile *f)
{
	if(f->partial)
		return 0;

	if(f->source == nil
	|| ((f->dir.mode & ModeDir) && f->msource == nil)){
		werrstr(ERemoved);
		return -1;
	}
	return 0;
}

static int
filelock(VacFile *f)
{
	wlock(&f->lk);
	if(chksource(f) < 0){
		wunlock(&f->lk);
		return -1;
	}
	return 0;
}

static void
fileunlock(VacFile *f)
{
	wunlock(&f->lk);
}

static int
filerlock(VacFile *f)
{
	rlock(&f->lk);
	if(chksource(f) < 0){
		runlock(&f->lk);
		return -1;
	}
	return 0;
}

static void
filerunlock(VacFile *f)
{
	runlock(&f->lk);
}

/*
 * The file metadata, like f->dir and f->ref,
 * are synchronized via the parent's lock.
 * This is why locking order goes up.
 */
static void
filemetalock(VacFile *f)
{
	assert(f->up != nil);
	wlock(&f->up->lk);
}

static void
filemetaunlock(VacFile *f)
{
	wunlock(&f->up->lk);
}

uvlong
vacfilegetid(VacFile *f)
{
	/* immutable */
	return f->qidoffset + f->dir.qid;
}

uvlong
vacfilegetqidoffset(VacFile *f)
{
	return f->qidoffset;
}

ulong
vacfilegetmcount(VacFile *f)
{
	ulong mcount;

	filemetalock(f);
	mcount = f->dir.mcount;
	filemetaunlock(f);
	return mcount;
}

ulong
vacfilegetmode(VacFile *f)
{
	ulong mode;

	filemetalock(f);
	mode = f->dir.mode;
	filemetaunlock(f);
	return mode;
}

int
vacfileisdir(VacFile *f)
{
	/* immutable */
	return (f->dir.mode & ModeDir) != 0;
}

int
vacfileisroot(VacFile *f)
{
	return f == f->fs->root;
}

/*
 * The files are reference counted, and while the reference
 * is bigger than zero, each file can be found in its parent's
 * f->down list (chains via f->next), so that multiple threads
 * end up sharing a VacFile* when referring to the same file.
 *
 * Each VacFile holds a reference to its parent.
 */
VacFile*
vacfileincref(VacFile *vf)
{
	filemetalock(vf);
	assert(vf->ref > 0);
	vf->ref++;
	filemetaunlock(vf);
	return vf;
}

int
vacfiledecref(VacFile *f)
{
	VacFile *p, *q, **qq;

	if(f->up == nil){
		/* never linked in */
		assert(f->ref == 1);
		filefree(f);
		return 0;
	}
	
	filemetalock(f);
	f->ref--;
	if(f->ref > 0){
		filemetaunlock(f);
		return -1;
	}
	assert(f->ref == 0);
	assert(f->down == nil);

	if(f->source && vtfilelock(f->source, -1) >= 0){
		vtfileflush(f->source);
		vtfileunlock(f->source);
	}
	if(f->msource && vtfilelock(f->msource, -1) >= 0){
		vtfileflush(f->msource);
		vtfileunlock(f->msource);
	}

	/*
	 * Flush f's directory information to the cache.
	 */
	filemetaflush(f, nil);

	p = f->up;
	qq = &p->down;
	for(q = *qq; q; q = *qq){
		if(q == f)
			break;
		qq = &q->next;
	}
	assert(q != nil);
	*qq = f->next;

	filemetaunlock(f);
	filefree(f);
	vacfiledecref(p);
	return 0;
}


/* 
 * Construct a vacfile for the root of a vac tree, given the 
 * venti file for the root information.  That venti file is a 
 * directory file containing VtEntries for three more venti files:
 * the two venti files making up the root directory, and a 
 * third venti file that would be the metadata half of the 
 * "root's parent".
 *
 * Fossil generates slightly different vac files, due to a now
 * impossible-to-change bug, which contain a VtEntry
 * for just one venti file, that itself contains the expected
 * three directory entries.  Sigh.
 */
VacFile*
_vacfileroot(VacFs *fs, VtFile *r)
{
	int redirected;
	char err[ERRMAX];	
	VtBlock *b;
	VtFile *r0, *r1, *r2;
	MetaBlock mb;
	MetaEntry me;
	VacFile *root, *mr;

	redirected = 0;
Top:
	b = nil;
	root = nil;
	mr = nil;
	r1 = nil;
	r2 = nil;

	if(vtfilelock(r, -1) < 0)
		return nil;
	r0 = vtfileopen(r, 0, fs->mode);
	if(debug)
		fprint(2, "r0 %p\n", r0);
	if(r0 == nil)
		goto Err;
	r2 = vtfileopen(r, 2, fs->mode);
	if(debug)
		fprint(2, "r2 %p\n", r2);
	if(r2 == nil){
		/*
		 * some vac files (e.g., from fossil)
		 * have an extra layer of indirection.
		 */
		rerrstr(err, sizeof err);
		if(!redirected && strstr(err, "not active")){
			redirected = 1;
			vtfileunlock(r);
			r = r0;
			goto Top;
		}
		goto Err;
	}
	r1 = vtfileopen(r, 1, fs->mode);
	if(debug)
		fprint(2, "r1 %p\n", r1);
	if(r1 == nil)
		goto Err;

	mr = filealloc(fs);
	mr->msource = r2;
	r2 = nil;

	root = filealloc(fs);
	root->boff = 0;
	root->up = mr;
	root->source = r0;
	r0 = nil;
	root->msource = r1;
	r1 = nil;

	mr->down = root;
	vtfileunlock(r);

	if(vtfilelock(mr->msource, VtOREAD) < 0)
		goto Err1;
	b = vtfileblock(mr->msource, 0, VtOREAD);
	vtfileunlock(mr->msource);
	if(b == nil)
		goto Err1;

	if(mbunpack(&mb, b->data, mr->msource->dsize) < 0)
		goto Err1;

	meunpack(&me, &mb, 0);
	if(vdunpack(&root->dir, &me) < 0)
		goto Err1;
	vtblockput(b);

	return root;
Err:
	vtfileunlock(r);
Err1:
	vtblockput(b);
	if(r0)
		vtfileclose(r0);
	if(r1)
		vtfileclose(r1);
	if(r2)
		vtfileclose(r2);
	if(mr)
		filefree(mr);
	if(root)
		filefree(root);

	return nil;
}

/*
 * Vac directories are a sequence of metablocks, each of which
 * contains a bunch of metaentries sorted by file name.
 * The whole sequence isn't sorted, though, so you still have
 * to look at every block to find a given name.
 * Dirlookup looks in f for an element name elem.
 * It returns a new VacFile with the dir, boff, and mode
 * filled in, but the sources (venti files) are not, and f is 
 * not yet linked into the tree.  These details must be taken
 * care of by the caller.
 *
 * f must be locked, f->msource must not.
 */
static VacFile*
dirlookup(VacFile *f, char *elem)
{
	int i;
	MetaBlock mb;
	MetaEntry me;
	VtBlock *b;
	VtFile *meta;
	VacFile *ff;
	u32int bo, nb;

	meta = f->msource;
	b = nil;
	if(vtfilelock(meta, -1) < 0)
		return nil;
	nb = (vtfilegetsize(meta)+meta->dsize-1)/meta->dsize;
	for(bo=0; bo<nb; bo++){
		b = vtfileblock(meta, bo, VtOREAD);
		if(b == nil)
			goto Err;
		if(mbunpack(&mb, b->data, meta->dsize) < 0)
			goto Err;
		if(mbsearch(&mb, elem, &i, &me) >= 0){
			ff = filealloc(f->fs);
			if(vdunpack(&ff->dir, &me) < 0){
				filefree(ff);
				goto Err;
			}
fprint(2, "offset %s %lld\n", ff->dir.elem, ff->dir.qidoffset);
			ff->qidoffset = f->qidoffset + ff->dir.qidoffset;
			vtfileunlock(meta);
			vtblockput(b);
			ff->boff = bo;
			ff->mode = f->mode;
			return ff;
		}
		vtblockput(b);
		b = nil;
	}
	werrstr(ENoFile);
	/* fall through */
Err:
	vtfileunlock(meta);
	vtblockput(b);
	return nil;
}

/*
 * Open the venti file at offset in the directory f->source.
 * f is locked.
 */
static VtFile *
fileopensource(VacFile *f, u32int offset, u32int gen, int dir, uint mode)
{
	VtFile *r;

	if((r = vtfileopen(f->source, offset, mode)) == nil)
		return nil;
	if(r == nil)
		return nil;
	if(r->gen != gen){
		werrstr(ERemoved);
		vtfileclose(r);
		return nil;
	}
	if(r->dir != dir && r->mode != -1){
		werrstr(EBadMeta);
		vtfileclose(r);
		return nil;
	}
	return r;
}

VacFile*
vacfilegetparent(VacFile *f)
{
	if(vacfileisroot(f))
		return vacfileincref(f);
	return vacfileincref(f->up);
}

/*
 * Given an unlocked vacfile (directory) f,
 * return the vacfile named elem in f.
 * Interprets . and .. as a convenience to callers.
 */
VacFile*
vacfilewalk(VacFile *f, char *elem)
{
	VacFile *ff;

	if(elem[0] == 0){
		werrstr(EBadPath);
		return nil;
	}

	if(!vacfileisdir(f)){
		werrstr(ENotDir);
		return nil;
	}

	if(strcmp(elem, ".") == 0)
		return vacfileincref(f);

	if(strcmp(elem, "..") == 0)
		return vacfilegetparent(f);

	if(filelock(f) < 0)
		return nil;

	for(ff = f->down; ff; ff=ff->next){
		if(strcmp(elem, ff->dir.elem) == 0 && !ff->removed){
			ff->ref++;
			goto Exit;
		}
	}

	ff = dirlookup(f, elem);
	if(ff == nil)
		goto Err;

	if(ff->dir.mode & ModeSnapshot)
		ff->mode = VtOREAD;

	if(vtfilelock(f->source, f->mode) < 0)
		goto Err;
	if(ff->dir.mode & ModeDir){
		ff->source = fileopensource(f, ff->dir.entry, ff->dir.gen, 1, ff->mode);
		ff->msource = fileopensource(f, ff->dir.mentry, ff->dir.mgen, 0, ff->mode);
		if(ff->source == nil || ff->msource == nil)
			goto Err1;
	}else{
		ff->source = fileopensource(f, ff->dir.entry, ff->dir.gen, 0, ff->mode);
		if(ff->source == nil)
			goto Err1;
	}
	vtfileunlock(f->source);

	/* link in and up parent ref count */
	ff->next = f->down;
	f->down = ff;
	ff->up = f;
	vacfileincref(f);
Exit:
	fileunlock(f);
	return ff;

Err1:
	vtfileunlock(f->source);
Err:
	fileunlock(f);
	if(ff != nil)
		vacfiledecref(ff);
	return nil;
}

/* 
 * Open a path in the vac file system: 
 * just walk each element one at a time.
 */
VacFile*
vacfileopen(VacFs *fs, char *path)
{
	VacFile *f, *ff;
	char *p, elem[VtMaxStringSize], *opath;
	int n;

	f = fs->root;
	vacfileincref(f);
	opath = path;
	while(*path != 0){
		for(p = path; *p && *p != '/'; p++)
			;
		n = p - path;
		if(n > 0){
			if(n > VtMaxStringSize){
				werrstr("%s: element too long", EBadPath);
				goto Err;
			}
			memmove(elem, path, n);
			elem[n] = 0;
			ff = vacfilewalk(f, elem);
			if(ff == nil){
				werrstr("%.*s: %r", utfnlen(opath, p-opath), opath);
				goto Err;
			}
			vacfiledecref(f);
			f = ff;
		}
		if(*p == '/')
			p++;
		path = p;
	}
	return f;
Err:
	vacfiledecref(f);
	return nil;
}

/*
 * Extract the score for the bn'th block in f.
 */
int
vacfileblockscore(VacFile *f, u32int bn, u8int *score)
{
	VtFile *s;
	uvlong size;
	int dsize, ret;

	ret = -1;
	if(filerlock(f) < 0)
		return -1;
	if(vtfilelock(f->source, VtOREAD) < 0)
		goto out;

	s = f->source;
	dsize = s->dsize;
	size = vtfilegetsize(s);
	if((uvlong)bn*dsize >= size)
		goto out;
	ret = vtfileblockscore(f->source, bn, score);

out:
	vtfileunlock(f->source);
	filerunlock(f);
	return ret;
}

/*
 * Read data from f.
 */
int
vacfileread(VacFile *f, void *buf, int cnt, vlong offset)
{
	int n;

	if(offset < 0){
		werrstr(EBadOffset);
		return -1;
	}
	if(filerlock(f) < 0)
		return -1;
	if(vtfilelock(f->source, VtOREAD) < 0){
		filerunlock(f);
		return -1;
	}
	n = vtfileread(f->source, buf, cnt, offset);
	vtfileunlock(f->source);
	filerunlock(f);
	return n;
}

static int
getentry(VtFile *f, VtEntry *e)
{
	if(vtfilelock(f, VtOREAD) < 0)
		return -1;
	if(vtfilegetentry(f, e) < 0){
		vtfileunlock(f);
		return -1;
	}
	vtfileunlock(f);
	if(vtglobaltolocal(e->score) != NilBlock){
		werrstr("internal error - data not on venti");
		return -1;
	}
	return 0;
}

/*
 * Get the VtEntries for the data contained in f.
 */
int
vacfilegetentries(VacFile *f, VtEntry *e, VtEntry *me)
{
	if(filerlock(f) < 0)
		return -1;
	if(e && getentry(f->source, e) < 0){
		filerunlock(f);
		return -1;
	}
	if(me){
		if(f->msource == nil)
			memset(me, 0, sizeof *me);
		if(getentry(f->msource, me) < 0){
			filerunlock(f);
			return -1;
		}
	}
	filerunlock(f);
	return 0;
}

/*
 * Get the file's size.
 */
int
vacfilegetsize(VacFile *f, uvlong *size)
{
	if(filerlock(f) < 0)
		return -1;
	if(vtfilelock(f->source, VtOREAD) < 0){
		filerunlock(f);
		return -1;
	}
	*size = vtfilegetsize(f->source);
	vtfileunlock(f->source);
	filerunlock(f);

	return 0;
}

/*
 * Directory reading.
 *
 * A VacDirEnum is a buffer containing directory entries.
 * Directory entries contain malloced strings and need to 
 * be cleaned up with vdcleanup.  The invariant in the 
 * VacDirEnum is that the directory entries between
 * vde->i and vde->n are owned by the vde and need to
 * be cleaned up if it is closed.  Those from 0 up to vde->i
 * have been handed to the reader, and the reader must 
 * take care of calling vdcleanup as appropriate.
 */
VacDirEnum*
vdeopen(VacFile *f)
{
	VacDirEnum *vde;
	VacFile *p;

	if(!vacfileisdir(f)){
		werrstr(ENotDir);
		return nil;
	}

	/*
	 * There might be changes to this directory's children
	 * that have not been flushed out into the cache yet.
	 * Those changes are only available if we look at the 
	 * VacFile structures directory.  But the directory reader
	 * is going to read the cache blocks directly, so update them.
	 */
	if(filelock(f) < 0)
		return nil;
	for(p=f->down; p; p=p->next)
		filemetaflush(p, nil);
	fileunlock(f);

	vde = vtmallocz(sizeof(VacDirEnum));
	vde->file = vacfileincref(f);

	return vde;
}

/*
 * Figure out the size of the directory entry at offset.
 * The rest of the metadata is kept in the data half,
 * but since venti has to track the data size anyway,
 * we just use that one and avoid updating the directory
 * each time the file size changes.
 */
static int
direntrysize(VtFile *s, ulong offset, ulong gen, uvlong *size)
{
	VtBlock *b;
	ulong bn;
	VtEntry e;
	int epb;

	epb = s->dsize/VtEntrySize;
	bn = offset/epb;
	offset -= bn*epb;

	b = vtfileblock(s, bn, VtOREAD);
	if(b == nil)
		goto Err;
	if(vtentryunpack(&e, b->data, offset) < 0)
		goto Err;

	/* dangling entries are returned as zero size */
	if(!(e.flags & VtEntryActive) || e.gen != gen)
		*size = 0;
	else
		*size = e.size;
	vtblockput(b);
	return 0;

Err:
	vtblockput(b);
	return -1;
}

/*
 * Fill in vde with a new batch of directory entries.
 */
static int
vdefill(VacDirEnum *vde)
{
	int i, n;
	VtFile *meta, *source;
	MetaBlock mb;
	MetaEntry me;
	VacFile *f;
	VtBlock *b;
	VacDir *de;

	/* clean up first */
	for(i=vde->i; i<vde->n; i++)
		vdcleanup(vde->buf+i);
	vtfree(vde->buf);
	vde->buf = nil;
	vde->i = 0;
	vde->n = 0;

	f = vde->file;

	source = f->source;
	meta = f->msource;

	b = vtfileblock(meta, vde->boff, VtOREAD);
	if(b == nil)
		goto Err;
	if(mbunpack(&mb, b->data, meta->dsize) < 0)
		goto Err;

	n = mb.nindex;
	vde->buf = vtmalloc(n * sizeof(VacDir));

	for(i=0; i<n; i++){
		de = vde->buf + i;
		meunpack(&me, &mb, i);
		if(vdunpack(de, &me) < 0)
			goto Err;
		vde->n++;
		if(!(de->mode & ModeDir))
		if(direntrysize(source, de->entry, de->gen, &de->size) < 0)
			goto Err;
	}
	vde->boff++;
	vtblockput(b);
	return 0;
Err:
	vtblockput(b);
	return -1;
}

/*
 * Read a single directory entry from vde into de.
 * Returns -1 on error, 0 on EOF, and 1 on success.
 * When it returns 1, it becomes the caller's responsibility
 * to call vdcleanup(de) to free the strings contained
 * inside, or else to call vdunread to give it back.
 */
int
vderead(VacDirEnum *vde, VacDir *de)
{
	int ret;
	VacFile *f;
	u32int nb;

	f = vde->file;
	if(filerlock(f) < 0)
		return -1;

	if(vtfilelock2(f->source, f->msource, VtOREAD) < 0){
		filerunlock(f);
		return -1;
	}

	nb = (vtfilegetsize(f->msource)+f->msource->dsize-1)/f->msource->dsize;

	while(vde->i >= vde->n){
		if(vde->boff >= nb){
			ret = 0;
			goto Return;
		}
		if(vdefill(vde) < 0){
			ret = -1;
			goto Return;
		}
	}

	memmove(de, vde->buf + vde->i, sizeof(VacDir));
	vde->i++;
	ret = 1;

Return:
	vtfileunlock(f->source);
	vtfileunlock(f->msource);
	filerunlock(f);

	return ret;
}

/*
 * "Unread" the last directory entry that was read,
 * so that the next vderead will return the same one.
 * If the caller calls vdeunread(vde) it should not call
 * vdcleanup on the entry being "unread".
 */
int
vdeunread(VacDirEnum *vde)
{
	if(vde->i > 0){
		vde->i--;
		return 0;
	}
	return -1;
}

/*
 * Close the enumerator.
 */
void
vdeclose(VacDirEnum *vde)
{
	int i;
	if(vde == nil)
		return;
	/* free the strings */
	for(i=vde->i; i<vde->n; i++)
		vdcleanup(vde->buf+i);
	vtfree(vde->buf);
	vacfiledecref(vde->file);
	vtfree(vde);
}


/*
 * On to mutation.  If the vac file system has been opened
 * read-write, then the files and directories can all be edited.
 * Changes are kept in the in-memory cache until flushed out
 * to venti, so we must be careful to explicitly flush data 
 * that we're not likely to modify again.
 *
 * Each VacFile has its own copy of its VacDir directory entry
 * in f->dir, but otherwise the cache is the authoratative source
 * for data.  Thus, for the most part, it suffices if we just 
 * call vtfileflushbefore and vtfileflush when we modify things.
 * There are a few places where we have to remember to write
 * changed VacDirs back into the cache.  If f->dir *is* out of sync,
 * then f->dirty should be set.
 *
 * The metadata in a directory is, to venti, a plain data file,
 * but as mentioned above it is actually a sequence of 
 * MetaBlocks that contain sorted lists of VacDir entries.
 * The filemetaxxx routines manipulate that stream.
 */

/*
 * Find space in fp for the directory entry dir (not yet written to disk)
 * and write it to disk, returning NilBlock on failure,
 * or the block number on success.
 *
 * Start is a suggested block number to try.
 * The caller must have filemetalock'ed f and have
 * vtfilelock'ed f->up->msource.
 */
static u32int
filemetaalloc(VacFile *fp, VacDir *dir, u32int start)
{
	u32int nb, bo;
	VtBlock *b;
	MetaBlock mb;
	int nn;
	uchar *p;
	int i, n;
	MetaEntry me;
	VtFile *ms;
	
	ms = fp->msource;
	n = vdsize(dir, VacDirVersion);
	
	/* Look for a block with room for a new entry of size n. */
	nb = (vtfilegetsize(ms)+ms->dsize-1)/ms->dsize;
	if(start == NilBlock){
		if(nb > 0)
			start = nb - 1;
		else
			start = 0;
	}
	
	if(start > nb)
		start = nb;
	for(bo=start; bo<nb; bo++){
		if((b = vtfileblock(ms, bo, VtOREAD)) == nil)
			goto Err;
		if(mbunpack(&mb, b->data, ms->dsize) < 0)
			goto Err;
		nn = (mb.maxsize*FullPercentage/100) - mb.size + mb.free;
		if(n <= nn && mb.nindex < mb.maxindex){
			/* reopen for writing */
			vtblockput(b);
			if((b = vtfileblock(ms, bo, VtORDWR)) == nil)
				goto Err;
			goto Found;
		}
		vtblockput(b);
	}

	/* No block found, extend the file by one metablock. */
	vtfileflushbefore(ms, nb*(uvlong)ms->dsize);
	if((b = vtfileblock(ms, nb, VtORDWR)) == nil)
		goto Err;
	vtfilesetsize(ms, (nb+1)*ms->dsize);
	mbinit(&mb, b->data, ms->dsize, ms->dsize/BytesPerEntry);

Found:
	/* Now we have a block; allocate space to write the entry. */
	p = mballoc(&mb, n);
	if(p == nil){
		/* mballoc might have changed block */
		mbpack(&mb);
		werrstr(EBadMeta);
		goto Err;
	}

	/* Figure out where to put the index entry, and write it. */
	mbsearch(&mb, dir->elem, &i, &me);
	assert(me.p == nil);	/* not already there */
	me.p = p;
	me.size = n;
	vdpack(dir, &me, VacDirVersion);
vdunpack(dir, &me);
	mbinsert(&mb, i, &me);
	mbpack(&mb);
	vtblockput(b);
	return bo;

Err:
	vtblockput(b);
	return NilBlock;
}

/*
 * Update f's directory entry in the block cache. 
 * We look for the directory entry by name;
 * if we're trying to rename the file, oelem is the old name.
 *
 * Assumes caller has filemetalock'ed f.
 */
static int
filemetaflush(VacFile *f, char *oelem)
{
	int i, n;
	MetaBlock mb;
	MetaEntry me, me2;
	VacFile *fp;
	VtBlock *b;
	u32int bo;

	if(!f->dirty)
		return 0;

	if(oelem == nil)
		oelem = f->dir.elem;

	/*
	 * Locate f's old metadata in the parent's metadata file.
	 * We know which block it was in, but not exactly where
	 * in the block.
	 */
	fp = f->up;
	if(vtfilelock(fp->msource, -1) < 0)
		return -1;
	/* can happen if source is clri'ed out from under us */
	if(f->boff == NilBlock)
		goto Err1;
	b = vtfileblock(fp->msource, f->boff, VtORDWR);
	if(b == nil)
		goto Err1;
	if(mbunpack(&mb, b->data, fp->msource->dsize) < 0)
		goto Err;
	if(mbsearch(&mb, oelem, &i, &me) < 0)
		goto Err;

	/*
	 * Check whether we can resize the entry and keep it 
	 * in this block.
	 */
	n = vdsize(&f->dir, VacDirVersion);
	if(mbresize(&mb, &me, n) >= 0){
		/* Okay, can be done without moving to another block. */

		/* Remove old data */
		mbdelete(&mb, i, &me);

		/* Find new location if renaming */
		if(strcmp(f->dir.elem, oelem) != 0)
			mbsearch(&mb, f->dir.elem, &i, &me2);

		/* Pack new data into new location. */
		vdpack(&f->dir, &me, VacDirVersion);
vdunpack(&f->dir, &me);
		mbinsert(&mb, i, &me);
		mbpack(&mb);
		
		/* Done */
		vtblockput(b);
		vtfileunlock(fp->msource);
		f->dirty = 0;
		return 0;
	}
	
	/*
	 * The entry must be moved to another block.
	 * This can only really happen on renames that
	 * make the name very long.
	 */
	
	/* Allocate a spot in a new block. */
	if((bo = filemetaalloc(fp, &f->dir, f->boff+1)) == NilBlock){
		/* mbresize above might have modified block */
		mbpack(&mb);
		goto Err;
	}
	f->boff = bo;

	/* Now we're committed.  Delete entry in old block. */
	mbdelete(&mb, i, &me);
	mbpack(&mb);
	vtblockput(b);
	vtfileunlock(fp->msource);

	f->dirty = 0;
	return 0;

Err:
	vtblockput(b);
Err1:
	vtfileunlock(fp->msource);
	return -1;
}

/*
 * Remove the directory entry for f.
 */
static int
filemetaremove(VacFile *f)
{
	VtBlock *b;
	MetaBlock mb;
	MetaEntry me;
	int i;
	VacFile *fp;

	b = nil;
	fp = f->up;
	filemetalock(f);

	if(vtfilelock(fp->msource, VtORDWR) < 0)
		goto Err;
	b = vtfileblock(fp->msource, f->boff, VtORDWR);
	if(b == nil)
		goto Err;

	if(mbunpack(&mb, b->data, fp->msource->dsize) < 0)
		goto Err;
	if(mbsearch(&mb, f->dir.elem, &i, &me) < 0)
		goto Err;
	mbdelete(&mb, i, &me);
	mbpack(&mb);
	vtblockput(b);
	vtfileunlock(fp->msource);

	f->removed = 1;
	f->boff = NilBlock;
	f->dirty = 0;

	filemetaunlock(f);
	return 0;

Err:
	vtfileunlock(fp->msource);
	vtblockput(b);
	filemetaunlock(f);
	return -1;
}

/*
 * That was far too much effort for directory entries.
 * Now we can write code that *does* things.
 */

/*
 * Flush all data associated with f out of the cache and onto venti.
 * If recursive is set, flush f's children too.
 */
int
vacfileflush(VacFile *f, int recursive)
{
	int ret;
	VacFile **kids, *p;
	int i, nkids;
	
	if(f->mode == VtOREAD)
		return 0;

	ret = 0;
	filemetalock(f);
	if(filemetaflush(f, nil) < 0)
		ret = -1;
	filemetaunlock(f);

	/*
	 * Vacfiledecref knows how to flush source and msource too.
	 */
	if(filelock(f) < 0)
		return -1;
	vtfilelock(f->source, -1);
	if(vtfileflush(f->source) < 0)
		ret = -1;
	vtfileunlock(f->source);
	if(f->msource){
		vtfilelock(f->msource, -1);
		if(vtfileflush(f->msource) < 0)
			ret = -1;
		vtfileunlock(f->msource);
	}
	
	/*
	 * Lock order prevents us from flushing kids while holding
	 * lock, so make a list.
	 */
	nkids = 0;
	kids = nil;
	if(recursive){
		nkids = 0;
		for(p=f->down; p; p=p->next)
			nkids++;
		kids = vtmalloc(nkids*sizeof(VacFile*));
		i = 0;
		for(p=f->down; p; p=p->next){
			kids[i++] = p;
			p->ref++;
		}
	}
	fileunlock(f);
	
	for(i=0; i<nkids; i++){
		if(vacfileflush(kids[i], 1) < 0)
			ret = -1;
		vacfiledecref(kids[i]);
	}
	free(kids);
	return ret;
}
		
/*
 * Create a new file named elem in fp with the given mode.
 * The mode can be changed later except for the ModeDir bit.
 */
VacFile*
vacfilecreate(VacFile *fp, char *elem, ulong mode)
{
	VacFile *ff;
	VacDir *dir;
	VtFile *pr, *r, *mr;
	int type;
	u32int bo;

	if(filelock(fp) < 0)
		return nil;

	/*
	 * First, look to see that there's not a file in memory
	 * with the same name.
	 */
	for(ff = fp->down; ff; ff=ff->next){
		if(strcmp(elem, ff->dir.elem) == 0 && !ff->removed){
			ff = nil;
			werrstr(EExists);
			goto Err1;
		}
	}

	/*
	 * Next check the venti blocks.
	 */
	ff = dirlookup(fp, elem);
	if(ff != nil){
		werrstr(EExists);
		goto Err1;
	}

	/*
	 * By the way, you can't create in a read-only file system.
	 */
	pr = fp->source;
	if(pr->mode != VtORDWR){
		werrstr(EReadOnly);
		goto Err1;
	}

	/*
	 * Okay, time to actually create something.  Lock the two
	 * halves of the directory and create a file.
	 */
	if(vtfilelock2(fp->source, fp->msource, -1) < 0)
		goto Err1;
	ff = filealloc(fp->fs);
	ff->qidoffset = fp->qidoffset;	/* hopefully fp->qidoffset == 0 */
	type = VtDataType;
	if(mode & ModeDir)
		type = VtDirType;
	mr = nil;
	if((r = vtfilecreate(pr, pr->psize, pr->dsize, type)) == nil)
		goto Err;
	if(mode & ModeDir)
	if((mr = vtfilecreate(pr, pr->psize, pr->dsize, VtDataType)) == nil)
		goto Err;

	/*
	 * Fill in the directory entry and write it to disk.
	 */
	dir = &ff->dir;
	dir->elem = vtstrdup(elem);
	dir->entry = r->offset;
	dir->gen = r->gen;
	if(mode & ModeDir){
		dir->mentry = mr->offset;
		dir->mgen = mr->gen;
	}
	dir->size = 0;
	if(_vacfsnextqid(fp->fs, &dir->qid) < 0)
		goto Err;
	dir->uid = vtstrdup(fp->dir.uid);
	dir->gid = vtstrdup(fp->dir.gid);
	dir->mid = vtstrdup("");
	dir->mtime = time(0L);
	dir->mcount = 0;
	dir->ctime = dir->mtime;
	dir->atime = dir->mtime;
	dir->mode = mode;
	if((bo = filemetaalloc(fp, &ff->dir, NilBlock)) == NilBlock)
		goto Err;

	/*
	 * Now we're committed.
	 */
	vtfileunlock(fp->source);
	vtfileunlock(fp->msource);
	ff->source = r;
	ff->msource = mr;
	ff->boff = bo;

	/* Link into tree. */
	ff->next = fp->down;
	fp->down = ff;
	ff->up = fp;
	vacfileincref(fp);

	fileunlock(fp);
	return ff;

Err:
	vtfileunlock(fp->source);
	vtfileunlock(fp->msource);
	if(r){
		vtfilelock(r, -1);
		vtfileremove(r);
	}
	if(mr){
		vtfilelock(mr, -1);
		vtfileremove(mr);
	}
Err1:
	if(ff)
		vacfiledecref(ff);
	fileunlock(fp);
	return nil;
}

/*
 * Change the size of the file f.
 */
int
vacfilesetsize(VacFile *f, uvlong size)
{
	if(vacfileisdir(f)){
		werrstr(ENotFile);
		return -1;
	}
	
	if(filelock(f) < 0)
		return -1;

	if(f->source->mode != VtORDWR){
		werrstr(EReadOnly);
		goto Err;
	}
	if(vtfilelock(f->source, -1) < 0)
		goto Err;
	if(vtfilesetsize(f->source, size) < 0){
		vtfileunlock(f->source);
		goto Err;
	}
	vtfileunlock(f->source);
	fileunlock(f);
	return 0;

Err:
	fileunlock(f);
	return -1;
}

/*
 * Write data to f.
 */
int
vacfilewrite(VacFile *f, void *buf, int cnt, vlong offset)
{
	if(vacfileisdir(f)){
		werrstr(ENotFile);
		return -1;
	}
	if(filelock(f) < 0)
		return -1;
	if(f->source->mode != VtORDWR){
		werrstr(EReadOnly);
		goto Err;
	}
	if(offset < 0){
		werrstr(EBadOffset);
		goto Err;
	}

	if(vtfilelock(f->source, -1) < 0)
		goto Err;
	if(f->dir.mode & ModeAppend)
		offset = vtfilegetsize(f->source);
	if(vtfilewrite(f->source, buf, cnt, offset) != cnt
	|| vtfileflushbefore(f->source, offset) < 0){
		vtfileunlock(f->source);
		goto Err;
	}
	vtfileunlock(f->source);
	fileunlock(f);
	return cnt;

Err:
	fileunlock(f);
	return -1;
}

/*
 * Set (!) the VtEntry for the data contained in f.
 * This let's us efficiently copy data from one file to another.
 */
int
vacfilesetentries(VacFile *f, VtEntry *e, VtEntry *me)
{
	int ret;

	vacfileflush(f, 0);	/* flush blocks to venti, since we won't see them again */

	if(!(e->flags&VtEntryActive)){
		werrstr("missing entry for source");
		return -1;
	}
	if(me && !(me->flags&VtEntryActive))
		me = nil;
	if(f->msource && !me){
		werrstr("missing entry for msource");
		return -1;
	}
	if(me && !f->msource){
		werrstr("no msource to set");
		return -1;
	}

	if(filelock(f) < 0)
		return -1;
	if(f->source->mode != VtORDWR
	|| (f->msource && f->msource->mode != VtORDWR)){
		werrstr(EReadOnly);
		fileunlock(f);
		return -1;
	}
	if(vtfilelock2(f->source, f->msource, -1) < 0){
		fileunlock(f);
		return -1;
	}
	ret = 0;
	if(vtfilesetentry(f->source, e) < 0)
		ret = -1;
	else if(me && vtfilesetentry(f->msource, me) < 0)
		ret = -1;

	vtfileunlock(f->source);
	if(f->msource)
		vtfileunlock(f->msource);
	fileunlock(f);
	return ret;
}

/*
 * Get the directory entry for f.
 */
int
vacfilegetdir(VacFile *f, VacDir *dir)
{
	if(filerlock(f) < 0)
		return -1;

	filemetalock(f);
	vdcopy(dir, &f->dir);
	filemetaunlock(f);

	if(!vacfileisdir(f)){
		if(vtfilelock(f->source, VtOREAD) < 0){
			filerunlock(f);
			return -1;
		}
		dir->size = vtfilegetsize(f->source);
		vtfileunlock(f->source);
	}
	filerunlock(f);

	return 0;
}

/*
 * Set the directory entry for f.
 */
int
vacfilesetdir(VacFile *f, VacDir *dir)
{
	VacFile *ff;
	char *oelem;
	u32int mask;
	u64int size;

	/* can not set permissions for the root */
	if(vacfileisroot(f)){
		werrstr(ERoot);
		return -1;
	}

	if(filelock(f) < 0)
		return -1;
	filemetalock(f);
	
	if(f->source->mode != VtORDWR){
		werrstr(EReadOnly);
		goto Err;
	}

	/* On rename, check new name does not already exist */
	if(strcmp(f->dir.elem, dir->elem) != 0){
		for(ff = f->up->down; ff; ff=ff->next){
			if(strcmp(dir->elem, ff->dir.elem) == 0 && !ff->removed){
				werrstr(EExists);
				goto Err;
			}
		}
		ff = dirlookup(f->up, dir->elem);
		if(ff != nil){
			vacfiledecref(ff);
			werrstr(EExists);
			goto Err;
		}
		werrstr("");	/* "failed" dirlookup poisoned it */
	}

	/* Get ready... */
	if(vtfilelock2(f->source, f->msource, -1) < 0)
		goto Err;
	if(!vacfileisdir(f)){
		size = vtfilegetsize(f->source);
		if(size != dir->size){
			if(vtfilesetsize(f->source, dir->size) < 0){
				vtfileunlock(f->source);
				if(f->msource)
					vtfileunlock(f->msource);
				goto Err;
			}
		}
	}
	/* ... now commited to changing it. */
	vtfileunlock(f->source);
	if(f->msource)
		vtfileunlock(f->msource);

	oelem = nil;
	if(strcmp(f->dir.elem, dir->elem) != 0){
		oelem = f->dir.elem;
		f->dir.elem = vtstrdup(dir->elem);
	}

	if(strcmp(f->dir.uid, dir->uid) != 0){
		vtfree(f->dir.uid);
		f->dir.uid = vtstrdup(dir->uid);
	}

	if(strcmp(f->dir.gid, dir->gid) != 0){
		vtfree(f->dir.gid);
		f->dir.gid = vtstrdup(dir->gid);
	}

	f->dir.mtime = dir->mtime;
	f->dir.atime = dir->atime;

	mask = ~(ModeDir|ModeSnapshot);
	f->dir.mode &= ~mask;
	f->dir.mode |= mask & dir->mode;
	f->dirty = 1;

	if(filemetaflush(f, oelem) < 0){
		vtfree(oelem);
		goto Err;	/* that sucks */
	}
	vtfree(oelem);

	filemetaunlock(f);
	fileunlock(f);
	return 0;

Err:
	filemetaunlock(f);
	fileunlock(f);
	return -1;
}

/*
 * Set the qid space.
 */
int
vacfilesetqidspace(VacFile *f, u64int offset, u64int max)
{
	int ret;

	if(filelock(f) < 0)
		return -1;
	if(f->source->mode != VtORDWR){
		fileunlock(f);
		werrstr(EReadOnly);
		return -1;
	}
	filemetalock(f);
	f->dir.qidspace = 1;
	f->dir.qidoffset = offset;
	f->dir.qidmax = max;
	f->dirty = 1;
	ret = filemetaflush(f, nil);
	filemetaunlock(f);
	fileunlock(f);
	return ret;
}

/*
 * Check that the file is empty, returning 0 if it is.
 * Returns -1 on error (and not being empty is an error).
 */
static int
filecheckempty(VacFile *f)
{
	u32int i, n;
	VtBlock *b;
	MetaBlock mb;
	VtFile *r;

	r = f->msource;
	n = (vtfilegetsize(r)+r->dsize-1)/r->dsize;
	for(i=0; i<n; i++){
		b = vtfileblock(r, i, VtOREAD);
		if(b == nil)
			return -1;
		if(mbunpack(&mb, b->data, r->dsize) < 0)
			goto Err;
		if(mb.nindex > 0){
			werrstr(ENotEmpty);
			goto Err;
		}
		vtblockput(b);
	}
	return 0;

Err:
	vtblockput(b);
	return -1;
}

/*
 * Remove the vac file f.
 */
int
vacfileremove(VacFile *f)
{
	VacFile *ff;

	/* Cannot remove the root */
	if(vacfileisroot(f)){
		werrstr(ERoot);
		return -1;
	}

	if(filelock(f) < 0)
		return -1;
	if(f->source->mode != VtORDWR){
		werrstr(EReadOnly);
		goto Err1;
	}
	if(vtfilelock2(f->source, f->msource, -1) < 0)
		goto Err1;
	if(vacfileisdir(f) && filecheckempty(f)<0)
		goto Err;

	for(ff=f->down; ff; ff=ff->next)
		assert(ff->removed);

	vtfileremove(f->source);
	f->source = nil;
	if(f->msource){
		vtfileremove(f->msource);
		f->msource = nil;
	}
	fileunlock(f);

	if(filemetaremove(f) < 0)
		return -1;
	return 0;

Err:
	vtfileunlock(f->source);
	if(f->msource)
		vtfileunlock(f->msource);
Err1:
	fileunlock(f);
	return -1;
}

/*
 * Vac file system format.
 */
static char EBadVacFormat[] = "bad format for vac file";

static VacFs *
vacfsalloc(VtConn *z, int bsize, int ncache, int mode)
{
	VacFs *fs;

	fs = vtmallocz(sizeof(VacFs));
	fs->z = z;
	fs->bsize = bsize;
	fs->mode = mode;
	fs->cache = vtcachealloc(z, bsize, ncache);
	return fs;
}

static int
readscore(int fd, uchar score[VtScoreSize])
{
	char buf[45], *pref;
	int n;

	n = readn(fd, buf, sizeof(buf)-1);
	if(n < sizeof(buf)-1) {
		werrstr("short read");
		return -1;
	}
	buf[n] = 0;

	if(vtparsescore(buf, &pref, score) < 0){
		werrstr(EBadVacFormat);
		return -1;
	}
	if(pref==nil || strcmp(pref, "vac") != 0) {
		werrstr("not a vac file");
		return -1;
	}
	return 0;
}

VacFs*
vacfsopen(VtConn *z, char *file, int mode, int ncache)
{
	int fd;
	uchar score[VtScoreSize];
	char *prefix;
	
	if(vtparsescore(file, &prefix, score) >= 0){
		if(strcmp(prefix, "vac") != 0){
			werrstr("not a vac file");
			return nil;
		}
	}else{
		fd = open(file, OREAD);
		if(fd < 0)
			return nil;
		if(readscore(fd, score) < 0){
			close(fd);
			return nil;
		}
		close(fd);
	}
	return vacfsopenscore(z, score, mode, ncache);
}

VacFs*
vacfsopenscore(VtConn *z, u8int *score, int mode, int ncache)
{
	VacFs *fs;
	int n;
	VtRoot rt;
	uchar buf[VtRootSize];
	VacFile *root;
	VtFile *r;
	VtEntry e;

	n = vtread(z, score, VtRootType, buf, VtRootSize);
	if(n < 0)
		return nil;
	if(n != VtRootSize){
		werrstr("vtread on root too short");
		return nil;
	}

	if(vtrootunpack(&rt, buf) < 0)
		return nil;

	if(strcmp(rt.type, "vac") != 0) {
		werrstr("not a vac root");
		return nil;
	}

	fs = vacfsalloc(z, rt.blocksize, ncache, mode);
	memmove(fs->score, score, VtScoreSize);
	fs->mode = mode;

	memmove(e.score, rt.score, VtScoreSize);
	e.gen = 0;
	e.psize = (rt.blocksize/VtEntrySize)*VtEntrySize;
	e.dsize = rt.blocksize;
	e.type = VtDirType;
	e.flags = VtEntryActive;
	e.size = 3*VtEntrySize;

	root = nil;
	if((r = vtfileopenroot(fs->cache, &e)) == nil)
		goto Err;
	if(debug)
		fprint(2, "r %p\n", r);
	root = _vacfileroot(fs, r);
	if(debug)
		fprint(2, "root %p\n", root);
	vtfileclose(r);
	if(root == nil)
		goto Err;
	fs->root = root;
	return fs;
Err:
	if(root)
		vacfiledecref(root);
	vacfsclose(fs);
	return nil;
}

int
vacfsmode(VacFs *fs)
{
	return fs->mode;
}

VacFile*
vacfsgetroot(VacFs *fs)
{
	return vacfileincref(fs->root);
}

int
vacfsgetblocksize(VacFs *fs)
{
	return fs->bsize;
}

int
vacfsgetscore(VacFs *fs, u8int *score)
{
	memmove(score, fs->score, VtScoreSize);
	return 0;
}

int
_vacfsnextqid(VacFs *fs, uvlong *qid)
{
	++fs->qid;
	*qid = fs->qid;
	return 0;
}

void
vacfsjumpqid(VacFs *fs, uvlong step)
{
	fs->qid += step;
}

/*
 * Set *maxqid to the maximum qid expected in this file system.
 * In newer vac archives, the maximum qid is stored in the
 * qidspace VacDir annotation.  In older vac archives, the root
 * got created last, so it had the maximum qid.
 */
int
vacfsgetmaxqid(VacFs *fs, uvlong *maxqid)
{
	VacDir vd;
	
	if(vacfilegetdir(fs->root, &vd) < 0)
		return -1;
	if(vd.qidspace)
		*maxqid = vd.qidmax;
	else
		*maxqid = vd.qid;
	vdcleanup(&vd);
	return 0;
}


void
vacfsclose(VacFs *fs)
{
	if(fs->root)
		vacfiledecref(fs->root);
	fs->root = nil;
	vtcachefree(fs->cache);
	vtfree(fs);
}

/*
 * Create a fresh vac fs.
 */
VacFs *
vacfscreate(VtConn *z, int bsize, int ncache)
{
	VacFs *fs;
	VtFile *f;
	uchar buf[VtEntrySize], metascore[VtScoreSize];
	VtEntry e;
	VtBlock *b;
	MetaBlock mb;
	VacDir vd;
	MetaEntry me;
	int psize;
	
	if((fs = vacfsalloc(z, bsize, ncache, VtORDWR)) == nil)
		return nil;
	
	/*
	 * Fake up an empty vac fs.
	 */
	psize = bsize/VtEntrySize*VtEntrySize;
	f = vtfilecreateroot(fs->cache, psize, bsize, VtDirType);
	vtfilelock(f, VtORDWR);
	
	/* Write metablock containing root directory VacDir. */
	b = vtcacheallocblock(fs->cache, VtDataType);
	mbinit(&mb, b->data, bsize, bsize/BytesPerEntry);
	memset(&vd, 0, sizeof vd);
	vd.elem = "/";
	vd.mode = 0777|ModeDir;
	vd.uid = "vac";
	vd.gid = "vac";
	vd.mid = "";
	me.size = vdsize(&vd, VacDirVersion);
	me.p = mballoc(&mb, me.size);
	vdpack(&vd, &me, VacDirVersion);
	mbinsert(&mb, 0, &me);
	mbpack(&mb);
	vtblockwrite(b);
	memmove(metascore, b->score, VtScoreSize);
	vtblockput(b);
	
	/* First entry: empty venti directory stream. */
	memset(&e, 0, sizeof e);
	e.flags = VtEntryActive;
	e.psize = psize;
	e.dsize = bsize;
	e.type = VtDirType;
	memmove(e.score, vtzeroscore, VtScoreSize);
	vtentrypack(&e, buf, 0);
	vtfilewrite(f, buf, VtEntrySize, 0);
	
	/* Second entry: empty metadata stream. */
	e.type = VtDataType;
	vtentrypack(&e, buf, 0);
	vtfilewrite(f, buf, VtEntrySize, VtEntrySize);

	/* Third entry: metadata stream with root directory. */
	memmove(e.score, metascore, VtScoreSize);
	e.size = bsize;
	vtentrypack(&e, buf, 0);
	vtfilewrite(f, buf, VtEntrySize, VtEntrySize*2);

	vtfileflush(f);
	vtfileunlock(f);
	
	/* Now open it as a vac fs. */
	fs->root = _vacfileroot(fs, f);
	if(fs->root == nil){
		werrstr("vacfileroot: %r");
		vacfsclose(fs);
		return nil;
	}

	return fs;
}

int
vacfssync(VacFs *fs)
{
	uchar buf[1024];
	VtEntry e;
	VtFile *f;
	VtRoot root;

	/* Sync the entire vacfs to disk. */
	if(vacfileflush(fs->root, 1) < 0)
		return -1;
	if(vtfilelock(fs->root->up->msource, -1) < 0)
		return -1;
	if(vtfileflush(fs->root->up->msource) < 0){
		vtfileunlock(fs->root->up->msource);
		return -1;
	}
	vtfileunlock(fs->root->up->msource);

	/* Prepare the dir stream for the root block. */
	if(getentry(fs->root->source, &e) < 0)
		return -1;
	vtentrypack(&e, buf, 0);
	if(getentry(fs->root->msource, &e) < 0)
		return -1;
	vtentrypack(&e, buf, 1);
	if(getentry(fs->root->up->msource, &e) < 0)
		return -1;
	vtentrypack(&e, buf, 2);

	f = vtfilecreateroot(fs->cache, fs->bsize, fs->bsize, VtDirType);
	vtfilelock(f, VtORDWR);
	if(vtfilewrite(f, buf, 3*VtEntrySize, 0) < 0
	|| vtfileflush(f) < 0){
		vtfileunlock(f);
		vtfileclose(f);
		return -1;
	}
	vtfileunlock(f);
	if(getentry(f, &e) < 0){
		vtfileclose(f);
		return -1;
	}
	vtfileclose(f);
	
	/* Build a root block. */
	memset(&root, 0, sizeof root);
	strcpy(root.type, "vac");
	strcpy(root.name, fs->name);
	memmove(root.score, e.score, VtScoreSize);
	root.blocksize = fs->bsize;
	memmove(root.prev, fs->score, VtScoreSize);
	vtrootpack(&root, buf);
	if(vtwrite(fs->z, fs->score, VtRootType, buf, VtRootSize) < 0){
		werrstr("writing root: %r");
		return -1;
	}
	if(vtsync(fs->z) < 0)
		return -1;
	return 0;
}
