/*
 * 9P to FUSE translator.  Acts as FUSE server, 9P client.
 * Mounts 9P servers via FUSE kernel module.
 *
 * There are four procs in this threaded program
 * (ignoring the one that runs main and then exits).
 * The first proc reads FUSE requests from /dev/fuse.
 * It sends the requests over a channel to a second proc,
 * which serves the requests.  Each request runs in a
 * thread in that second proc.  Those threads do write
 * FUSE replies, which in theory might block, but in practice don't.
 * The 9P interactions are handled by lib9pclient, which
 * allocates two more procs, one for reading and one for
 * writing the 9P connection.  Thus the many threads in the
 * request proc can do 9P interactions without blocking.
 */
 
#define _GNU_SOURCE 1	/* for O_DIRECTORY on Linux */
#include "a.h"

/* GNUisms */
#ifndef O_DIRECTORY
#define O_DIRECTORY 0
#endif

#ifndef O_LARGEFILE
#  define O_LARGEFILE 0
#endif

/*
 * Work around glibc's broken <bits/fcntl.h> which defines
 * O_LARGEFILE to 0 on 64 bit architectures.  But, on those same
 * architectures, linux _forces_ O_LARGEFILE (which is always
 * 0100000 in the kernel) at each file open. FUSE is all too
 * happy to pass the flag onto us, where we'd have no idea what
 * to do with it if we trusted glibc.
 */
#if defined(__linux__)
#  undef O_LARGEFILE
#  define O_LARGEFILE 0100000
#endif

#ifndef O_CLOEXEC
#  if defined(__linux__)
#    define O_CLOEXEC 02000000  /* Sigh */
#  else
#    define O_CLOEXEC 0
#  endif
#endif

int debug;
char *argv0;
char *aname = "";
void fusedispatch(void*);
Channel *fusechan;

enum
{
	STACK = 8192
};

/*
 * The number of seconds that the kernel can cache
 * returned file attributes.  FUSE's default is 1.0.
 * I haven't experimented with using 0.
 */
double attrtimeout = 1.0;

/*
 * The number of seconds that the kernel can cache
 * the returned entry nodeids returned by lookup.
 * I haven't experimented with other values.
 */
double entrytimeout = 1.0;

CFsys *fsys;
CFid *fsysroot;
void init9p(char*, char*);

void
usage(void)
{
	fprint(2, "usage: 9pfuse [-D] [-A attrtimeout] [-a aname] address mtpt\n");
	exit(1);
}

void fusereader(void*);
void watchfd(void*);

void
threadmain(int argc, char **argv)
{
	ARGBEGIN{
	case 'D':
		chatty9pclient++;
		debug++;
		break;
	case 'A':
		attrtimeout = atof(EARGF(usage()));
		break;
	case 'a':
		aname = EARGF(usage());
		break;
	default:
		usage();
	}ARGEND

	if(argc != 2)
		usage();

	quotefmtinstall();
	fmtinstall('F', fcallfmt);
	fmtinstall('M', dirmodefmt);
	fmtinstall('G', fusefmt);

	setsid();	/* won't be able to use console, but can't be interrupted */

	init9p(argv[0], aname);
	initfuse(argv[1]);

	fusechan = chancreate(sizeof(void*), 0);
	proccreate(fusedispatch, nil, STACK);
	sendp(fusechan, nil);	/* sync */

	proccreate(fusereader, nil, STACK);
	/*
	 * Now that we're serving FUSE, we can wait
	 * for the mount to finish and exit back to the user.
	 */
	waitfuse();
	threadexits(0);
}

void
fusereader(void *v)
{
	FuseMsg *m;

	while((m = readfusemsg()) != nil)
		sendp(fusechan, m);

	fusemtpt = nil;	/* no need to unmount */
	threadexitsall(0);
}

void
init9p(char *addr, char *spec)
{
	int fd;

	if(strcmp(addr, "-") == 0)
		fd = 0;
	else
		if((fd = dial(netmkaddr(addr, "tcp", "564"), nil, nil, nil)) < 0)
			sysfatal("dial %s: %r", addr);
	proccreate(watchfd, (void*)(uintptr)fd, STACK);
	if((fsys = fsmount(fd, spec)) == nil)
		sysfatal("fsmount: %r");
	fsysroot = fsroot(fsys);
}

