#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;
			}
			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);
		else 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;
			mbunpack(&mb, b->data, ms->dsize);
			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);
	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.
 * Vacfiledecref knows how to flush source and msource 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);

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

	/*
	 * Lock order prevents us from flushing kids while holding
	 * lock, so make a list and then flush without the lock.
	 */
	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++;
		}
	}
	if(nkids > 0){
		fileunlock(f);
		for(i=0; i<nkids; i++){
			if(vacfileflush(kids[i], 1) < 0)
				ret = -1;
			vacfiledecref(kids[i]);
		}
		filelock(f);
	}
	free(kids);

	/*
	 * Now we can flush our own data.
	 */	
	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);
	}
	fileunlock(f);

	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);
	
	filelock(ff);
	vtfilelock(ff->source, -1);
	vtfileunlock(ff->source);
	fileunlock(ff);

	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;
}
