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

/*
 * locking order is upwards.  A thread can hold the lock for a VacFile
 * and then acquire the lock of its parent
 */
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;
};

static int		filelock(VacFile*);
static u32int	filemetaalloc(VacFile*, VacDir*, u32int);
static int		filemetaflush2(VacFile*, char*);
static void		filemetalock(VacFile*);
static void		filemetaunlock(VacFile*);
static void		fileraccess(VacFile*);
static int		filerlock(VacFile*);
static void		filerunlock(VacFile*);
static void		fileunlock(VacFile*);
static void		filewaccess(VacFile*, char*);

void mbinit(MetaBlock*, u8int*, uint, uint);
int mbsearch(MetaBlock*, char*, int*, MetaEntry*);
int mbresize(MetaBlock*, MetaEntry*, int);
VacFile *vdlookup(VacFile*, char*);

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

/*
 * the file is locked already
 * f->msource is unlocked
 */
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;
			}
			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;
}

VacFile*
_vacfileroot(VacFs *fs, VtFile *r)
{
	VtBlock *b;
	VtFile *r0, *r1, *r2;
	MetaBlock mb;
	MetaEntry me;
	VacFile *root, *mr;

	b = nil;
	root = nil;
	mr = nil;
	r1 = nil;
	r2 = nil;

	if(vtfilelock(r, -1) < 0)
		return nil;
	r0 = vtfileopen(r, 0, fs->mode);
	if(r0 == nil)
		goto Err;
	r1 = vtfileopen(r, 1, fs->mode);
	if(r1 == nil)
		goto Err;
	r2 = vtfileopen(r, 2, fs->mode);
	if(r2 == 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;

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

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

	meunpack(&me, &mb, 0);
	if(vdunpack(&root->dir, &me) < 0)
		goto Err;
	vtblockput(b);
	vtfileunlock(r);
	fileraccess(root);

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

	return nil;
}

static VtFile *
fileopensource(VacFile *f, u32int offset, u32int gen, int dir, uint mode)
{
	VtFile *r;

	if(vtfilelock(f->source, mode) < 0)
		return nil;
	r = vtfileopen(f->source, offset, mode);
	vtfileunlock(f->source);
	if(r == nil)
		return nil;
	if(r->gen != gen){
		werrstr(ERemoved);
		goto Err;
	}
	if(r->dir != dir && r->mode != -1){
fprint(2, "fileopensource: dir mismatch %d %d\n", r->dir, dir);
		werrstr(EBadMeta);
		goto Err;
	}
	return r;
Err:
	vtfileclose(r);
	return nil;
}

VacFile*
_filewalk(VacFile *f, char *elem, int partial)
{
	VacFile *ff;

	fileraccess(f);

	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){
		if(vacfileisroot(f))
			return vacfileincref(f);
		return vacfileincref(f->up);
	}

	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(partial){
		/*
		 * Do nothing.  We're opening this file only so we can clri it.
		 * Usually the sources can't be opened, hence we won't even bother.
		 * Be VERY careful with the returned file.  If you hand it to a routine
		 * expecting ff->source and/or ff->msource to be non-nil, we're
		 * likely to dereference nil.  FileClri should be the only routine
		 * setting partial.
		 */
		ff->partial = 1;
	}else 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 Err;
	}else{
		ff->source = fileopensource(f, ff->dir.entry, ff->dir.gen, 0, ff->mode);
		if(ff->source == nil)
			goto Err;
	}

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

VacFile*
vacfilewalk(VacFile *f, char *elem)
{
	return _filewalk(f, elem, 0);
}

VacFile*
_fileopen(VacFs *fs, char *path, int partial)
{
	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 = _filewalk(f, elem, partial && *p=='\0');
			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;
}

VacFile*
vacfileopen(VacFs *fs, char *path)
{
	return _fileopen(fs, path, 0);
}