/*
 * FUSE uses nodeids to refer to active "struct inodes"
 * (9P's unopened fids).  FUSE uses fhs to refer to active
 * "struct fuse_files" (9P's opened fids).  The choice of 
 * numbers is up to us except that nodeid 1 is the root directory.
 * We use the same number space for both and call the 
 * bookkeeping structure a FuseFid.
 *
 * FUSE requires nodeids to have associated generation 
 * numbers.  If we reuse a nodeid, we have to bump the 
 * generation number to guarantee that the nodeid,gen
 * combination is never reused.
 * 
 * There are also inode numbers returned in directory reads
 * and file attributes, but these do NOT need to match the nodeids.
 * We use a combination of qid.path and qid.type as the inode
 * number.
 */
/*
 * TO DO: reference count the fids.
 */
typedef struct Fusefid Fusefid;
struct Fusefid
{
	Fusefid *next;
	CFid *fid;
	int ref;
	int id;
	int gen;
	int isnodeid;
	
	/* directory read state */
	Dir *d0;
	Dir *d;
	int nd;
	int off;
};

Fusefid **fusefid;
int nfusefid;
Fusefid *freefusefidlist;

Fusefid*
allocfusefid(void)
{
	Fusefid *f;
	
	if((f = freefusefidlist) == nil){
		f = emalloc(sizeof *f);
		fusefid = erealloc(fusefid, (nfusefid+1)*sizeof *fusefid);
		f->id = nfusefid;
		fusefid[f->id] = f;
		nfusefid++;
	}else
		freefusefidlist = f->next;
	f->next = nil;
	f->ref = 1;
	f->isnodeid = -1;
	return f;
}

void
freefusefid(Fusefid *f)
{
	if(--f->ref > 0)
		return;
	assert(f->ref == 0);
	if(f->fid)
		fsclose(f->fid);
	if(f->d0)
		free(f->d0);
	f->off = 0;
	f->d0 = nil;
	f->fid = nil;
	f->d = nil;
	f->nd = 0;
	f->next = freefusefidlist;
	f->isnodeid = -1;
	freefusefidlist = f;
}

uvlong
_alloc(CFid *fid, int isnodeid)
{
	Fusefid *ff;
	
	ff = allocfusefid();
	ff->fid = fid;
	ff->isnodeid = isnodeid;
	ff->gen++;
	return ff->id+2; /* skip 0 and 1 */
}

uvlong
allocfh(CFid *fid)
{
	return _alloc(fid, 0);
}

uvlong
allocnodeid(CFid *fid)
{
	return _alloc(fid, 1);
}

Fusefid*
lookupfusefid(uvlong id, int isnodeid)
{
	Fusefid *ff;
	if(id < 2 || id >= nfusefid+2)
		return nil;
	ff = fusefid[(int)id-2];
	if(ff->isnodeid != isnodeid)
		return nil;
	return ff;
}

CFid*
_lookupcfid(uvlong id, int isnodeid)
{
	Fusefid *ff;
	
	if((ff = lookupfusefid(id, isnodeid)) == nil)
		return nil;
	return ff->fid;
}

CFid*
fh2fid(uvlong fh)
{
	return _lookupcfid(fh, 0);
}

CFid*
nodeid2fid(uvlong nodeid)
{
	if(nodeid == 1)
		return fsysroot;
	return _lookupcfid(nodeid, 1);
}

uvlong
qid2inode(Qid q)
{
	return q.path | ((uvlong)q.type<<56);
}

void
dir2attr(Dir *d, struct fuse_attr *attr)
{
	attr->ino = qid2inode(d->qid);
	attr->size = d->length;
	attr->blocks = (d->length+8191)/8192;
	attr->atime = d->atime;
	attr->mtime = d->mtime;
	attr->ctime = d->mtime;	/* not right */
	attr->atimensec = 0;
	attr->mtimensec = 0;
	attr->ctimensec = 0;
	attr->mode = d->mode&0777;
	if(d->mode&DMDIR)
		attr->mode |= S_IFDIR;
	else if(d->mode&DMSYMLINK)
		attr->mode |= S_IFLNK;
	else
		attr->mode |= S_IFREG;
	attr->nlink = 1;	/* works for directories! - see FUSE FAQ */
	attr->uid = getuid();
	attr->gid = getgid();
	attr->rdev = 0;
}

void
f2timeout(double f, __u64 *s, __u32 *ns)
{
	*s = f;
	*ns = (f - (int)f)*1e9;
}

void
dir2attrout(Dir *d, struct fuse_attr_out *out)
{
	f2timeout(attrtimeout, &out->attr_valid, &out->attr_valid_nsec);
	dir2attr(d, &out->attr);
}

/*
 * Lookup.  Walk to the name given as the argument.
 * The response is a fuse_entry_out giving full stat info.
 */
