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


int debug;
char *argv0;
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*);

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

void fusereader(void*);

void
threadmain(int argc, char **argv)
{
	ARGBEGIN{
	case 'D':
		chatty9pclient++;
		debug++;
		break;
	case 'a':
		attrtimeout = atof(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]);
	initfuse(argv[1]);

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

	proccreate(fusereader, nil, STACK);
	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)
{
	int fd;

	if((fd = dial(netmkaddr(addr, "tcp", "564"), nil, nil, nil)) < 0)
		sysfatal("dial %s: %r", addr);
	if((fsys = fsmount(fd, "")) == 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;
fprint(2, "allocfusefid %d %p\n", f->id, f);
		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
		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);
}

/*
 * 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);
	if(flags & O_TRUNC){
		openmode |= OTRUNC;
		flags &= ~O_TRUNC;
	}
	/*
	 * Could translate but not standard 9P:
	 *	O_DIRECT -> ODIRECT
	 *	O_NONBLOCK -> ONONBLOCK
	 *	O_APPEND -> OAPPEND
	 */
	if(flags){
		fprint(2, "unexpected open flags %#uo", (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, perm, omode) < 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 &= ~(O_DIRECTORY|O_NONBLOCK|O_LARGEFILE);
	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;
	static int a2o[] = {
		0,
		OEXEC,
		OWRITE,
		ORDWR,
		OREAD,
		OEXEC,
		ORDWR,
		ORDWR
	};
	
	in = m->tx;
	if(in->mask >= nelem(a2o)){
		replyfuseerrno(m, EINVAL);
		return;
	}
	if((fid = _fuseopenfid(m->hdr->nodeid, 0, a2o[in->mask], &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 = fsread(fid, buf, n);
	if(n < 0){
		free(buf);
		replyfuseerrstr(m);
	}
	replyfuse(m, buf, n);
	free(buf);
}

/* 
 * 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*);
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 = nil;
		ff->d = nil;
		ff->nd = 0;
	}
	n = in->size;
	if(n > fusemaxwrite)
		n = fusemaxwrite;
	buf = emalloc(n);
	p = buf;
	ep = buf + n;
	for(;;){
		if(ff->nd == 0){
			free(ff->d0);
			ff->d0 = nil;
			ff->d = nil;
			if((ff->nd = fsdirread(ff->fid, &ff->d0)) < 0){
				replyfuseerrstr(m);
				return;
			}
			if(ff->nd == 0)
				break;
			ff->d = ff->d0;
		}
		while(ff->nd > 0 && canpack(ff->d, ff->off, &p, ep)){
			ff->off++;
			ff->d++;
			ff->nd--;
		}
	}				
	replyfuse(m, buf, p - buf);
	free(buf);
}

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 = fswrite(fid, a, in->size);
	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_READLINK, FUSE_SYMLINK, FUSE_MKNOD are unimplemented.
	 */
	{ 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)
		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;
}