#if 0
static void
filesettmp(VacFile *f, int istmp)
{
	int i;
	VtEntry e;
	VtFile *r;

	for(i=0; i<2; i++){
		if(i==0)
			r = f->source;
		else
			r = f->msource;
		if(r == nil)
			continue;
		if(vtfilegetentry(r, &e) < 0){
			fprint(2, "vtfilegetentry failed (cannot happen): %r\n");
			continue;
		}
		if(istmp)
			e.flags |= VtEntryNoArchive;
		else
			e.flags &= ~VtEntryNoArchive;
		if(vtfilesetentry(r, &e) < 0){
			fprint(2, "vtfilesetentry failed (cannot happen): %r\n");
			continue;
		}
	}
}
#endif

VacFile*
vacfilecreate(VacFile *f, char *elem, ulong mode, char *uid)
{
	VacFile *ff;
	VacDir *dir;
	VtFile *pr, *r, *mr;
	int isdir;

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

	r = nil;
	mr = nil;
	for(ff = f->down; ff; ff=ff->next){
		if(strcmp(elem, ff->dir.elem) == 0 && !ff->removed){
			ff = nil;
			werrstr(EExists);
			goto Err1;
		}
	}

	ff = dirlookup(f, elem);
	if(ff != nil){
		werrstr(EExists);
		goto Err1;
	}

	pr = f->source;
	if(pr->mode != VtORDWR){
		werrstr(EReadOnly);
		goto Err1;
	}

	if(vtfilelock2(f->source, f->msource, -1) < 0)
		goto Err1;

	ff = filealloc(f->fs);
	isdir = mode & ModeDir;

	r = vtfilecreate(pr, pr->dsize, isdir, 0);
	if(r == nil)
		goto Err;
	if(isdir){
		mr = vtfilecreate(pr, pr->dsize, 0, r->offset);
		if(mr == nil)
			goto Err;
	}

	dir = &ff->dir;
	dir->elem = vtstrdup(elem);
	dir->entry = r->offset;
	dir->gen = r->gen;
	if(isdir){
		dir->mentry = mr->offset;
		dir->mgen = mr->gen;
	}
	dir->size = 0;
	if(_vacfsnextqid(f->fs, &dir->qid) < 0)
		goto Err;
	dir->uid = vtstrdup(uid);
	dir->gid = vtstrdup(f->dir.gid);
	dir->mid = vtstrdup(uid);
	dir->mtime = time(0L);
	dir->mcount = 0;
	dir->ctime = dir->mtime;
	dir->atime = dir->mtime;
	dir->mode = mode;

	ff->boff = filemetaalloc(f, dir, 0);
	if(ff->boff == NilBlock)
		goto Err;

	vtfileunlock(f->source);
	vtfileunlock(f->msource);

	ff->source = r;
	ff->msource = mr;

#if 0
	if(mode&ModeTemporary){
		if(vtfilelock2(r, mr, -1) < 0)
			goto Err1;
		filesettmp(ff, 1);
		vtfileunlock(r);
		if(mr)
			vtfileunlock(mr);
	}
#endif

	/* committed */

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

	filewaccess(f, uid);

	fileunlock(f);
	return ff;

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

int
vacfileblockscore(VacFile *f, u32int bn, u8int *score)
{
	VtFile *s;
	uvlong size;
	int dsize, ret;

	ret = -1;
	if(filerlock(f) < 0)
		return -1;
	fileraccess(f);
	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;
}

int
vacfileread(VacFile *f, void *buf, int cnt, vlong offset)
{
	VtFile *s;
	uvlong size;
	u32int bn;
	int off, dsize, n, nn;
	VtBlock *b;
	uchar *p;

if(0)fprint(2, "fileRead: %s %d, %lld\n", f->dir.elem, cnt, offset);

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

	if(offset < 0){
		werrstr(EBadOffset);
		goto Err1;
	}

	fileraccess(f);

	if(vtfilelock(f->source, VtOREAD) < 0)
		goto Err1;

	s = f->source;
	dsize = s->dsize;
	size = vtfilegetsize(s);

	if(offset >= size)
		offset = size;

	if(cnt > size-offset)
		cnt = size-offset;
	bn = offset/dsize;
	off = offset%dsize;
	p = buf;
	while(cnt > 0){
		b = vtfileblock(s, bn, OREAD);
		if(b == nil)
			goto Err;
		n = cnt;
		if(n > dsize-off)
			n = dsize-off;
		nn = dsize-off;
		if(nn > n)
			nn = n;
		memmove(p, b->data+off, nn);
		memset(p+nn, 0, nn-n);
		off = 0;
		bn++;
		cnt -= n;
		p += n;
		vtblockput(b);
	}
	vtfileunlock(s);
	filerunlock(f);
	return p-(uchar*)buf;

Err:
	vtfileunlock(s);
Err1:
	filerunlock(f);
	return -1;
}

#if 0
/* 
 * Changes the file block bn to be the given block score.
 * Very sneaky.  Only used by flfmt.
 */
int
filemapblock(VacFile *f, ulong bn, uchar score[VtScoreSize], ulong tag)
{
	VtBlock *b;
	VtEntry e;
	VtFile *s;

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

	s = nil;
	if(f->dir.mode & ModeDir){
		werrstr(ENotFile);
		goto Err;
	}

	if(f->source->mode != VtORDWR){
		werrstr(EReadOnly);
		goto Err;
	}

	if(vtfilelock(f->source, -1) < 0)
		goto Err;

	s = f->source;
	b = _vtfileblock(s, bn, VtORDWR, 1, tag);
	if(b == nil)
		goto Err;

	if(vtfilegetentry(s, &e) < 0)
		goto Err;
	if(b->l.type == BtDir){
		memmove(e.score, score, VtScoreSize);
		assert(e.tag == tag || e.tag == 0);
		e.tag = tag;
		e.flags |= VtEntryLocal;
		vtentrypack(&e, b->data, f->source->offset % f->source->epb);
	}else
		memmove(b->data + (bn%(e.psize/VtScoreSize))*VtScoreSize, score, VtScoreSize);
	vtblockdirty(b);
	vtblockput(b);
	vtfileunlock(s);
	fileunlock(f);
	return 0;

Err:
	if(s)
		vtfileunlock(s);
	fileunlock(f);
	return -1;
}
#endif

int
vacfilesetsize(VacFile *f, uvlong size)
{
	int r;

	if(filelock(f) < 0)
		return -1;
	r = 0;
	if(f->dir.mode & ModeDir){
		werrstr(ENotFile);
		goto Err;
	}
	if(f->source->mode != VtORDWR){
		werrstr(EReadOnly);
		goto Err;
	}
	if(vtfilelock(f->source, -1) < 0)
		goto Err;
	r = vtfilesetsize(f->source, size);
	vtfileunlock(f->source);
Err:
	fileunlock(f);
	return r;
}

int
filewrite(VacFile *f, void *buf, int cnt, vlong offset, char *uid)
{
	VtFile *s;
	ulong bn;
	int off, dsize, n;
	VtBlock *b;
	uchar *p;
	vlong eof;

if(0)fprint(2, "fileWrite: %s %d, %lld\n", f->dir.elem, cnt, offset);

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

	s = nil;
	if(f->dir.mode & ModeDir){
		werrstr(ENotFile);
		goto Err;
	}

	if(f->source->mode != VtORDWR){
		werrstr(EReadOnly);
		goto Err;
	}
	if(offset < 0){
		werrstr(EBadOffset);
		goto Err;
	}

	filewaccess(f, uid);

	if(vtfilelock(f->source, -1) < 0)
		goto Err;
	s = f->source;
	dsize = s->dsize;

	eof = vtfilegetsize(s);
	if(f->dir.mode & ModeAppend)
		offset = eof;
	bn = offset/dsize;
	off = offset%dsize;
	p = buf;
	while(cnt > 0){
		n = cnt;
		if(n > dsize-off)
			n = dsize-off;
		b = vtfileblock(s, bn, n<dsize?VtORDWR:VtOWRITE);
		if(b == nil){
			if(offset > eof)
				vtfilesetsize(s, offset);
			goto Err;
		}
		memmove(b->data+off, p, n);
		off = 0;
		cnt -= n;
		p += n;
		offset += n;
		bn++;
		vtblockdirty(b);
		vtblockput(b);
	}
	if(offset > eof && vtfilesetsize(s, offset) < 0)
		goto Err;
	vtfileunlock(s);
	fileunlock(f);
	return p-(uchar*)buf;
Err:
	if(s)
		vtfileunlock(s);
	fileunlock(f);
	return -1;
}

int
vacfilegetdir(VacFile *f, VacDir *dir)
{
	if(filerlock(f) < 0)
		return -1;

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

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

	return 0;
}

int
vacfiletruncate(VacFile *f, char *uid)
{
	if(vacfileisdir(f)){
		werrstr(ENotFile);
		return -1;
	}

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

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

	filewaccess(f, uid);

	return 0;
}

int
vacfilesetdir(VacFile *f, VacDir *dir, char *uid)
{
	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;

	if(f->source->mode != VtORDWR){
		werrstr(EReadOnly);
		fileunlock(f);
		return -1;
	}

	filemetalock(f);

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

	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;
			}
			/* commited to changing it now */
		}
	}
	/* commited to changing it now */
