Small tweaks
Lots of new code imported.
diff --git a/src/lib9p/req.c b/src/lib9p/req.c
new file mode 100644
index 0000000..8e1aaab
--- /dev/null
+++ b/src/lib9p/req.c
@@ -0,0 +1,112 @@
+#include <u.h>
+#include <libc.h>
+#include <auth.h>
+#include <fcall.h>
+#include <thread.h>
+#include <9p.h>
+
+static void
+increqref(void *v)
+{
+	Req *r;
+
+	r = v;
+	if(r){
+if(chatty9p > 1)
+	fprint(2, "increfreq %p %ld\n", r, r->ref.ref);
+		incref(&r->ref);
+	}
+}
+
+Reqpool*
+allocreqpool(void (*destroy)(Req*))
+{
+	Reqpool *f;
+
+	f = emalloc9p(sizeof *f);
+	f->map = allocmap(increqref);
+	f->destroy = destroy;
+	return f;
+}
+
+void
+freereqpool(Reqpool *p)
+{
+	freemap(p->map, (void(*)(void*))p->destroy);
+	free(p);
+}	
+
+Req*
+allocreq(Reqpool *pool, ulong tag)
+{
+	Req *r;
+
+	r = emalloc9p(sizeof *r);
+	r->tag = tag;
+	r->pool = pool;
+
+	increqref(r);
+	increqref(r);
+	if(caninsertkey(pool->map, tag, r) == 0){
+		closereq(r);
+		return nil;
+	}
+
+	return r;
+}
+
+Req*
+lookupreq(Reqpool *pool, ulong tag)
+{
+if(chatty9p > 1)
+	fprint(2, "lookupreq %lud\n", tag);
+	return lookupkey(pool->map, tag);
+}
+
+void
+closereq(Req *r)
+{
+	int i;
+
+	if(r == nil)
+		return;
+
+if(chatty9p > 1)
+	fprint(2, "closereq %p %ld\n", r, r->ref.ref);
+
+	if(decref(&r->ref) == 0){
+		if(r->fid)
+			closefid(r->fid);
+		if(r->newfid)
+			closefid(r->newfid);
+		if(r->afid)
+			closefid(r->afid);
+		if(r->oldreq)
+			closereq(r->oldreq);
+		for(i=0; i<r->nflush; i++)
+			respond(r->flush[i], nil);
+		free(r->flush);
+		switch(r->ifcall.type){
+		case Tstat:
+			free(r->ofcall.stat);
+			free(r->d.name);
+			free(r->d.uid);
+			free(r->d.gid);
+			free(r->d.muid);
+			break;
+		}
+		if(r->pool->destroy)
+			r->pool->destroy(r);
+		free(r->buf);
+		free(r->rbuf);
+		free(r);
+	}
+}
+
+Req*
+removereq(Reqpool *pool, ulong tag)
+{
+if(chatty9p > 1)
+	fprint(2, "removereq %lud\n", tag);
+	return deletekey(pool->map, tag);
+}