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

/*
 * 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);
	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, 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);
	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*);
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(;;){
		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);
}

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