#if 0
	if((f->dir.mode&ModeTemporary) != (dir->mode&ModeTemporary))
		filesettmp(f, dir->mode&ModeTemporary);
#endif
	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;

//fprint(2, "mode %x %x ", f->dir.mode, dir->mode);
	mask = ~(ModeDir|ModeSnapshot);
	f->dir.mode &= ~mask;
	f->dir.mode |= mask & dir->mode;
	f->dirty = 1;
//fprint(2, "->%x\n", f->dir.mode);

	filemetaflush2(f, oelem);
	vtfree(oelem);

	filemetaunlock(f);
	fileunlock(f);

	filewaccess(f->up, uid);

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

int
vacfilesetqidspace(VacFile *f, u64int offset, u64int max)
{
	int ret;

	if(filelock(f) < 0)
		return -1;
	filemetalock(f);
	f->dir.qidspace = 1;
	f->dir.qidoffset = offset;
	f->dir.qidmax = max;
	ret = filemetaflush2(f, nil);
	filemetaunlock(f);
	fileunlock(f);
	return ret;
}

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

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

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

	return 0;
}

int
vacfilegetvtentry(VacFile *f, VtEntry *e)
{
	if(filerlock(f) < 0)
		return 0;
	if(vtfilelock(f->source, VtOREAD) < 0){
		filerunlock(f);
		return -1;
	}
	vtfilegetentry(f->source, e);
	vtfileunlock(f->source);
	filerunlock(f);

	return 0;
}