void
fuselookup(FuseMsg *m)
{
	char *name;
	Fusefid *ff;
	CFid *fid, *newfid;
	Dir *d;
	struct fuse_entry_out out;
	
	name = m->tx;
	if((fid = nodeid2fid(m->hdr->nodeid)) == nil){
		replyfuseerrno(m, ESTALE);
		return;
	}
	if(strchr(name, '/')){
		replyfuseerrno(m, ENOENT);
		return;
	}
	if((newfid = fswalk(fid, name)) == nil){
		replyfuseerrstr(m);
		return;
	}
	if((d = fsdirfstat(newfid)) == nil){
		fsclose(newfid);
		replyfuseerrstr(m);
		return;
	}
	out.nodeid = allocnodeid(newfid);
	ff = lookupfusefid(out.nodeid, 1);
	out.generation = ff->gen;
	f2timeout(attrtimeout, &out.attr_valid, &out.attr_valid_nsec);
	f2timeout(entrytimeout, &out.entry_valid, &out.entry_valid_nsec);
	dir2attr(d, &out.attr);
	free(d);
	replyfuse(m, &out, sizeof out);
}

/*
 * Forget.  Reference-counted clunk for nodeids.
 * Does not send a reply.
 * Each lookup response gives the kernel an additional reference 
 * to the returned nodeid.  Forget says "drop this many references
 * to this nodeid".  Our fuselookup, when presented with the same query,
 * does not return the same results (it allocates a new nodeid for each
 * call), but if that ever changes, fuseforget already handles the ref
 * counts properly.
 */
void
fuseforget(FuseMsg *m)
{
	struct fuse_forget_in *in;
	Fusefid *ff;

	in = m->tx;
	if((ff = lookupfusefid(m->hdr->nodeid, 1)) == nil)
		return;
	if(ff->ref > in->nlookup){
		ff->ref -= in->nlookup;
		return;
	}
	if(ff->ref < in->nlookup)
		fprint(2, "bad count in forget\n");
	ff->ref = 1;
	freefusefid(ff);
	freefusemsg(m);
}

/*
 * Getattr.
 * Replies with a fuse_attr_out structure giving the
 * attr for the requested nodeid in out.attr.
 * Out.attr_valid and out.attr_valid_nsec give 
 * the amount of time that the attributes can
 * be cached.
 *
 * Empirically, though, if I run ls -ld on the root
 * twice back to back, I still get two getattrs,
 * even with a one second attribute timeout!
 */
void
fusegetattr(FuseMsg *m)
{
	CFid *fid;
	struct fuse_attr_out out;
	Dir *d;

	if((fid = nodeid2fid(m->hdr->nodeid)) == nil){
		replyfuseerrno(m, ESTALE);
		return;
	}
	if((d = fsdirfstat(fid)) == nil){
		replyfuseerrstr(m);
		return;
	}
	memset(&out, 0, sizeof out);
	dir2attrout(d, &out);
	free(d);
	replyfuse(m, &out, sizeof out);
}

/*
 * Setattr.
 * FUSE treats the many Unix attribute setting routines
 * more or less like 9P does, with a single message.
 */
void
fusesetattr(FuseMsg *m)
{
	CFid *fid, *nfid;
	Dir d, *dd;
	struct fuse_setattr_in *in;
	struct fuse_attr_out out;

	in = m->tx;
	if(in->valid&FATTR_FH){
		if((fid = fh2fid(in->fh)) == nil){
			replyfuseerrno(m, ESTALE);
			return;
		}
	}else{
		if((fid = nodeid2fid(m->hdr->nodeid)) == nil){
			replyfuseerrno(m, ESTALE);
			return;
		}
		/*
		 * Special case: Linux issues a size change to
		 * truncate a file before opening it OTRUNC.
		 * Synthetic file servers (e.g., plumber) honor 
		 * open(OTRUNC) but not wstat.
		 */
		if(in->valid == FATTR_SIZE && in->size == 0){
			if((nfid = fswalk(fid, nil)) == nil){
				replyfuseerrstr(m);
				return;
			}
			if(fsfopen(nfid, OWRITE|OTRUNC) < 0){
				replyfuseerrstr(m);
				fsclose(nfid);
				return;
			}
			fsclose(nfid);
			goto stat;
		}
	}

	nulldir(&d);
	if(in->valid&FATTR_SIZE)
		d.length = in->size;
	if(in->valid&FATTR_ATIME)
		d.atime = in->atime;
	if(in->valid&FATTR_MTIME)
		d.mtime = in->mtime;
	if(in->valid&FATTR_MODE)
		d.mode = in->mode;
	if((in->valid&FATTR_UID) || (in->valid&FATTR_GID)){
		/*
		 * I can't be bothered with these yet.
		 */
		replyfuseerrno(m, EPERM);
		return;
	}
	if(fsdirfwstat(fid, &d) < 0){
		replyfuseerrstr(m);
		return;
	}
stat:
	if((dd = fsdirfstat(fid)) == nil){
		replyfuseerrstr(m);
		return;
	}
	memset(&out, 0, sizeof out);
	dir2attrout(dd, &out);
	free(dd);
	replyfuse(m, &out, sizeof out);
}

