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

static void fsMetaFlush(void *a);
static Snap *snapInit(Fs*);
static void snapClose(Snap*);

Fs *
fsOpen(char *file, VtConn *z, long ncache, int mode)
{
	int fd, m;
	uchar oscore[VtScoreSize];
	Block *b, *bs;
	Disk *disk;
	Fs *fs;
	Super super;
	char e[ERRMAX];

	switch(mode){
	default:
		werrstr(EBadMode);
		return nil;
	case OReadOnly:
		m = OREAD;
		break;
	case OReadWrite:
		m = ORDWR;
		break;
	}
	fd = open(file, m);
	if(fd < 0){
		werrstr("open %s: %r", file);
		return nil;
	}

	bwatchInit();
	disk = diskAlloc(fd);
	if(disk == nil){
		werrstr("diskAlloc: %r");
		close(fd);
		return nil;
	}

	fs = vtmallocz(sizeof(Fs));
	fs->mode = mode;
	fs->name = vtstrdup(file);
	fs->blockSize = diskBlockSize(disk);
	fs->cache = cacheAlloc(disk, z, ncache, mode);
	if(mode == OReadWrite && z)
		fs->arch = archInit(fs->cache, disk, fs, z);
	fs->z = z;

	b = cacheLocal(fs->cache, PartSuper, 0, mode);
	if(b == nil)
		goto Err;
	if(!superUnpack(&super, b->data)){
		blockPut(b);
		werrstr("bad super block");
		goto Err;
	}
	blockPut(b);

	fs->ehi = super.epochHigh;
	fs->elo = super.epochLow;

//fprint(2, "%s: fs->ehi %d fs->elo %d active=%d\n", argv0, fs->ehi, fs->elo, super.active);

	fs->source = sourceRoot(fs, super.active, mode);
	if(fs->source == nil){
		/*
		 * Perhaps it failed because the block is copy-on-write.
		 * Do the copy and try again.
		 */
		rerrstr(e, sizeof e);
		if(mode == OReadOnly || strcmp(e, EBadRoot) != 0)
			goto Err;
		b = cacheLocalData(fs->cache, super.active, BtDir, RootTag,
			OReadWrite, 0);
		if(b == nil){
			werrstr("cacheLocalData: %r");
			goto Err;
		}
		if(b->l.epoch == fs->ehi){
			blockPut(b);
			werrstr("bad root source block");
			goto Err;
		}
		b = blockCopy(b, RootTag, fs->ehi, fs->elo);
		if(b == nil)
			goto Err;
		localToGlobal(super.active, oscore);
		super.active = b->addr;
		bs = cacheLocal(fs->cache, PartSuper, 0, OReadWrite);
		if(bs == nil){
			blockPut(b);
			werrstr("cacheLocal: %r");
			goto Err;
		}
		superPack(&super, bs->data);
		blockDependency(bs, b, 0, oscore, nil);
		blockPut(b);
		blockDirty(bs);
		blockRemoveLink(bs, globalToLocal(oscore), BtDir, RootTag, 0);
		blockPut(bs);
		fs->source = sourceRoot(fs, super.active, mode);
		if(fs->source == nil){
			werrstr("sourceRoot: %r");
			goto Err;
		}
	}

//fprint(2, "%s: got fs source\n", argv0);

	rlock(&fs->elk);
	fs->file = fileRoot(fs->source);
	fs->source->file = fs->file;		/* point back */
	runlock(&fs->elk);
	if(fs->file == nil){
		werrstr("fileRoot: %r");
		goto Err;
	}

//fprint(2, "%s: got file root\n", argv0);

	if(mode == OReadWrite){
		fs->metaFlush = periodicAlloc(fsMetaFlush, fs, 1000);
		fs->snap = snapInit(fs);
	}
	return fs;

Err:
fprint(2, "%s: fsOpen error\n", argv0);
	fsClose(fs);
	return nil;
}