void
vacfilemetaflush(VacFile *f, int rec)
{
	VacFile **kids, *p;
	int nkids;
	int i;

	filemetalock(f);
	filemetaflush2(f, nil);
	filemetaunlock(f);

	if(!rec || !vacfileisdir(f))
		return;

	if(filelock(f) < 0)
		return;
	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++){
		vacfilemetaflush(kids[i], 1);
		vacfiledecref(kids[i]);
	}
	vtfree(kids);
}

/* assumes metaLock is held */
static int
filemetaflush2(VacFile *f, char *oelem)
{
	VacFile *fp;
	VtBlock *b, *bb;
	MetaBlock mb;
	MetaEntry me, me2;
	int i, n;
	u32int boff;

	if(!f->dirty)
		return 0;

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

	fp = f->up;

	if(vtfilelock(fp->msource, -1) < 0)
		return 0;
	/* 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;

	n = vdsize(&f->dir);
if(0)fprint(2, "old size %d new size %d\n", me.size, n);

	if(mbresize(&mb, &me, n) >= 0){
		/* fits in the block */
		mbdelete(&mb, i, &me);
		if(strcmp(f->dir.elem, oelem) != 0)
			mbsearch(&mb, f->dir.elem, &i, &me2);
		vdpack(&f->dir, &me);
		mbinsert(&mb, i, &me);
		mbpack(&mb);
		vtblockdirty(b);
		vtblockput(b);
		vtfileunlock(fp->msource);
		f->dirty = 0;
		return -1;
	}

	/*
	 * moving entry to another block
	 * it is feasible for the fs to crash leaving two copies
	 * of the directory entry.  This is just too much work to
	 * fix.  Given that entries are only allocated in a block that
	 * is less than PercentageFull, most modifications of meta data
	 * will fit within the block.  i.e. this code should almost
	 * never be executed.
	 */
	boff = filemetaalloc(fp, &f->dir, f->boff+1);
	if(boff == NilBlock){
		/* mbResize might have modified block */
		mbpack(&mb);
		vtblockdirty(b);
		goto Err;
	}
