Anonymous avatar Anonymous committed 2b6bf0e

Can resolve names

Comments (0)

Files changed (12)

 	o9fs_vfsops\
 	o9fs_vnops
 COMBINED=o9fs.o
-load:
+l: $(COMBINED)
 	modload -o o9fs $(COMBINED)
 
+u:
+	modunload -n o9fs
+
 .include <bsd.lkm.mk>
 
-#ifdef DEBUG
-#define DPRINT printf
-#else
-#define DPRINT 
-#endif
+#define DBG(x...) do{\
+	if(Debug){\
+		printf("%s: ", __FUNCTION__);\
+		printf(x);\
+	}\
+}while(0)
+
+#define DIN() DBG(">>>\n")
+#define DRET() DBG("<<<\n")
+
 #define nelem(a) (sizeof(a) / sizeof(*a))
 
 struct o9fsqid {
+	uint8_t		type;
+	uint32_t	vers;
 	uint64_t	path;
-	uint32_t	vers;
-	uint8_t		type;
 };
 
 struct o9fsstat {
 	struct	o9fsfid *next;
 };
 
+struct o9fid {
+	int		fid;
+	int		mode;
+	struct	o9fsqid	qid;
+	int64_t	offset;
+	TAILQ_ENTRY(o9fid) next;
+};
 
 #define VTO9(vp) ((struct o9fsfid *)(vp)->v_data)
+#define VTO92(vp) ((struct o9fid *)(vp)->v_data)
 #define VFSTOO9FS(mp) ((struct o9fs *)((mp)->mnt_data))
 
+
 #define	O9FS_VERSION9P	"9P2000"
 #define	O9FS_MAXWELEM	16
 
 	u_char	*inbuf;
 	u_char	*outbuf;
 
+	TAILQ_HEAD(, o9fid)	activeq;
+	TAILQ_HEAD(, o9fid) freeq;
 	int	nextfid;
-	struct	o9fsfid *rootfid;
+
 	struct	o9fsfid *freefid;
 };
 
 #define O9FS_GBIT64(p)	((uint32_t)((p)[0]|((p)[1]<<8)|((p)[2]<<16)|((p)[3]<<24)) |\
 						((uint64_t)((p)[4]|((p)[5]<<8)|((p)[6]<<16)|((p)[7]<<24)) << 32))
  
-#define O9FS_PBIT8(p,v)		((qaddr_t)(p))[0]=(v)
-#define O9FS_PBIT16(p,v)	((qaddr_t)(p))[0]=(v);((qaddr_t)(p))[1]=(v)>>8   
-#define O9FS_PBIT32(p,v)	((qaddr_t)(p))[0]=(v);((qaddr_t)(p))[1]=(v)>>8;((qaddr_t)(p))[2]=(v)>>16;((qaddr_t)(p))[3]=(v)>>24
-#define O9FS_PBIT64(p,v)	((qaddr_t)(p))[0]=(v);((qaddr_t)(p))[1]=(v)>>8;((qaddr_t)(p))[2]=(v)>>16;((qaddr_t)(p))[3]=(v)>>24;\
-							((qaddr_t)(p))[4]=(v)>>32;((qaddr_t)(p))[5]=(v)>>40;((qaddr_t)(p))[6]=(v)>>48;((qaddr_t)(p))[7]=(v)>>56
+#define O9FS_PBIT8(p,v)		(p)[0]=(v)
+#define O9FS_PBIT16(p,v)	(p)[0]=(v);(p)[1]=(v)>>8   
+#define O9FS_PBIT32(p,v)	(p)[0]=(v);(p)[1]=(v)>>8;(p)[2]=(v)>>16;(p)[3]=(v)>>24
+#define O9FS_PBIT64(p,v)	(p)[0]=(v);(p)[1]=(v)>>8;(p)[2]=(v)>>16;(p)[3]=(v)>>24;\
+							(p)[4]=(v)>>32;(p)[5]=(v)>>40;(p)[6]=(v)>>48;(p)[7]=(v)>>56
 
 #define O9FS_BIT8SZ		1
 #define O9FS_BIT16SZ	2
 #include <sys/malloc.h>
 #include <sys/vnode.h>
 #include <sys/namei.h>
+#include <sys/queue.h>
 
 #include "o9fs.h"
 #include "o9fs_extern.h"
 