void
fsClose(Fs *fs)
{
	rlock(&fs->elk);
	periodicKill(fs->metaFlush);
	snapClose(fs->snap);
	if(fs->file){
		fileMetaFlush(fs->file, 0);
		if(!fileDecRef(fs->file))
			sysfatal("fsClose: files still in use: %r");
	}
	fs->file = nil;
	sourceClose(fs->source);
	cacheFree(fs->cache);
	if(fs->arch)
		archFree(fs->arch);
	vtfree(fs->name);
	runlock(&fs->elk);
	memset(fs, ~0, sizeof(Fs));
	vtfree(fs);
}

int
fsRedial(Fs *fs, char *host)
{
	if(vtredial(fs->z, host) < 0)
		return 0;
	if(vtconnect(fs->z) < 0)
		return 0;
	return 1;
}

File *
fsGetRoot(Fs *fs)
{
	return fileIncRef(fs->file);
}

int
fsGetBlockSize(Fs *fs)
{
	return fs->blockSize;
}

Block*
superGet(Cache *c, Super* super)
{
	Block *b;

	if((b = cacheLocal(c, PartSuper, 0, OReadWrite)) == nil){
		fprint(2, "%s: superGet: cacheLocal failed: %r\n", argv0);
		return nil;
	}
	if(!superUnpack(super, b->data)){
		fprint(2, "%s: superGet: superUnpack failed: %r\n", argv0);
		blockPut(b);
		return nil;
	}

	return b;
}

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

/*
 * Prepare the directory to store a snapshot.
 * Temporary snapshots go into /snapshot/yyyy/mmdd/hhmm[.#]
 * Archival snapshots go into /archive/yyyy/mmdd[.#].
 *
 * TODO This should be rewritten to eliminate most of the duplication.
 */
static File*
fileOpenSnapshot(Fs *fs, char *dstpath, int doarchive)
{
	int n;
	char buf[30], *s, *p, *elem;
	File *dir, *f;
	Tm now;

	if(dstpath){
		if((p = strrchr(dstpath, '/')) != nil){
			*p++ = '\0';
			elem = p;
			p = dstpath;
			if(*p == '\0')
				p = "/";
		}else{
			p = "/";
			elem = dstpath;
		}
		if((dir = fileOpen(fs, p)) == nil)
			return nil;
		f = fileCreate(dir, elem, ModeDir|ModeSnapshot|0555, "adm");
		fileDecRef(dir);
		return f;
	}else if(doarchive){
		/*
		 * a snapshot intended to be archived to venti.
		 */
		dir = fileOpen(fs, "/archive");
		if(dir == nil)
			return nil;
		now = *localtime(time(0));

		/* yyyy */
		snprint(buf, sizeof(buf), "%d", now.year+1900);
		f = fileWalk(dir, buf);
		if(f == nil)
			f = fileCreate(dir, buf, ModeDir|0555, "adm");
		fileDecRef(dir);
		if(f == nil)
			return nil;
		dir = f;

		/* mmdd[#] */
		snprint(buf, sizeof(buf), "%02d%02d", now.mon+1, now.mday);
		s = buf+strlen(buf);
		for(n=0;; n++){
			if(n)
				seprint(s, buf+sizeof(buf), ".%d", n);
			f = fileWalk(dir, buf);
			if(f != nil){
				fileDecRef(f);
				continue;
			}
			f = fileCreate(dir, buf, ModeDir|ModeSnapshot|0555, "adm");
			break;
		}
		fileDecRef(dir);
		return f;
	}else{
		/*
		 * Just a temporary snapshot
		 * We'll use /snapshot/yyyy/mmdd/hhmm.
		 * There may well be a better naming scheme.
		 * (I'd have used hh:mm but ':' is reserved in Microsoft file systems.)
		 */
		dir = fileOpen(fs, "/snapshot");
		if(dir == nil)
			return nil;

		now = *localtime(time(0));

		/* yyyy */
		snprint(buf, sizeof(buf), "%d", now.year+1900);
		f = fileWalk(dir, buf);
		if(f == nil)
			f = fileCreate(dir, buf, ModeDir|0555, "adm");
		fileDecRef(dir);
		if(f == nil)
			return nil;
		dir = f;

		/* mmdd */
		snprint(buf, sizeof(buf), "%02d%02d", now.mon+1, now.mday);
		f = fileWalk(dir, buf);
		if(f == nil)
			f = fileCreate(dir, buf, ModeDir|0555, "adm");
		fileDecRef(dir);
		if(f == nil)
			return nil;
		dir = f;

		/* hhmm[.#] */
		snprint(buf, sizeof buf, "%02d%02d", now.hour, now.min);
		s = buf+strlen(buf);
		for(n=0;; n++){
			if(n)
				seprint(s, buf+sizeof(buf), ".%d", n);
			f = fileWalk(dir, buf);
			if(f != nil){
				fileDecRef(f);
				continue;
			}
			f = fileCreate(dir, buf, ModeDir|ModeSnapshot|0555, "adm");
			break;
		}
		fileDecRef(dir);
		return f;
	}
}