CFid*
_fuseopenfid(uvlong nodeid, int isdir, int openmode, int *err)
{
	CFid *fid, *newfid;

	if((fid = nodeid2fid(nodeid)) == nil){
		*err = ESTALE;
		return nil;
	}
	if(isdir && !(fsqid(fid).type&QTDIR)){
		*err = ENOTDIR;
		return nil;
	}
	if(openmode != OREAD && fsqid(fid).type&QTDIR){
		*err = EISDIR;
		return nil;
	}

	/* Clone fid to get one we can open. */
	newfid = fswalk(fid, nil);
	if(newfid == nil){
		*err = errstr2errno();
		return nil;
	}
		
	if(fsfopen(newfid, openmode) < 0){
		*err = errstr2errno();
		fsclose(newfid);
		return nil;
	}

	return newfid;
}

/*
 * Open & Opendir.
 * Argument is a struct fuse_open_in.
 * The mode field is ignored (presumably permission bits)
 * and flags is the open mode.
 * Replies with a struct fuse_open_out.
 */
void
_fuseopen(FuseMsg *m, int isdir)
{
	struct fuse_open_in *in;
	struct fuse_open_out out;
	CFid *fid;
	int openmode, flags, err;

	in = m->tx;
	flags = in->flags;
	openmode = flags&3;
	flags &= ~3;
	flags &= ~(O_DIRECTORY|O_NONBLOCK|O_LARGEFILE|O_CLOEXEC);
#ifdef O_NOFOLLOW
	flags &= ~O_NOFOLLOW;
#endif
#ifdef O_LARGEFILE
	flags &= ~O_LARGEFILE;
#endif

	/*
	 * Discarding O_APPEND here is not completely wrong,
	 * because the host kernel will rewrite the offsets
	 * of write system calls for us.  That's the best we
	 * can do on Unix anyway.
	 */
	flags &= ~O_APPEND;
	if(flags & O_TRUNC){
		openmode |= OTRUNC;
		flags &= ~O_TRUNC;
	}
	/*
	 * Could translate but not standard 9P:
	 *	O_DIRECT -> ODIRECT
	 *	O_NONBLOCK -> ONONBLOCK
	 */
	if(flags){
		fprint(2, "unexpected open flags %#uo\n", (uint)in->flags);
		replyfuseerrno(m, EACCES);
		return;
	}
	if((fid = _fuseopenfid(m->hdr->nodeid, isdir, openmode, &err)) == nil){
		replyfuseerrno(m, err);
		return;
	}
	out.fh = allocfh(fid);
	out.open_flags = FOPEN_DIRECT_IO;	/* no page cache */	
	replyfuse(m, &out, sizeof out);
}

void
fuseopen(FuseMsg *m)
{
	_fuseopen(m, 0);
}

void
fuseopendir(FuseMsg *m)
{
	_fuseopen(m, 1);
}

/*
 * Create & Mkdir.
 */
CFid*
_fusecreate(uvlong nodeid, char *name, int perm, int ismkdir, int omode, struct fuse_entry_out *out, int *err)
{
	CFid *fid, *newfid, *newfid2;
	Dir *d;
	Fusefid *ff;

	if((fid = nodeid2fid(nodeid)) == nil){
		*err = ESTALE;
		return nil;
	}
	perm &= 0777;
	if(ismkdir)
		perm |= DMDIR;
	if(ismkdir && omode != OREAD){
		*err = EPERM;
		return nil;
	}
	if((newfid = fswalk(fid, nil)) == nil){
		*err = errstr2errno();
		return nil;
	}
	if(fsfcreate(newfid, name, omode, perm) < 0){
		*err = errstr2errno();
		fsclose(newfid);
		return nil;
	}
	if((d = fsdirfstat(newfid)) == nil){
		*err = errstr2errno();
		fsfremove(newfid);
		return nil;
	}
	/*
	 * This fid is no good, because it's open.
	 * We need an unopened fid.  Sigh.
	 */
	if((newfid2 = fswalk(fid, name)) == nil){
		*err = errstr2errno();
		free(d);
		fsfremove(newfid);
		return nil;
	}
	out->nodeid = allocnodeid(newfid2);
	ff = lookupfusefid(out->nodeid, 1);
	out->generation = ff->gen;
	f2timeout(attrtimeout, &out->attr_valid, &out->attr_valid_nsec);
	f2timeout(entrytimeout, &out->entry_valid, &out->entry_valid_nsec);
	dir2attr(d, &out->attr);
	free(d);
	return newfid;
}