+enum{
+	Debug = 1,
+};
+
 void
 o9fs_fidclunk(struct o9fs *fs, struct o9fsfid *f)
 {
 	struct o9fsfcall tx, rx;
 
-	DPRINT("fidclunk: enter\n");
+	DBG("fidclunk: enter\n");
 	tx.type = O9FS_TCLUNK;
 	tx.fid = f->fid;
 	o9fs_rpc(fs, &tx, &rx);
 	f->opened = 0;
 	f->mode = -1;
 	o9fs_putfid(fs, f);
-	DPRINT("fidclunk: return\n");
+	DBG("fidclunk: return\n");
+}
+
+struct o9fid *
+o9fs_walk(struct o9fs *fs, struct o9fid *fid, struct o9fid *newfid, char *name)
+{
+	long n;
+	u_char *p;
+	int nwname;
+	DIN();
+
+	if (fid == NULL) {
+		DRET();
+		return NULL;
+	}
+
+	p = fs->outbuf;
+	O9FS_PBIT8(p + Offtype, O9FS_TWALK);
+	O9FS_PBIT16(p + Offtag, 0);
+	O9FS_PBIT32(p + Minhd, fid->fid);
+
+	if (newfid == NULL) {
+		printf("cloning fid %d\n", fid->fid);
+		newfid = o9fs_xgetfid(fs);
+		newfid->mode = fid->mode;
+		newfid->qid = fid->qid;
+		newfid->offset = fid->offset;
+		nwname = 0;
+		p += Minhd + 4 + 4 + 2;		/* Advance after nwname, which will be filled later */
+	} else {
+		if (name == NULL) {
+			printf("o9fs_walk: cloning with empty name\n");
+			DRET();
+			return NULL;
+		}
+		p = putstring(p + Minhd + 4 + 4 + 2, name);
+		nwname = 1;
+	}
+	O9FS_PBIT32(fs->outbuf + Minhd + 4, newfid->fid);
+	o9fs_dump(fs->outbuf, p - fs->outbuf);
+	O9FS_PBIT16(fs->outbuf + Minhd + 4 + 4, nwname);
+
+	n = p - fs->outbuf;
+	o9fs_dump(fs->outbuf, n);
+	O9FS_PBIT32(fs->outbuf, n);
+	n = o9fs_mio(fs, n);
+	if (n <= 0) {
+		o9fs_xputfid(fs, newfid);
+		DRET();
+		return NULL;
+	}
+	DRET();
+	return fid;
 }
 
 struct o9fsfid*
 
 	name = oname;
 	if (nf == NULL) {
-		DPRINT("twalk: cloning fid=%d\n", f->fid);
+		DBG("twalk: cloning fid=%d\n", f->fid);
 		nf = o9fs_fidclone(fs, f);
 		n = 0;
 	}
 #include "o9fs.h"
 #include "o9fs_extern.h"
 