static int
fsNeedArch(Fs *fs, uint archMinute)
{
	int need;
	File *f;
	char buf[100];
	Tm now;
	ulong then;

	then = time(0);
	now = *localtime(then);

	/* back up to yesterday if necessary */
	if(now.hour < archMinute/60
	|| now.hour == archMinute/60 && now.min < archMinute%60)
		now = *localtime(then-86400);

	snprint(buf, sizeof buf, "/archive/%d/%02d%02d",
		now.year+1900, now.mon+1, now.mday);
	need = 1;
	rlock(&fs->elk);
	f = fileOpen(fs, buf);
	if(f){
		need = 0;
		fileDecRef(f);
	}
	runlock(&fs->elk);
	return need;
}

int
fsEpochLow(Fs *fs, u32int low)
{
	Block *bs;
	Super super;

	wlock(&fs->elk);
	if(low > fs->ehi){
		werrstr("bad low epoch (must be <= %ud)", fs->ehi);
		wunlock(&fs->elk);
		return 0;
	}

	if((bs = superGet(fs->cache, &super)) == nil){
		wunlock(&fs->elk);
		return 0;
	}

	super.epochLow = low;
	fs->elo = low;
	superWrite(bs, &super, 1);
	blockPut(bs);
	wunlock(&fs->elk);

	return 1;
}

static int
bumpEpoch(Fs *fs, int doarchive)
{
	uchar oscore[VtScoreSize];
	u32int oldaddr;
	Block *b, *bs;
	Entry e;
	Source *r;
	Super super;

	/*
	 * Duplicate the root block.
	 *
	 * As a hint to flchk, the garbage collector,
	 * and any (human) debuggers, store a pointer
	 * to the old root block in entry 1 of the new root block.
	 */
	r = fs->source;
	b = cacheGlobal(fs->cache, r->score, BtDir, RootTag, OReadOnly);
	if(b == nil)
		return 0;

	memset(&e, 0, sizeof e);
	e.flags = VtEntryActive | VtEntryLocal | _VtEntryDir;
	memmove(e.score, b->score, VtScoreSize);
	e.tag = RootTag;
	e.snap = b->l.epoch;

	b = blockCopy(b, RootTag, fs->ehi+1, fs->elo);
	if(b == nil){
		fprint(2, "%s: bumpEpoch: blockCopy: %r\n", argv0);
		return 0;
	}

	if(0) fprint(2, "%s: snapshot root from %d to %d\n", argv0, oldaddr, b->addr);
	entryPack(&e, b->data, 1);
	blockDirty(b);

	/*
	 * Update the superblock with the new root and epoch.
	 */
	if((bs = superGet(fs->cache, &super)) == nil)
		return 0;

	fs->ehi++;
	memmove(r->score, b->score, VtScoreSize);
	r->epoch = fs->ehi;

	super.epochHigh = fs->ehi;
	oldaddr = super.active;
	super.active = b->addr;
	if(doarchive)
		super.next = oldaddr;

	/*
	 * Record that the new super.active can't get written out until
	 * the new b gets written out.  Until then, use the old value.
	 */
	localToGlobal(oldaddr, oscore);
	blockDependency(bs, b, 0, oscore, nil);
	blockPut(b);

	/*
	 * We force the super block to disk so that super.epochHigh gets updated.
	 * Otherwise, if we crash and come back, we might incorrectly treat as active
	 * some of the blocks that making up the snapshot we just created.
	 * Basically every block in the active file system and all the blocks in
	 * the recently-created snapshot depend on the super block now.
	 * Rather than record all those dependencies, we just force the block to disk.
	 *
	 * Note that blockWrite might actually (will probably) send a slightly outdated
	 * super.active to disk.  It will be the address of the most recent root that has
	 * gone to disk.
	 */
	superWrite(bs, &super, 1);
	blockRemoveLink(bs, globalToLocal(oscore), BtDir, RootTag, 0);
	blockPut(bs);

	return 1;
}