void
fusemkdir(FuseMsg *m)
{
	struct fuse_mkdir_in *in;
	struct fuse_entry_out out;
	CFid *fid;
	int err;
	char *name;
	
	in = m->tx;
	name = (char*)(in+1);
	if((fid = _fusecreate(m->hdr->nodeid, name, in->mode, 1, OREAD, &out, &err)) == nil){
		replyfuseerrno(m, err);
		return;
	}
	/* Toss the open fid. */
	fsclose(fid);
	replyfuse(m, &out, sizeof out);
}

void
fusecreate(FuseMsg *m)
{
	struct fuse_open_in *in;
	struct fuse_create_out out;
	CFid *fid;
	int err, openmode, flags;
	char *name;
	
	in = m->tx;
	flags = in->flags;
	openmode = in->flags&3;
	flags &= ~3;
	flags &= ~(O_DIRECTORY|O_NONBLOCK|O_LARGEFILE|O_EXCL);
	flags &= ~O_APPEND;	/* see comment in _fuseopen */
	flags &= ~(O_CREAT|O_TRUNC);	/* huh? */
	if(flags){
		fprint(2, "bad mode %#uo\n", in->flags);
		replyfuseerrno(m, EACCES);
		return;
	}
	name = (char*)(in+1);
	if((fid = _fusecreate(m->hdr->nodeid, name, in->mode, 0, openmode, &out.e, &err)) == nil){
		replyfuseerrno(m, err);
		return;
	}
	out.o.fh = allocfh(fid);
	out.o.open_flags = FOPEN_DIRECT_IO;	/* no page cache */
	replyfuse(m, &out, sizeof out);
}

/*
 * Access.  
 * Lib9pclient implements this just as Plan 9 does,
 * by opening the file (or not) and then closing it.
 */
void
fuseaccess(FuseMsg *m)
{
	struct fuse_access_in *in;
	CFid *fid;
	int err, omode;
	static int a2o[] = {
		0,
		OEXEC,
		OWRITE,
		ORDWR,
		OREAD,
		OEXEC,
		ORDWR,
		ORDWR
	};
	
	in = m->tx;
	if(in->mask >= nelem(a2o)){
		replyfuseerrno(m, EINVAL);
		return;
	}
	omode = a2o[in->mask];
	if((fid = nodeid2fid(m->hdr->nodeid)) == nil){
		replyfuseerrno(m, ESTALE);
		return;
	}
	if(fsqid(fid).type&QTDIR)
		omode = OREAD;
	if((fid = _fuseopenfid(m->hdr->nodeid, 0, omode, &err)) == nil){
		replyfuseerrno(m, err);
		return;
	}
	fsclose(fid);
	replyfuse(m, nil, 0);
}

/*
 * Release.
 * Equivalent of clunk for file handles.
 * in->flags is the open mode used in Open or Opendir.
 */
void
fuserelease(FuseMsg *m)
{
	struct fuse_release_in *in;
	Fusefid *ff;
	
	in = m->tx;
	if((ff = lookupfusefid(in->fh, 0)) != nil)
		freefusefid(ff);
	else
		fprint(2, "fuserelease: fh not found\n");
	replyfuse(m, nil, 0);
}

void
fusereleasedir(FuseMsg *m)
{
	fuserelease(m);
}

/*
 * Read.
 * Read from file handle in->fh at offset in->offset for size in->size.
 * We truncate size to maxwrite just to keep the buffer reasonable.
 */
void
fuseread(FuseMsg *m)
{
	int n;
	uchar *buf;
	CFid *fid;
	struct fuse_read_in *in;

	in = m->tx;
	if((fid = fh2fid(in->fh)) == nil){
		replyfuseerrno(m, ESTALE);
		return;
	}
	n = in->size;
	if(n > fusemaxwrite)
		n = fusemaxwrite;
	buf = emalloc(n);
	n = fspread(fid, buf, n, in->offset);
	if(n < 0){
		free(buf);
		replyfuseerrstr(m);
		return;
	}
	replyfuse(m, buf, n);
	free(buf);
}