+enum{
+	Debug = 1,
+};
+
 int
 o9fs_statcheck(u_char *buf, u_int nbuf)
 {
 #include "o9fs.h"
 #include "o9fs_extern.h"
 
+enum{
+	Debug = 1,
+};
+
 u_char*
 gstring(u_char *p, u_char *ep, char **s)
 {
 #include "o9fs.h"
 #include "o9fs_extern.h"
 
+enum{
+	Debug = 1,
+};
+
 u_char*
 pstring(u_char *p, char *s)
 {
 /* o9fs_subr.c */
-int		o9fs_allocvp(struct mount *, struct o9fsfid *, struct vnode **, u_long);
+void	o9fs_dump(u_char *, long);
+char	*putstring(char *, char *);
+int		o9fs_allocvp(struct mount *, struct o9fid *, struct vnode **, u_long);
 void	o9fs_freevp(struct vnode *);
 u_int	o9fs_tokenize(char **, u_int, char *, char);
 struct	o9fsfid *o9fs_getfid(struct o9fs *);
+struct	o9fid *o9fs_xgetfid(struct o9fs *);
+void	o9fs_xputfid(struct o9fs *, struct o9fid *);
 void	o9fs_putfid(struct o9fs *, struct o9fsfid *);
 int		o9fs_ptoumode(int);
 int		o9fs_utopmode(int);
 void	o9fs_fidclunk(struct o9fs *, struct o9fsfid *);
 struct	o9fsfid *o9fs_twalk(struct o9fs *, struct o9fsfid *, struct o9fsfid *, char *);
 int		o9fs_opencreate(int, struct o9fs *, struct o9fsfid *, int, ulong, char *);
+struct	o9fid *o9fs_walk(struct o9fs *, struct o9fid *, struct o9fid *, char *);
 
 /* o9fs_conv* */
 u_char	*pstring(u_char *, char *);
 int		o9fs_rpc(struct o9fs *, struct o9fsfcall *, struct o9fsfcall *);
 long	o9fs_mio(struct o9fs *, u_long);
 
-extern int (**o9fs_vnodeop_p)(void *);
+extern struct vops o9fs_vops;
 #include "o9fs.h"
 #include "o9fs_extern.h"
 
+enum{
+	Debug = 1,
+};
+
 extern struct vnodeopv_desc o9fs_vnodeop_opv_desc;
 extern struct vfsops o9fs_vfsops;
 
 #include "o9fs.h"
 #include "o9fs_extern.h"
 
+enum{
+	Debug = 1,
+};
+
 static long
 rdwr(struct o9fs *fs, void *buf, long count, off_t *offset, int write)
 {
 	}
 
 	if (rx->type == O9FS_RERROR) {
-		DPRINT("%s\n", rx->ename);
+		DBG("%s\n", rx->ename);
 		return -1;
 	}
 	return error;
 #include <sys/vnode.h>
 #include <sys/malloc.h>
 #include <sys/lock.h>
+#include <sys/queue.h>
 
 #include "o9fs.h"
 #include "o9fs_extern.h"
 
+enum{
+	Debug = 1,
+};
+
 enum {
-	fidchunk = 64
+	Chunk = 64
 };
 
+void
+o9fs_dump(u_char *buf, long n)
+{
+	long i;
+
+	if (buf == NULL)
+		return;
+
+	for (i = 0; i < n; i++) {
+		printf("%02x", buf[i]);
+		if (i % 16 == 15)
+			printf("\n");
+		else
+			printf(" ");
+	}
+	printf("\n");
+}
+
+struct o9fid *
+o9fs_xgetfid(struct o9fs *fs)
+{
+	struct o9fid *f;
+
+	if (fs->freefid == NULL) {
+		f = (struct o9fid *) malloc(sizeof(struct o9fid), M_O9FS, M_WAITOK);
+		f->fid = fs->nextfid++;
+		TAILQ_INSERT_TAIL(&fs->activeq, f, next);
+	} else {
+		f = TAILQ_FIRST(&fs->freeq);
+		TAILQ_REMOVE(&fs->freeq, f, next);
+	}
+	
+	f->offset = 0;
+	f->mode = -1;
+	f->qid.path = 0;
+	f->qid.vers = 0;
+	f->qid.type = 0;
+	return f;
+}
+
+void
+o9fs_xputfid(struct o9fs *fs, struct o9fid *f)
+{
+	if (f == NULL)
+		panic("o9fs_xputfid: cannot put a nil fid");
+
+	TAILQ_REMOVE(&fs->activeq, f, next);
+	TAILQ_INSERT_TAIL(&fs->freeq, f, next);
+}
+
 struct o9fsfid *
 o9fs_getfid(struct o9fs *fs)
 {
         int i;
         
         if (fs->freefid == NULL) {
-				f = (struct o9fsfid *) malloc(sizeof(struct o9fsfid) * fidchunk,
+				f = (struct o9fsfid *) malloc(sizeof(struct o9fsfid) * Chunk,
                 	M_O9FS, M_WAITOK);
-				for (i = 0; i < fidchunk; i++) {
+				for (i = 0; i < Chunk; i++) {
 						f[i].fid = fs->nextfid++;
 						f[i].next = &f[i+1];
 						f[i].opened = 0;
 void
 o9fs_putfid(struct o9fs *fs, struct o9fsfid *f)
 {        
-		DPRINT("putfid: enter\n");
+		DBG("putfid: enter\n");
 		if (f == NULL)
 			return;
 		f->next = fs->freefid;
 		fs->freefid = f;
-		DPRINT("putfid: return\n");
+		DBG("putfid: return\n");
 }
 
 /* clone a fid, client-side */
 o9fs_fidclone(struct o9fs *fs, struct o9fsfid *f)
 {
 	struct o9fsfid *nf;
-	DPRINT("o9fs_fidclone: enter\n");
+	DBG("o9fs_fidclone: enter\n");
 	if (f->opened)
 		panic("clone of open fid=%d\n", f->fid);
 	
 	nf->mode = f->mode;
 	nf->qid = f->qid;
 	nf->offset = f->offset;
-	DPRINT("o9fs_fidclone: return\n");
+	DBG("o9fs_fidclone: return\n");
 	return nf;
 }
 
 	return f;
 }
 
+char *
+putstring(char *buf, char *s)
+{
+	long n;
+
+	if (buf == NULL || s == NULL)
+		panic("putstring was given nil pointers");
+
+	n = strlen(s);
+	O9FS_PBIT16(buf, n);
+	memcpy(buf + 2, s, n);
+	return buf + 2 + n;
+}
+
 void
 o9fs_freestat(struct o9fsstat *s)
 {
 }
 
 int
-o9fs_allocvp(struct mount *mp, struct o9fsfid *f, struct vnode **vpp, u_long flag)
+o9fs_allocvp(struct mount *mp, struct o9fid *f, struct vnode **vpp, u_long flag)
 {
 	struct vnode *vp;
 	struct proc *p;
 	int error;
 
+	DIN();
+
 	p = curproc;
 	error = 0;
 	
 	/* Get a new vnode and associate it with our fid */
-	error = getnewvnode(VT_O9FS, mp, o9fs_vnodeop_p, &vp);
-	if (error)
-		goto out;
+	error = getnewvnode(VT_O9FS, mp, &o9fs_vops, &vp);
+	if (error) {
+		*vpp = NULL;
+		printf("error in getnewvnode %d\n", error);
+		DRET();
+		return error;
+	}
 
 	error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
 	if (error) {
 		vp->v_data = NULL;
 		vp = NULL;
-		goto out;
+		*vpp = NULL;
+		printf("could not lock vnode, %d\n", error);
+		DRET();
+		return error;
 	}
 
 	if (f->qid.type == O9FS_QTDIR){
-		DPRINT("o9fs_fid2vnode: isdir\n");
+		DBG("o9fs_fid2vnode: isdir\n");
 		vp->v_type = VDIR;
 	} else
 		vp->v_type = VREG;
 	vp->v_flag |= flag;
 out:
 	*vpp = vp;
+	DRET();
 	return error;
 }
 
 	vp->v_data = NULL;
 }
 
-struct o9fsfid *
-o9fs_findfid(struct o9fs *fs, int fid)
-{
-	struct o9fsfid *f;
-
-	for (f = fs->rootfid; f; f = f->next)
-		if (f->fid == fid)
-			return f;
-	return NULL;
-}
-
 int
 o9fs_ptoumode(int mode)
 {
 #include <sys/malloc.h> 
 #include <sys/filedesc.h>
 #include <sys/file.h>
+#include <sys/queue.h>
 
 #include "o9fs.h"
 #include "o9fs_extern.h"
 
+enum{
+	Debug = 1,
+};
+
 #define o9fs_init ((int (*)(struct vfsconf *))nullop)
 
 int o9fs_mount(struct mount *, const char *, void *, struct nameidata *, struct proc *);
 int o9fs_start(struct mount *, int, struct proc *);
 int o9fs_root(struct mount *, struct vnode **);
 static int	mounto9fs(struct mount *, struct file *);
-struct o9fsfid *o9fs_attach(struct o9fs *, struct o9fsfid *, char *, char *);
+struct o9fid *o9fs_attach(struct o9fs *, struct o9fid *, char *, char *);
 
+/*
+ * TODO: Check if we are are not overflowing our i/o buffers.
+ */
+
+		
+	
 static long
 o9fs_version(struct o9fs *fs, uint32_t msize)
 {
 	O9FS_PBIT8(p + Offtype, O9FS_TVERSION);
 	O9FS_PBIT16(p + Offtag, O9FS_NOTAG);
 	O9FS_PBIT32(p + Minhd, msize);
-	O9FS_PBIT16(p + Minhd + 4, 6);
-	memmove(p + Minhd + 4 + 2, "9P2000", 6);
+	putstring(p + Minhd + 4, "9P2000");
 
 	n = o9fs_mio(fs, 19);
 	if (n <= 0)
 	return fs->msize = O9FS_GBIT16(fs->inbuf + Minhd + 4);
 }	
 
-static struct o9fsfid *
+struct o9fid *
 o9fs_auth(struct o9fs *fs, char *user, char *aname)
 {
-	struct o9fsfcall tx, rx;
-	struct o9fsfid *afid;
-	int error;
+	long n;
+	u_char *p;
+	struct o9fid *f;
 
-	if (aname == NULL)
-		aname = "";
+	if (fs == NULL)
+		return NULL;
+	
+	user = user ? user : "";
+	aname = aname ? aname : "";
 
-	tx.type = O9FS_TAUTH;
-	afid = o9fs_getfid(fs);
+	p = fs->outbuf;
+	O9FS_PBIT8(p + Offtype, O9FS_TAUTH);
+	O9FS_PBIT16(p + Offtag, 0);
 
-	tx.afid = afid ? afid->fid : O9FS_NOFID;
-	tx.uname = user;
-	tx.aname = aname;
+	f = o9fs_xgetfid(fs);
+	O9FS_PBIT32(p + Minhd, f->fid);
+	p = putstring(p + Minhd + 4, user);
+	p = putstring(p, aname);
+	n = p - fs->outbuf;
+	O9FS_PBIT32(fs->outbuf, n);
 
-	error = o9fs_rpc(fs, &tx, &rx);
-	if (error) {
-		o9fs_putfid(fs, afid);
+	n = o9fs_mio(fs, n);
+	if (n <= 0) {
+		o9fs_xputfid(fs, f);
 		return NULL;
 	}
-	
-	afid->qid = rx.qid;
-	return afid;
+	return f;
 }
 
-struct o9fsfid *
-o9fs_attach(struct o9fs *fs, struct o9fsfid *afid,
-			char *user, char *aname)
+struct o9fid *
+o9fs_attach(struct o9fs *fs, struct o9fid *afid, char *user, char *aname)
 {
-	struct o9fsfcall tx, rx;
-	struct o9fsfid *fid;
-	int error;
+	long n;
+	u_char *p;
+	struct o9fid *f;
 
-	error = 0;
+	if (fs == NULL)
+		return NULL;
+
+	user = user ? user : "";
+	aname = aname ? aname : "";
 	
-	if (aname == NULL)
-		aname = "";
+	p = fs->outbuf;
+	O9FS_PBIT8(p + Offtype, O9FS_TATTACH);
+	O9FS_PBIT16(p + Offtag, 0);
 	
-	fid = o9fs_getfid(fs);
+	f = o9fs_xgetfid(fs);
+	O9FS_PBIT32(p + Minhd, f->fid);
+	O9FS_PBIT32(p + Minhd + 4, afid ? afid->fid : -1);
+	p = putstring(p + Minhd + 4 + 4, user);
+	p = putstring(p, aname);
 	
-	tx.type = O9FS_TATTACH;
-	tx.afid = afid ? afid->fid : O9FS_NOFID;
-	tx.fid = fid->fid;
-	tx.uname = user;
-	tx.aname = aname;
-
-	error = o9fs_rpc(fs, &tx, &rx);
-	if (error) {
-		o9fs_putfid(fs, fid);
+	n = p - fs->outbuf;
+	O9FS_PBIT32(fs->outbuf, n);
+	n = o9fs_mio(fs, n);
+	if (n <= 0) {
+		o9fs_xputfid(fs, f);
 		return NULL;
 	}
 
-	fid->qid = rx.qid;
-	return fid;
+	f->qid.type = O9FS_GBIT8(fs->inbuf + Minhd);
+	f->qid.vers = O9FS_GBIT32(fs->inbuf + Minhd + 1);
+	f->qid.path = O9FS_GBIT64(fs->inbuf + Minhd + 1 + 4);
+	return f;
 }
 
 int
 {
 	struct o9fs *fs;
 	struct vnode *rvp;
-	struct o9fsfid *fid;
-	int error;
+	struct o9fid *fid;
 
-	error = 0;
 	fs = (struct o9fs *) malloc(sizeof(struct o9fs), M_MISCFSMNT, M_WAITOK | M_ZERO);
-	error = getnewvnode(VT_O9FS, mp, o9fs_vnodeop_p, &rvp);
-	if (error)
-		return error;
+	if (getnewvnode(VT_O9FS, mp, &o9fs_vops, &rvp) != 0)
+		return EIO;
 
 	rvp->v_type = VDIR;
 	rvp->v_flag = VROOT;
 
 	fs->inbuf = malloc(8192+Maxhd, M_O9FS, M_WAITOK | M_ZERO);
 	fs->outbuf = malloc(8192+Maxhd, M_O9FS, M_WAITOK | M_ZERO);
+	TAILQ_INIT(&fs->activeq);
+	TAILQ_INIT(&fs->freeq);
+	fs->nextfid = 0;	
 
 	if(o9fs_version(fs, 8192) < 0)
 		return EIO;
-	return EIO;
 
 	fid = o9fs_attach(fs, o9fs_auth(fs, "none", ""), "iru", "");
 	if (fid == NULL)
-		return EIO;
+		return EIO;	
 
-	fs->rootfid = fid;
 	fs->vroot->v_data = fid;
-	error = o9fs_allocvp(fs->mp, fid, &fs->vroot, VROOT);
-	return error;
+	return o9fs_allocvp(fs->mp, fid, &fs->vroot, VROOT);
 }
 	
 
 int
-o9fs_mount(struct mount *mp, const char *path, void *data, 
-		struct nameidata *ndp, struct proc *p)
+o9fs_mount(struct mount *mp, const char *path, void *data, struct nameidata *ndp, struct proc *p)
 {
 	struct o9fs_args args;
 	int error;
 	fp->f_count++;
 	FREF(fp);
 
-	if(mounto9fs(mp, fp))
-		return 1;
+	if (mounto9fs(mp, fp) != 0)
+		return EIO;
+	printf("after mounto9fs\n");
 
 	error = copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &len);
 	if (error)
 	if (error)
 		return error;
 	bzero(mp->mnt_stat.f_mntfromname + len, MNAMELEN - len);
+	printf("returning from mount ok\n");
 	return 0;
 }
 
 {
 	struct vnode *vp;
 	struct proc *p;
-	struct o9fsfid *f;
+	struct o9fid *f;
 	struct o9fs *fs;
 	int error;
 
+	DIN();
+
 	p = curproc;
 	fs = VFSTOO9FS(mp);
+	DBG("fs %p\n", fs);
+	DBG("fs->vroot %p %d\n", fs->vroot, VTO92(fs->vroot)->fid);
 
-	DPRINT("o9fs_root: enter\n");
-/*	vp = fs->vroot;
-	vref(vp);
-	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); */
+	f = o9fs_walk(fs, VTO92(fs->vroot), NULL, NULL);
+	if (f == NULL) {
+		DRET();
+		return -1;
+	}
+	DBG("cloned root\n");
 
-	f = o9fs_clone(fs, VTO9(fs->vroot));
-	if (f == NULL)
-		return -1;
-	DPRINT("o9fs_root: cloned root\n");
-	if((error = o9fs_allocvp(fs->mp, f, &vp, VROOT)))
+	if (error = o9fs_allocvp(fs->mp, f, &vp, VROOT)) {
+		DRET();
 		return error;
+	}
 	vp->v_flag = VROOT;
 	vp->v_type = VDIR;
-	*vpp = vp;
-	DPRINT("o9fs_root: return\n");
+	*vpp = vp; 
+
+	DRET();
 	return 0;
 }
 
 {
 	struct o9fs *fs;
 	struct vnode *vp;
-	struct o9fsfid *f;
+	struct o9fid *f;
 	struct file *fp;
 	int error, flags;
 	
 	fp = fs->servfp;
 
 	vp = fs->vroot;
-	f = VTO9(vp);
+	f = VTO92(vp);
 
 	if (mntflags & MNT_FORCE)
 		flags |= FORCECLOSE;
 
 	error = vflush(mp, vp, flags);
 	if (error)
-		return (error);
+		return error;
 
 	vput(vp);
-	if (f)
-		o9fs_fidclunk(fs, f);
+//	if (f)
+//		o9fs_fidclunk(fs, f);
 	fp->f_count--;
 	FRELE(fp);
 	free(fs->rpc, M_O9FS);
 #include "o9fs.h"
 #include "o9fs_extern.h"
 
+enum{
+	Debug = 1,
+};
+
 static void *o9fsrealloc(void *, size_t, size_t);
 
 int o9fs_open(void *);
 	struct o9fsfid *f;
 	int error, mode;
 
-	DPRINT("open: enter\n");
+	DBG("open: enter\n");
 	ap = v;
 	vp = ap->a_vp;
 	p = ap->a_p;
 	f = VTO9(vp);
 
 	if (f->opened == 1) {
-		DPRINT("open: already opened\n");
+		DBG("open: already opened\n");
 		goto out;
 	}
 	
 		vp->v_type = VREG;
 
 out:
-	DPRINT("open: return (%p)->v_type=%d\n", vp, vp->v_type);
+	DBG("open: return (%p)->v_type=%d\n", vp, vp->v_type);
 	return 0;
 }
 
 	struct o9fsfid *f;
 	struct o9fs *fs;
 	
-	DPRINT("close: enter\n");
+	DBG("close: enter\n");
 	ap = v;
 	vp = ap->a_vp;
 	f = VTO9(vp);
 
 	if (f == NULL) {
-		DPRINT("close: nil fid\n");
-		DPRINT("close: return\n");
+		DBG("close: nil fid\n");
+		DBG("close: return\n");
 		return 0;
 	}
 
-	DPRINT("close: fid=%d\n", f->fid);
+	DBG("close: fid=%d\n", f->fid);
 	fs = VFSTOO9FS(vp->v_mount);
 
 	o9fs_fidclunk(fs, f);
 	vp->v_data = NULL;
-	DPRINT("close: return\n");
+	DBG("close: return\n");
 	return 0;
 }
 
 	int error, *eofflag, i, msize;
 	int64_t len;
 
-	DPRINT("readdir: enter\n");
+	DBG("readdir: enter\n");
 	ap = v;
 	vp = ap->a_vp;
 	uio = ap->a_uio;
 	free(buf, M_O9FS);
 
 	if (ts == 0 && n < 0) {
-		DPRINT("readdir: return\n");
+		DBG("readdir: return\n");
 		return -1;
 	}
 	for (i = 0; i < ts; i++) {
 		error = uiomove(&d, d.d_reclen, uio);
 		if (error) {
 			printf("readdir: uiomove error\n");
-			DPRINT("readdir: return\n");
+			DBG("readdir: return\n");
 			return -1;
 		}
 	}
-	DPRINT("readdir: return\n");
+	DBG("readdir: return\n");
 	return 0;
 }
 
 	int64_t len;
 	off_t offset;
 
-	DPRINT("write: enter\n");
+	DBG("write: enter\n");
 	ap = v;
 	vp = ap->a_vp;
 	uio = ap->a_uio;
 	f = VTO9(vp);
 	error = n = 0;
 
-	DPRINT("write: vp=%p v_type=%d\n", vp, vp->v_type); 
+	DBG("write: vp=%p v_type=%d\n", vp, vp->v_type); 
 
 	if (uio->uio_offset < 0 || vp->v_type != VREG) {
-		DPRINT("write: return EINVAL\n");
+		DBG("write: return EINVAL\n");
 		return EINVAL;
 	}
 
 	if (n < 0)
 		return -1;
 	free(buf, M_O9FS);
-	DPRINT("write: return\n");
+	DBG("write: return\n");
 	return error;
 }
 
 {
 	struct vop_lookup_args *ap;
 	struct componentname *cnp;
-	char namep[MAXPATHLEN], *path[O9FS_MAXWELEM];
-	struct vnode *dvp;
-	struct vnode **vpp;
-	struct o9fsfid *fid, *dfid;
+	struct vnode **vpp, *dvp;
+	struct proc *p;
 	struct o9fs *fs;
-	struct proc *p;
-	int flags, nameiop, error, islast;
-
-	DPRINT("lookup: enter\n");
+	struct o9fid *f, *parf;
+	int flags, op, islast, error;
+	
+	DIN();
 	ap = v;
 	dvp = ap->a_dvp;			/* parent dir where to look */
 	vpp = ap->a_vpp;			/* resulting vnode */
-	cnp = ap->a_cnp;
+	cnp = ap->a_cnp;			/* path component name */
 	flags = cnp->cn_flags;		/* lookup options */
 	p = curproc;
-	nameiop = cnp->cn_nameiop;	/* lookup operation */
+	op = cnp->cn_nameiop;		/* lookup operation */
 	islast = flags & ISLASTCN;
 
+	fs = VFSTOO9FS(dvp->v_mount);
+	parf = VTO92(dvp);			/* parent fid */
+	error = 0;
 	*vpp = NULL;
-	dfid = VTO9(dvp);			/* parent dir fid */
-	fs = VFSTOO9FS(dvp->v_mount);
+	
+	if (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.') {
+		DBG("dot\n");
+		vref(dvp);
+		*vpp = dvp;
+		DRET();
+		return 0;
+	}
 
-	DPRINT("lookup: checking dot\n");
-	/* XXX correct dot/dotdot semantics */
-/*	if (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.') {
-		DPRINT("lookup: isdot\n");
-		if (dfid->opened){
-			o9fs_fidclunk(fs, dfid);
-			fid = dfid;
-		else {
-			fid = o9fs_twalk(fs, dfid, 0, ".");
-			if (fid == NULL)
-				goto bad;
-		}
-		error = o9fs_allocvp(fs->mp, fid, vpp, 0);
-		if (error)
-			goto bad;*/
+	DBG("name is %s\n", cnp->cn_nameptr);
 
-	/*	*vpp = dvp;
-		VREF(*vpp); */
-	//	DPRINT("lookup: return\n");
-	//	return 0;
-//	} else {
-//		DPRINT("lookup: not dot\n");
-		strlcpy(namep, cnp->cn_nameptr, cnp->cn_namelen+1);
-		o9fs_tokenize(path, nelem(path), namep, '/');
-//	}
-	
-	DPRINT("lookup: walking... ");
-	if ((fid = o9fs_twalk(fs, dfid, 0, *path)) == NULL) {
-		DPRINT("not ok\n");
-		/* it is fine to fail walking when we are creating
-	 	 * or renaming on the last component of the path name
-	 	 */
-		if (islast && (nameiop == CREATE || nameiop == RENAME)) {
+	f = o9fs_walk(fs, parf, o9fs_xgetfid(fs), cnp->cn_nameptr);
+	if (f == NULL) {
+		DBG("%s not found\n", cnp->cn_nameptr);
+		if (islast && (op == CREATE || op == RENAME)) {
 			/* save the name. it's gonna be used soon */
 			cnp->cn_flags |= SAVENAME;
-			error = EJUSTRETURN;
-			DPRINT("lookup: return\n");
-			return error;
-		} else
-			/* it wasn't found at all */
-			o9fs_putfid(fs, fid);
-			goto bad;
+			DRET();
+			return EJUSTRETURN;
+		}
+		*vpp = NULL;
+		DRET();
+		return ENOENT;
 	}
-
-	DPRINT("ok\n");
-	error = o9fs_allocvp(fs->mp, fid, vpp, 0);
-	if (error)
-		goto bad;
-
+	
+	error = o9fs_allocvp(fs->mp, f, vpp, 0);
+	if (error) {
+		*vpp = NULL;
+		DRET();
+		return ENOENT;
+	}
+	
 	/* fix locking on parent dir */
 	if (islast && !(cnp->cn_flags & LOCKPARENT)) {
 		VOP_UNLOCK(dvp, 0, p);
 		flags |= PDIRUNLOCK;
 	}
-	DPRINT("lookup: return\n");
-	return error;
+	
+	DRET();
+	return 0;
+}
 
-bad:
-	*vpp = NULL;
-	DPRINT("lookup: return\n");
-	return ENOENT;
-}	
 
 
 int
 	struct vop_getattr_args *ap;
 	struct vnode *vp;
 	struct vattr *vap;
-	struct o9fsfid *f;
+	struct o9fid *f;
 	struct o9fsstat *stat;
 	struct o9fs *fs;
 
-	DPRINT("getattr: enter\n");
+	DBG("getattr: enter\n");
+
 	ap = v;
 	vp = ap->a_vp;
 	vap = ap->a_vap;
-	f = VTO9(vp);
+	f = VTO92(vp);
 	fs = VFSTOO9FS(vp->v_mount);
 
-	if (!f)
+	if (f == NULL)
 		return 0;
-	stat = o9fs_fstat(fs, f);
+
+/*	stat = o9fs_fstat(fs, f);
 	if (stat == NULL) {
-		DPRINT("getattr: Tstat failed\n");
-		DPRINT("getattr: return\n");
+		DBG("getattr: Tstat failed\n");
+		DBG("getattr: return\n");
 		return -1;
 	}
+*/
 
 	bzero(vap, sizeof(*vap));
 	vattr_null(vap);
 	vap->va_uid = 0;
 	vap->va_gid = 0;
 	vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0];
-	vap->va_size = stat->length;
+	vap->va_size = 512; //stat->length;
 	vap->va_blocksize = VFSTOO9FS(vp->v_mount)->msize;
-	vap->va_atime.tv_sec = stat->atime;
-	vap->va_mtime.tv_sec = stat->mtime;
-	vap->va_ctime.tv_sec = stat->atime;
+	vap->va_atime.tv_sec = 0; //stat->atime;
+	vap->va_mtime.tv_sec = 0; // stat->mtime;
+	vap->va_ctime.tv_sec = 0; //stat->atime;
 	vap->va_gen = 0;
 	vap->va_flags = 0;
 	vap->va_rdev = 0;
 		vap->va_type = VDIR;
 		vap->va_fileid = 2;
 	}
+
+	/*
+	 * vap->va_type being VDIR does not guarantee that user applications
+	 * will see us as a dir, we have to set the mode explicitly.
+	 */
 	vap->va_type = vp->v_type;
-	vap->va_mode = o9fs_ptoumode(stat->mode);
+	vap->va_mode = 0777; //o9fs_ptoumode(stat->mode);
+	if(vap->va_type == VDIR)
+		vap->va_mode |= S_IFDIR;
+
 	vap->va_nlink = 0;
 	vap->va_fileid = f->qid.path; /* path is bigger. truncate? */
 	vap->va_filerev = f->qid.vers;
 
-	o9fs_freestat(stat);
-	free(stat, M_O9FS);
-	DPRINT("getattr: return\n");
+//	o9fs_freestat(stat);
+//	free(stat, M_O9FS);
+	DBG("getattr: return\n");
 	return 0;
 }
 
 o9fs_inactive(void *v)
 {
 	struct vop_inactive_args *ap;
-	DPRINT("inactive: enter\n");
-	DPRINT("inactive: return\n");
+	DBG("inactive: enter\n");
+	DBG("inactive: return\n");
 	return 0;
 }
 
 	struct o9fsfid *f;
 	struct o9fs *fs;
 
-	DPRINT("reclaim: enter\n");
+	DBG("reclaim: enter\n");
 	ap = v;
 	vp = ap->a_vp;
 	f = VTO9(vp);
 	fs = VFSTOO9FS(vp->v_mount);
 
 	cache_purge(vp);
-	DPRINT("reclaiming fid %d\n", f->fid);
+	DBG("reclaiming fid %d\n", f->fid);
 	if(f)
 		o9fs_fidclunk(fs, f);
 	o9fs_freevp(vp);
 
-	DPRINT("reclaim: return\n");
+	DBG("reclaim: return\n");
 	return 0;
 }
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.