int
saveQid(Fs *fs)
{
	Block *b;
	Super super;
	u64int qidMax;

	if((b = superGet(fs->cache, &super)) == nil)
		return 0;
	qidMax = super.qid;
	blockPut(b);

	if(!fileSetQidSpace(fs->file, 0, qidMax))
		return 0;

	return 1;
}

int
fsSnapshot(Fs *fs, char *srcpath, char *dstpath, int doarchive)
{
	File *src, *dst;

	assert(fs->mode == OReadWrite);

	dst = nil;

	if(fs->halted){
		werrstr("file system is halted");
		return 0;
	}

	/*
	 * Freeze file system activity.
	 */
	wlock(&fs->elk);

	/*
	 * Get the root of the directory we're going to save.
	 */
	if(srcpath == nil)
		srcpath = "/active";
	src = fileOpen(fs, srcpath);
	if(src == nil)
		goto Err;

	/*
	 * It is important that we maintain the invariant that:
	 *	if both b and bb are marked as Active with start epoch e
	 *	and b points at bb, then no other pointers to bb exist.
	 * 
	 * When bb is unlinked from b, its close epoch is set to b's epoch.
	 * A block with epoch == close epoch is
	 * treated as free by cacheAllocBlock; this aggressively
	 * reclaims blocks after they have been stored to Venti.
	 *
	 * Let's say src->source is block sb, and src->msource is block
	 * mb.  Let's also say that block b holds the Entry structures for
	 * both src->source and src->msource (their Entry structures might
	 * be in different blocks, but the argument is the same).
	 * That is, right now we have:
	 *
	 *	b	Active w/ epoch e, holds ptrs to sb and mb.
	 *	sb	Active w/ epoch e.
	 *	mb	Active w/ epoch e.
	 *
	 * With things as they are now, the invariant requires that
	 * b holds the only pointers to sb and mb.  We want to record
	 * pointers to sb and mb in new Entries corresponding to dst,
	 * which breaks the invariant.  Thus we need to do something
	 * about b.  Specifically, we bump the file system's epoch and
	 * then rewalk the path from the root down to and including b.
	 * This will copy-on-write as we walk, so now the state will be:
	 *
	 *	b	Snap w/ epoch e, holds ptrs to sb and mb.
	 *	new-b	Active w/ epoch e+1, holds ptrs to sb and mb.
	 *	sb	Active w/ epoch e.
	 *	mb	Active w/ epoch e.
	 *
	 * In this state, it's perfectly okay to make more pointers to sb and mb.
	 */
	if(!bumpEpoch(fs, 0) || !fileWalkSources(src))
		goto Err;

	/*
	 * Sync to disk.  I'm not sure this is necessary, but better safe than sorry.
	 */
	cacheFlush(fs->cache, 1);

	/*
	 * Create the directory where we will store the copy of src.
	 */
	dst = fileOpenSnapshot(fs, dstpath, doarchive);
	if(dst == nil)
		goto Err;

	/*
	 * Actually make the copy by setting dst's source and msource
	 * to be src's.
	 */
	if(!fileSnapshot(dst, src, fs->ehi-1, doarchive))
		goto Err;

	fileDecRef(src);
	fileDecRef(dst);
	src = nil;
	dst = nil;

	/*
	 * Make another copy of the file system.  This one is for the
	 * archiver, so that the file system we archive has the recently
	 * added snapshot both in /active and in /archive/yyyy/mmdd[.#].
	 */
	if(doarchive){
		if(!saveQid(fs))
			goto Err;
		if(!bumpEpoch(fs, 1))
			goto Err;
	}

	wunlock(&fs->elk);

	/* BUG? can fs->arch fall out from under us here? */
	if(doarchive && fs->arch)
		archKick(fs->arch);

	return 1;

Err:
	fprint(2, "%s: fsSnapshot: %r\n", argv0);
	if(src)
		fileDecRef(src);
	if(dst)
		fileDecRef(dst);
	wunlock(&fs->elk);
	return 0;
}