/*
 * Readlink.
 */
void
fusereadlink(FuseMsg *m)
{
	Dir *d;
	CFid *fid;

	if((fid = nodeid2fid(m->hdr->nodeid)) == nil){
		replyfuseerrno(m, ESTALE);
		return;
	}
	if((d = fsdirfstat(fid)) == nil){
		replyfuseerrstr(m);
		return;
	}
	if(!(d->mode&DMSYMLINK)){
		replyfuseerrno(m, EINVAL);
		return;
	}
	replyfuse(m, d->ext, strlen(d->ext));
	free(d);
	return;
}

/* 
 * Readdir.
 * Read from file handle in->fh at offset in->offset for size in->size.
 * We truncate size to maxwrite just to keep the buffer reasonable.
 * We assume 9P directory read semantics: a read at offset 0 rewinds
 * and a read at any other offset starts where we left off.
 * If it became necessary, we could implement a crude seek
 * or cache the entire list of directory entries.
 * Directory entries read from 9P but not yet handed to FUSE
 * are stored in m->d,nd,d0.
 */
int canpack(Dir*, uvlong, uchar**, uchar*);
Dir *dotdirs(CFid*);
void
fusereaddir(FuseMsg *m)
{
	struct fuse_read_in *in;
	uchar *buf, *p, *ep;
	int n;
	Fusefid *ff;
	
	in = m->tx;
	if((ff = lookupfusefid(in->fh, 0)) == nil){
		replyfuseerrno(m, ESTALE);
		return;
	}	
	if(in->offset == 0){
		fsseek(ff->fid, 0, 0);
		free(ff->d0);
		ff->d0 = ff->d = dotdirs(ff->fid);
		ff->nd = 2;
	}
	n = in->size;
	if(n > fusemaxwrite)
		n = fusemaxwrite;
	buf = emalloc(n);
	p = buf;
	ep = buf + n;
	for(;;){
		while(ff->nd > 0){
			if(!canpack(ff->d, ff->off, &p, ep))
				goto out;
			ff->off++;
			ff->d++;
			ff->nd--;
		}
		free(ff->d0);
		ff->d0 = nil;
		ff->d = nil;
		if((ff->nd = fsdirread(ff->fid, &ff->d0)) < 0){
			replyfuseerrstr(m);
			free(buf);
			return;
		}
		if(ff->nd == 0)
			break;
		ff->d = ff->d0;
	}
out:			
	replyfuse(m, buf, p - buf);
	free(buf);
}

/*
 * Fuse assumes that it can always read two directory entries.
 * If it gets just one, it will double it in the dirread results.
 * Thus if a directory contains just "a", you see "a" twice.
 * Adding . as the first directory entry works around this.
 * We could add .. too, but it isn't necessary.
 */
Dir*
dotdirs(CFid *f)
{
	Dir *d;
	CFid *f1;

	d = emalloc(2*sizeof *d);
	d[0].name = ".";
	d[0].qid = fsqid(f);
	d[1].name = "..";
	f1 = fswalk(f, "..");
	if(f1){
		d[1].qid = fsqid(f1);
		fsclose(f1);
	}
	return d;
}

int
canpack(Dir *d, uvlong off, uchar **pp, uchar *ep)
{
	uchar *p;
	struct fuse_dirent *de;
	int pad, size;
	
	p = *pp;
	size = FUSE_NAME_OFFSET + strlen(d->name);
	pad = 0;
	if(size%8)
		pad = 8 - size%8;
	if(size+pad > ep - p)
		return 0;
	de = (struct fuse_dirent*)p;
	de->ino = qid2inode(d->qid);
	de->off = off;
	de->namelen = strlen(d->name);
	memmove(de->name, d->name, de->namelen);
	if(pad > 0)
		memset(de->name+de->namelen, 0, pad);
	*pp = p+size+pad;
	return 1;
}

/*
 * Write.
 * Write from file handle in->fh at offset in->offset for size in->size.
 * Don't know what in->write_flags means.
 * 
 * Apparently implementations are allowed to buffer these writes
 * and wait until Flush is sent, but FUSE docs say flush may be
 * called zero, one, or even more times per close.  So better do the
 * actual writing here.  Also, errors that happen during Flush just
 * show up in the close() return status, which no one checks anyway.
 */
