#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 out1;
	ret = vtfileblockscore(f->source, bn, score);

out1:
	vtfileunlock(f->source);
out:
	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;
}

int
vacfiledsize(VacFile *f)
{
	VtEntry e;

	if(vacfilegetentries(f,&e,nil) < 0)
		return -1;
	return e.dsize;
}

/*
 * Does block b of f have the same SHA1 hash as the n bytes at buf?
 */
int
sha1matches(VacFile *f, ulong b, uchar *buf, int n)
{
	uchar fscore[VtScoreSize];
	uchar bufscore[VtScoreSize];
	
	if(vacfileblockscore(f, b, fscore) < 0)
		return 0;
	n = vtzerotruncate(VtDataType, buf, n);
	sha1(buf, n, bufscore, nil);
	if(memcmp(bufscore, fscore, VtScoreSize) == 0)
		return 1;
	return 0;
}