int
fsVac(Fs *fs, char *name, uchar score[VtScoreSize])
{
	int r;
	DirEntry de;
	Entry e, ee;
	File *f;

	rlock(&fs->elk);
	f = fileOpen(fs, name);
	if(f == nil){
		runlock(&fs->elk);
		return 0;
	}

	if(!fileGetSources(f, &e, &ee) || !fileGetDir(f, &de)){
		fileDecRef(f);
		runlock(&fs->elk);
		return 0;
	}
	fileDecRef(f);

	r = mkVac(fs->z, fs->blockSize, &e, &ee, &de, score);
	runlock(&fs->elk);
	return r;
}

static int
vtWriteBlock(VtConn *z, uchar *buf, uint n, uint type, uchar score[VtScoreSize])
{
	if(vtwrite(z, score, type, buf, n) < 0)
		return 0;
	if(vtsha1check(score, buf, n) < 0)
		return 0;
	return 1;
}

int
mkVac(VtConn *z, uint blockSize, Entry *pe, Entry *pee, DirEntry *pde, uchar score[VtScoreSize])
{
	uchar buf[8192];
	int i;
	uchar *p;
	uint n;
	DirEntry de;
	Entry e, ee, eee;
	MetaBlock mb;
	MetaEntry me;
	VtRoot root;

	e = *pe;
	ee = *pee;
	de = *pde;

	if(globalToLocal(e.score) != NilBlock
	|| (ee.flags&VtEntryActive && globalToLocal(ee.score) != NilBlock)){
		werrstr("can only vac paths already stored on venti");
		return 0;
	}

	/*
	 * Build metadata source for root.
	 */
	n = deSize(&de);
	if(n+MetaHeaderSize+MetaIndexSize > sizeof buf){
		werrstr("DirEntry too big");
		return 0;
	}
	memset(buf, 0, sizeof buf);
	mbInit(&mb, buf, n+MetaHeaderSize+MetaIndexSize, 1);
	p = mbAlloc(&mb, n);
	if(p == nil)
		abort();
	mbSearch(&mb, de.elem, &i, &me);
	assert(me.p == nil);
	me.p = p;
	me.size = n;
	dePack(&de, &me);
	mbInsert(&mb, i, &me);
	mbPack(&mb);

	eee.size = n+MetaHeaderSize+MetaIndexSize;
	if(!vtWriteBlock(z, buf, eee.size, VtDataType, eee.score))
		return 0;
	eee.psize = 8192;
	eee.dsize = 8192;
	eee.depth = 0;
	eee.flags = VtEntryActive;

	/*
	 * Build root source with three entries in it.
	 */
	entryPack(&e, buf, 0);
	entryPack(&ee, buf, 1);
	entryPack(&eee, buf, 2);

	n = VtEntrySize*3;
	memset(&root, 0, sizeof root);
	if(!vtWriteBlock(z, buf, n, VtDirType, root.score))
		return 0;

	/*
	 * Save root.
	 */
	strecpy(root.type, root.type+sizeof root.type, "vac");
	strecpy(root.name, root.name+sizeof root.name, de.elem);
	root.blocksize = blockSize;
	vtrootpack(&root, buf);
	if(!vtWriteBlock(z, buf, VtRootSize, VtRootType, score))
		return 0;

	return 1;
}

int
fsSync(Fs *fs)
{
	wlock(&fs->elk);
	fileMetaFlush(fs->file, 1);
	cacheFlush(fs->cache, 1);
	wunlock(&fs->elk);
	return 1;
}

int
fsHalt(Fs *fs)
{
	wlock(&fs->elk);
	fs->halted = 1;
	fileMetaFlush(fs->file, 1);
	cacheFlush(fs->cache, 1);
	return 1;
}