void
fusewrite(FuseMsg *m)
{
	struct fuse_write_in *in;
	struct fuse_write_out out;
	void *a;
	CFid *fid;
	int n;
	
	in = m->tx;
	a = in+1;
	if((fid = fh2fid(in->fh)) == nil){
		replyfuseerrno(m, ESTALE);
		return;
	}
	if(in->size > fusemaxwrite){
		replyfuseerrno(m, EINVAL);
		return;
	}
	n = fspwrite(fid, a, in->size, in->offset);
	if(n < 0){
		replyfuseerrstr(m);
		return;
	}
	out.size = n;
	replyfuse(m, &out, sizeof out);
}

/*
 * Flush.  Supposed to flush any buffered writes.  Don't use this.
 * 
 * Flush is a total crock.  It gets called on close() of a file descriptor
 * associated with this open file.  Some open files have multiple file
 * descriptors and thus multiple closes of those file descriptors.
 * In those cases, Flush is called multiple times.  Some open files
 * have file descriptors that are closed on process exit instead of
 * closed explicitly.  For those files, Flush is never called.
 * Even more amusing, Flush gets called before close() of read-only
 * file descriptors too!
 * 
 * This is just a bad idea.
 */
void
fuseflush(FuseMsg *m)
{
	replyfuse(m, nil, 0);
}

/*
 * Unlink & Rmdir.
 */
void
_fuseremove(FuseMsg *m, int isdir)
{
	char *name;
	CFid *fid, *newfid;
	
	name = m->tx;
	if((fid = nodeid2fid(m->hdr->nodeid)) == nil){
		replyfuseerrno(m, ESTALE);
		return;
	}
	if(strchr(name, '/')){
		replyfuseerrno(m, ENOENT);
		return;
	}
	if((newfid = fswalk(fid, name)) == nil){
		replyfuseerrstr(m);
		return;
	}
	if(isdir && !(fsqid(newfid).type&QTDIR)){
		replyfuseerrno(m, ENOTDIR);
		fsclose(newfid);
		return;
	}
	if(!isdir && (fsqid(newfid).type&QTDIR)){
		replyfuseerrno(m, EISDIR);
		fsclose(newfid);
		return;
	}
	if(fsfremove(newfid) < 0){
		replyfuseerrstr(m);
		return;
	}
	replyfuse(m, nil, 0);
}

void
fuseunlink(FuseMsg *m)
{
	_fuseremove(m, 0);
}

void
fusermdir(FuseMsg *m)
{
	_fuseremove(m, 1);
}

/*
 * Rename.
 *
 * FUSE sends the nodeid for the source and destination
 * directory and then the before and after names as strings.
 * 9P can only do the rename if the source and destination
 * are the same.  If the same nodeid is used for source and
 * destination, we're fine, but if FUSE gives us different nodeids
 * that happen to correspond to the same directory, we have
 * no way of figuring that out.  Let's hope it doesn't happen too often.
 */
void
fuserename(FuseMsg *m)
{
	struct fuse_rename_in *in;
	char *before, *after;
	CFid *fid, *newfid;
	Dir d;
	
	in = m->tx;
	if(in->newdir != m->hdr->nodeid){
		replyfuseerrno(m, EXDEV);
		return;
	}
	before = (char*)(in+1);
	after = before + strlen(before) + 1;
	if((fid = nodeid2fid(m->hdr->nodeid)) == nil){
		replyfuseerrno(m, ESTALE);
		return;
	}
	if(strchr(before, '/') || strchr(after, '/')){
		replyfuseerrno(m, ENOENT);
		return;
	}
	if((newfid = fswalk(fid, before)) == nil){
		replyfuseerrstr(m);
		return;
	}
	nulldir(&d);
	d.name = after;
	if(fsdirfwstat(newfid, &d) < 0){
		replyfuseerrstr(m);
		fsclose(newfid);
		return;
	}
	fsclose(newfid);
	replyfuse(m, nil, 0);
}

/*
 * Fsync.  Commit file info to stable storage.
 * Not sure what in->fsync_flags are.
 */
void
fusefsync(FuseMsg *m)
{
	struct fuse_fsync_in *in;
	CFid *fid;
	Dir d;
	
	in = m->tx;
	if((fid = fh2fid(in->fh)) == nil){
		replyfuseerrno(m, ESTALE);
		return;
	}
	nulldir(&d);
	if(fsdirfwstat(fid, &d) < 0){
		replyfuseerrstr(m);
		return;
	}
	replyfuse(m, nil, 0);
}

/*
 * Fsyncdir.  Commit dir info to stable storage?
 */