fprint(2, "fileMetaFlush moving entry from %ud -> %ud\n", f->boff, boff);
	f->boff = boff;

	/* make sure deletion goes to disk after new entry */
	bb = vtfileblock(fp->msource, f->boff, VtORDWR);
	mbdelete(&mb, i, &me);
	mbpack(&mb);
//	blockDependency(b, bb, -1, nil, nil);
	vtblockput(bb);
	vtblockdirty(b);
	vtblockput(b);
	vtfileunlock(fp->msource);

	f->dirty = 0;

	return 0;

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

static int
filemetaremove(VacFile *f, char *uid)
{
	VtBlock *b;
	MetaBlock mb;
	MetaEntry me;
	int i;
	VacFile *up;

	b = nil;
	up = f->up;
	filewaccess(up, uid);
	filemetalock(f);

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

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

	vtblockdirty(b);
	vtblockput(b);

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

	filemetaunlock(f);
	return 0;

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

/* assume file is locked, assume f->msource is locked */
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, VtORDWR);
		if(b == nil)
			goto Err;
		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;
}

int
vacfileremove(VacFile *f, char *muid)
{
	VacFile *ff;

	/* can not 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, muid) < 0)
		return -1;

	return 0;

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

static int
clri(VacFile *f, char *uid)
{
	int r;

	if(f == nil)
		return -1;
	if(f->up->source->mode != VtORDWR){
		werrstr(EReadOnly);
		vacfiledecref(f);
		return -1;
	}
	r = filemetaremove(f, uid);
	vacfiledecref(f);
	return r;
}

int
vacfileclripath(VacFs *fs, char *path, char *uid)
{
	return clri(_fileopen(fs, path, 1), uid);
}

int
vacfileclri(VacFile *dir, char *elem, char *uid)
{
	return clri(_filewalk(dir, elem, 1), uid);
}

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

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

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

VacDirEnum*
vdeopen(VacFile *f)
{
	VacDirEnum *vde;
	VacFile *p;

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

	/* flush out meta data */
	if(filelock(f) < 0)
		return nil;
	for(p=f->down; p; p=p->next)
		filemetaflush2(p, nil);
	fileunlock(f);

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

	return vde;
}