int
fsUnhalt(Fs *fs)
{
	if(!fs->halted)
		return 0;
	fs->halted = 0;
	wunlock(&fs->elk);
	return 1;
}

int
fsNextQid(Fs *fs, u64int *qid)
{
	Block *b;
	Super super;

	if((b = superGet(fs->cache, &super)) == nil)
		return 0;

	*qid = super.qid++;

	/*
	 * It's okay if the super block doesn't go to disk immediately,
	 * since fileMetaAlloc will record a dependency between the
	 * block holding this qid and the super block.  See file.c:/^fileMetaAlloc.
	 */
	superWrite(b, &super, 0);
	blockPut(b);
	return 1;
}

static void
fsMetaFlush(void *a)
{
	int rv;
	Fs *fs = a;

	rlock(&fs->elk);
	rv = fileMetaFlush(fs->file, 1);
	runlock(&fs->elk);
	if(rv > 0)
		cacheFlush(fs->cache, 0);
}

static int
fsEsearch1(File *f, char *path, u32int savetime, u32int *plo)
{
	int n, r;
	DirEntry de;
	DirEntryEnum *dee;
	File *ff;
	Entry e, ee;
	char *t;

	dee = deeOpen(f);
	if(dee == nil)
		return 0;

	n = 0;
	for(;;){
		r = deeRead(dee, &de);
		if(r <= 0)
			break;
		if(de.mode & ModeSnapshot){
			if((ff = fileWalk(f, de.elem)) != nil){
				if(fileGetSources(ff, &e, &ee))
					if(de.mtime >= savetime && e.snap != 0)
						if(e.snap < *plo)
							*plo = e.snap;
				fileDecRef(ff);
			}
		}
		else if(de.mode & ModeDir){
			if((ff = fileWalk(f, de.elem)) != nil){
				t = smprint("%s/%s", path, de.elem);
				n += fsEsearch1(ff, t, savetime, plo);
				vtfree(t);
				fileDecRef(ff);
			}
		}
		deCleanup(&de);
		if(r < 0)
			break;
	}
	deeClose(dee);

	return n;
}

static int
fsEsearch(Fs *fs, char *path, u32int savetime, u32int *plo)
{
	int n;
	File *f;
	DirEntry de;

	f = fileOpen(fs, path);
	if(f == nil)
		return 0;
	if(!fileGetDir(f, &de)){
		fileDecRef(f);
		return 0;
	}
	if((de.mode & ModeDir) == 0){
		fileDecRef(f);
		deCleanup(&de);
		return 0;
	}
	deCleanup(&de);
	n = fsEsearch1(f, path, savetime, plo);
	fileDecRef(f);
	return n;
}

void
fsSnapshotCleanup(Fs *fs, u32int age)
{
	u32int lo;

	/*
	 * Find the best low epoch we can use,
	 * given that we need to save all the unventied archives
	 * and all the snapshots younger than age.
	 */
	rlock(&fs->elk);
	lo = fs->ehi;
	fsEsearch(fs, "/archive", 0, &lo);
	fsEsearch(fs, "/snapshot", time(0)-age*60, &lo);
	runlock(&fs->elk);

	fsEpochLow(fs, lo);
	fsSnapshotRemove(fs);
}

/* remove all snapshots that have expired */
/* return number of directory entries remaining */
static int
fsRsearch1(File *f, char *s)
{
	int n, r;
	DirEntry de;
	DirEntryEnum *dee;
	File *ff;
	char *t, e[ERRMAX];

	dee = deeOpen(f);
	if(dee == nil)
		return 0;

	n = 0;
	for(;;){
		r = deeRead(dee, &de);
		if(r <= 0)
			break;
		n++;
		if(de.mode & ModeSnapshot){
			rerrstr(e, sizeof e);
			if((ff = fileWalk(f, de.elem)) != nil)
				fileDecRef(ff);
			else if(strcmp(e, ESnapOld) == 0){
				if(fileClri(f, de.elem, "adm"))
					n--;
			}
		}
		else if(de.mode & ModeDir){
			if((ff = fileWalk(f, de.elem)) != nil){
				t = smprint("%s/%s", s, de.elem);
				if(fsRsearch1(ff, t) == 0)
					if(fileRemove(ff, "adm"))
						n--;
				vtfree(t);
				fileDecRef(ff);
			}
		}
		deCleanup(&de);
		if(r < 0)
			break;
	}
	deeClose(dee);

	return n;
}