void
fusefsyncdir(FuseMsg *m)
{
	fusefsync(m);
}

/*
 * Statfs.  Send back information about file system.
 * Not really worth implementing, except that if we
 * reply with ENOSYS, programs like df print messages like
 *   df: `/tmp/z': Function not implemented
 * and that gets annoying.  Returning all zeros excludes
 * us from df without appearing to cause any problems.
 */
void
fusestatfs(FuseMsg *m)
{
	struct fuse_statfs_out out;
	
	memset(&out, 0, sizeof out);
	replyfuse(m, &out, sizeof out);
}

void (*fusehandlers[100])(FuseMsg*);

struct {
	int op;
	void (*fn)(FuseMsg*);
} fuselist[] = {
	{ FUSE_LOOKUP,		fuselookup },
	{ FUSE_FORGET,		fuseforget },
	{ FUSE_GETATTR,		fusegetattr },
	{ FUSE_SETATTR,		fusesetattr },
	/*
	 * FUSE_SYMLINK, FUSE_MKNOD are unimplemented.
	 */
	{ FUSE_READLINK,	fusereadlink },
	{ FUSE_MKDIR,		fusemkdir },
	{ FUSE_UNLINK,		fuseunlink },
	{ FUSE_RMDIR,		fusermdir },
	{ FUSE_RENAME,		fuserename },
	/*
	 * FUSE_LINK is unimplemented.
	 */
	{ FUSE_OPEN,		fuseopen },
	{ FUSE_READ,		fuseread },
	{ FUSE_WRITE,		fusewrite },
	{ FUSE_STATFS,		fusestatfs },
	{ FUSE_RELEASE,		fuserelease },
	{ FUSE_FSYNC,		fusefsync },
	/*
	 * FUSE_SETXATTR, FUSE_GETXATTR, FUSE_LISTXATTR, and
	 * FUSE_REMOVEXATTR are unimplemented. 
	 * FUSE will stop sending these requests after getting
	 * an -ENOSYS reply (see dispatch below).
	 */
	{ FUSE_FLUSH,		fuseflush },
	/*
	 * FUSE_INIT is handled in initfuse and should not be seen again.
	 */
	{ FUSE_OPENDIR,		fuseopendir },
	{ FUSE_READDIR,		fusereaddir },
	{ FUSE_RELEASEDIR,	fusereleasedir },
	{ FUSE_FSYNCDIR,	fusefsyncdir },
	{ FUSE_ACCESS,		fuseaccess },
	{ FUSE_CREATE,		fusecreate },
};

void
fusethread(void *v)
{
	FuseMsg *m;

	m = v;
	if((uint)m->hdr->opcode >= nelem(fusehandlers) 
	|| !fusehandlers[m->hdr->opcode]){
		replyfuseerrno(m, ENOSYS);
		return;
	}
	fusehandlers[m->hdr->opcode](m);
}

void
fusedispatch(void *v)
{
	int i;
	FuseMsg *m;

	eofkill9pclient = 1;	/* threadexitsall on 9P eof */
	atexit(unmountatexit);

	recvp(fusechan);	/* sync */

	for(i=0; i<nelem(fuselist); i++){
		if(fuselist[i].op >= nelem(fusehandlers))
			sysfatal("make fusehandlers bigger op=%d", fuselist[i].op);
		fusehandlers[fuselist[i].op] = fuselist[i].fn;
	}

	while((m = recvp(fusechan)) != nil) {
		switch(m->hdr->opcode) {
		case FUSE_FORGET:
		 	fusehandlers[m->hdr->opcode](m);
			break;
		default: 
			threadcreate(fusethread, m, STACK);
		}
	}
}

void*
emalloc(uint n)
{
	void *p;

	p = malloc(n);
	if(p == nil)
		sysfatal("malloc(%d): %r", n);
	memset(p, 0, n);
	return p;
}

void*
erealloc(void *p, uint n)
{
	p = realloc(p, n);
	if(p == nil)
		sysfatal("realloc(..., %d): %r", n);
	return p;
}

char*
estrdup(char *p)
{
	char *pp;
	pp = strdup(p);
	if(pp == nil)
		sysfatal("strdup(%.20s): %r", p);
	return pp;
}

void
watchfd(void *v)
{
	int fd = (int)(uintptr)v;

	/* wait for exception (file closed) */
	fd_set set;
	FD_ZERO(&set);
	FD_SET(fd, &set);
	if(select(fd+1, NULL, NULL, &set, NULL) >= 0)
		threadexitsall(nil);
	return;
}