static int
direntrysize(VtFile *s, ulong elem, ulong gen, uvlong *size)
{
	VtBlock *b;
	ulong bn;
	VtEntry e;
	int epb;

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

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

	/* hanging 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;
}

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

int
vderead(VacDirEnum *vde, VacDir *de)
{
	int ret, didread;
	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;

	didread = 0;
	while(vde->i >= vde->n){
		if(vde->boff >= nb){
			ret = 0;
			goto Return;
		}
		didread = 1;
		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);

	if(didread)
		fileraccess(f);
	return ret;
}

void
vdeclose(VacDirEnum *vde)
{
	int i;
	if(vde == nil)
		return;
	for(i=vde->i; i<vde->n; i++)
		vdcleanup(vde->buf+i);
	vtfree(vde->buf);
	vacfiledecref(vde->file);
	vtfree(vde);
}

/*
 * caller must lock f->source and f->msource
 * caller must NOT lock the source and msource
 * referenced by dir.
 */
static u32int
filemetaalloc(VacFile *f, VacDir *dir, u32int start)
{
	u32int nb, bo;
	VtBlock *b, *bb;
	MetaBlock mb;
	int nn;
	uchar *p;
	int i, n, epb;
	MetaEntry me;
	VtFile *s, *ms;

	s = f->source;
	ms = f->msource;

	n = vdsize(dir);
	nb = (vtfilegetsize(ms)+ms->dsize-1)/ms->dsize;
	b = nil;
	if(start > nb)
		start = nb;
	for(bo=start; bo<nb; bo++){
		b = vtfileblock(ms, bo, VtORDWR);
		if(b == 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)
			break;
		vtblockput(b);
		b = nil;
	}

	/* add block to meta file */
	if(b == nil){
		b = vtfileblock(ms, bo, VtORDWR);
		if(b == nil)
			goto Err;
		vtfilesetsize(ms, (nb+1)*ms->dsize);
		mbinit(&mb, b->data, ms->dsize, ms->dsize/BytesPerEntry);
	}

	p = mballoc(&mb, n);
	if(p == nil){
		/* mbAlloc might have changed block */
		mbpack(&mb);
		vtblockdirty(b);
		werrstr(EBadMeta);
		goto Err;
	}

	mbsearch(&mb, dir->elem, &i, &me);
	assert(me.p == nil);
	me.p = p;
	me.size = n;
	vdpack(dir, &me);
	mbinsert(&mb, i, &me);
	mbpack(&mb);

#ifdef notdef /* XXX */
	/* meta block depends on super block for qid ... */
	bb = cacheLocal(b->c, PartSuper, 0, VtOREAD);
	blockDependency(b, bb, -1, nil, nil);
	vtblockput(bb);

	/* ... and one or two dir entries */
	epb = s->dsize/VtEntrySize;
	bb = vtfileblock(s, dir->entry/epb, VtOREAD);
	blockDependency(b, bb, -1, nil, nil);
	vtblockput(bb);
	if(dir->mode & ModeDir){
		bb = sourceBlock(s, dir->mentry/epb, VtOREAD);
		blockDependency(b, bb, -1, nil, nil);
		vtblockput(bb);
	}
#endif

	vtblockdirty(b);
	vtblockput(b);
	return bo;
Err:
	vtblockput(b);
	return NilBlock;
}

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
filerlock(VacFile *f)
{
//	assert(!canwlock(&f->fs->elk));
	rlock(&f->lk);
	if(chksource(f) < 0){
		runlock(&f->lk);
		return -1;
	}
	return 0;
}

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

static int
filelock(VacFile *f)
{
//	assert(!canwlock(&f->fs->elk));
	wlock(&f->lk);
	if(chksource(f) < 0){
		wunlock(&f->lk);
		return -1;
	}
	return 0;
}

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

/*
 * f->source and f->msource must NOT be locked.
 * fileMetaFlush locks the fileMeta and then the source (in fileMetaFlush2).
 * We have to respect that ordering.
 */
static void
filemetalock(VacFile *f)
{
	assert(f->up != nil);
//	assert(!canwlock(&f->fs->elk));
	wlock(&f->up->lk);
}

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

/*
 * f->source and f->msource must NOT be locked.
 * see filemetalock.
 */
static void
fileraccess(VacFile* f)
{
	if(f->mode == VtOREAD)
		return;

	filemetalock(f);
	f->dir.atime = time(0L);
	f->dirty = 1;
	filemetaunlock(f);
}

/*
 * f->source and f->msource must NOT be locked.
 * see filemetalock.
 */
static void
filewaccess(VacFile* f, char *mid)
{
	if(f->mode == VtOREAD)
		return;

	filemetalock(f);
	f->dir.atime = f->dir.mtime = time(0L);
	if(strcmp(f->dir.mid, mid) != 0){
		vtfree(f->dir.mid);
		f->dir.mid = vtstrdup(mid);
	}
	f->dir.mcount++;
	f->dirty = 1;
	filemetaunlock(f);

/*RSC: let's try this */
/*presotto - lets not
	if(f->up)
		filewaccess(f->up, mid);
*/
}

#if 0
static void
markCopied(Block *b)
{
	VtBlock *lb;
	Label l;

	if(globalToLocal(b->score) == NilBlock)
		return;

	if(!(b->l.state & BsCopied)){
		/*
		 * We need to record that there are now pointers in
		 * b that are not unique to b.  We do this by marking
		 * b as copied.  Since we don't return the label block,
		 * the caller can't get the dependencies right.  So we have
		 * to flush the block ourselves.  This is a rare occurrence.
		 */
		l = b->l;
		l.state |= BsCopied;
		lb = _blockSetLabel(b, &l);
	WriteAgain:
		while(!blockWrite(lb)){
			fprint(2, "getEntry: could not write label block\n");
			sleep(10*1000);
		}
		while(lb->iostate != BioClean && lb->iostate != BioDirty){
			assert(lb->iostate == BioWriting);
			vtSleep(lb->ioready);
		}
		if(lb->iostate == BioDirty)
			goto WriteAgain;
		vtblockput(lb);
	}
}

static int
getEntry(VtFile *r, Entry *e, int mark)
{
	Block *b;

	if(r == nil){
		memset(&e, 0, sizeof e);
		return 1;
	}

	b = cacheGlobal(r->fs->cache, r->score, BtDir, r->tag, VtOREAD);
	if(b == nil)
		return 0;
	if(!entryUnpack(e, b->data, r->offset % r->epb)){
		vtblockput(b);
		return 0;
	}

	if(mark)
		markCopied(b);
	vtblockput(b);
	return 1;
}

static int
setEntry(Source *r, Entry *e)
{
	Block *b;
	Entry oe;

	b = cacheGlobal(r->fs->cache, r->score, BtDir, r->tag, VtORDWR);
	if(0) fprint(2, "setEntry: b %#ux %d score=%V\n", b->addr, r->offset % r->epb, e->score);
	if(b == nil)
		return 0;
	if(!entryUnpack(&oe, b->data, r->offset % r->epb)){
		vtblockput(b);
		return 0;
	}
	e->gen = oe.gen;
	entryPack(e, b->data, r->offset % r->epb);

	/* BUG b should depend on the entry pointer */

	markCopied(b);
	vtblockdirty(b);
	vtblockput(b);
	return 1;
}

/* assumes hold elk */
int
fileSnapshot(VacFile *dst, VacFile *src, u32int epoch, int doarchive)
{
	Entry e, ee;

	/* add link to snapshot */
	if(!getEntry(src->source, &e, 1) || !getEntry(src->msource, &ee, 1))
		return 0;

	e.snap = epoch;
	e.archive = doarchive;
	ee.snap = epoch;
	ee.archive = doarchive;

	if(!setEntry(dst->source, &e) || !setEntry(dst->msource, &ee))
		return 0;
	return 1;
}

int
fileGetSources(VacFile *f, Entry *e, Entry *ee, int mark)
{
	if(!getEntry(f->source, e, mark)
	|| !getEntry(f->msource, ee, mark))
		return 0;
	return 1;
}	

int
fileWalkSources(VacFile *f)
{
	if(f->mode == VtOREAD)
		return 1;
	if(!sourceLock2(f->source, f->msource, VtORDWR))
		return 0;
	vtfileunlock(f->source);
	vtfileunlock(f->msource);
	return 1;
}

#endif