static int
fsRsearch(Fs *fs, char *path)
{
	File *f;
	DirEntry de;

	f = fileOpen(fs, path);
	if(f == nil)
		return 0;
	if(!fileGetDir(f, &de)){
		fileDecRef(f);
		return 0;
	}
	if((de.mode & ModeDir) == 0){
		fileDecRef(f);
		deCleanup(&de);
		return 0;
	}
	deCleanup(&de);
	fsRsearch1(f, path);
	fileDecRef(f);
	return 1;
}

void
fsSnapshotRemove(Fs *fs)
{
	rlock(&fs->elk);
	fsRsearch(fs, "/snapshot");
	runlock(&fs->elk);
}

struct Snap
{
	Fs	*fs;
	Periodic*tick;
	QLock	lk;
	uint	snapMinutes;
	uint	archMinute;
	uint	snapLife;
	u32int	lastSnap;
	u32int	lastArch;
	u32int	lastCleanup;
	uint	ignore;
};

static void
snapEvent(void *v)
{
	Snap *s;
	u32int now, min;
	Tm tm;
	int need;
	u32int snaplife;

	s = v;

	now = time(0)/60;
	qlock(&s->lk);

	/*
	 * Snapshots happen every snapMinutes minutes.
	 * If we miss a snapshot (for example, because we
	 * were down), we wait for the next one.
	 */
	if(s->snapMinutes != ~0 && s->snapMinutes != 0
	&& now%s->snapMinutes==0 && now != s->lastSnap){
		if(!fsSnapshot(s->fs, nil, nil, 0))
			fprint(2, "%s: fsSnapshot snap: %r\n", argv0);
		s->lastSnap = now;
	}

	/*
	 * Archival snapshots happen at archMinute.
	 * If we miss an archive (for example, because we
	 * were down), we do it as soon as possible.
	 */
	tm = *localtime(now*60);
	min = tm.hour*60+tm.min;
	if(s->archMinute != ~0){
		need = 0;
		if(min == s->archMinute && now != s->lastArch)
			need = 1;
		if(s->lastArch == 0){
			s->lastArch = 1;
			if(fsNeedArch(s->fs, s->archMinute))
				need = 1;
		}
		if(need){
			fsSnapshot(s->fs, nil, nil, 1);
			s->lastArch = now;
		}
	}

	/*
	 * Snapshot cleanup happens every snaplife or every day.
	 */
	snaplife = s->snapLife;
	if(snaplife == ~0)
		snaplife = 24*60;
	if(s->lastCleanup+snaplife < now){
		fsSnapshotCleanup(s->fs, s->snapLife);
		s->lastCleanup = now;
	}
	qunlock(&s->lk);
}

static Snap*
snapInit(Fs *fs)
{
	Snap *s;

	s = vtmallocz(sizeof(Snap));
	s->fs = fs;
	s->tick = periodicAlloc(snapEvent, s, 10*1000);
	s->snapMinutes = -1;
	s->archMinute = -1;
	s->snapLife = -1;
	s->ignore = 5*2;	/* wait five minutes for clock to stabilize */
	return s;
}

void
snapGetTimes(Snap *s, u32int *arch, u32int *snap, u32int *snaplen)
{
	if(s == nil){
		*snap = -1;
		*arch = -1;
		*snaplen = -1;
		return;
	}

	qlock(&s->lk);
	*snap = s->snapMinutes;
	*arch = s->archMinute;
	*snaplen = s->snapLife;
	qunlock(&s->lk);
}

void
snapSetTimes(Snap *s, u32int arch, u32int snap, u32int snaplen)
{
	if(s == nil)
		return;

	qlock(&s->lk);
	s->snapMinutes = snap;
	s->archMinute = arch;
	s->snapLife = snaplen;
	qunlock(&s->lk);
}

static void
snapClose(Snap *s)
{
	if(s == nil)
		return;

	periodicKill(s->tick);
	vtfree(s);
}

