added support for setting the st_ino field
diff --git a/kernel/dir.c b/kernel/dir.c
index 36eb3bf..ce6df5d 100644
--- a/kernel/dir.c
+++ b/kernel/dir.c
@@ -35,6 +35,7 @@
 #endif
 	}
 
+	inode->i_ino     = attr->ino;
 	inode->i_mode    = (inode->i_mode & S_IFMT) + (attr->mode & 07777);
 	inode->i_nlink   = attr->nlink;
 	inode->i_uid     = attr->uid;
@@ -80,40 +81,102 @@
 		printk("fuse_init_inode: bad file type: %o\n", inode->i_mode);
 }
 
-struct inode *fuse_iget(struct super_block *sb, ino_t ino, int generation,
-			struct fuse_attr *attr, int version)
+#ifdef KERNEL_2_6
+static int fuse_inode_eq(struct inode *inode, void *_nodeidp)
+{
+	unsigned long nodeid = *(unsigned long *) _nodeidp;
+	struct fuse_inode *fi = INO_FI(inode);
+	if (fi->nodeid == nodeid)
+		return 1;
+	else
+		return 0;
+}
+
+static int fuse_inode_set(struct inode *inode, void *_nodeidp)
+{
+	unsigned long nodeid = *(unsigned long *) _nodeidp;
+	struct fuse_inode *fi = INO_FI(inode);
+	fi->nodeid = nodeid;
+	return 0;
+}
+
+struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
+			int generation, struct fuse_attr *attr, int version)
 {
 	struct inode *inode;
 
-	inode = iget(sb, ino);
-	if (inode) {
-		if (!INO_FI(inode)) {
-			struct fuse_inode *fi = fuse_inode_alloc();
-			if (!fi) {
-				iput(inode);
-				inode = NULL;
-				goto out;
-			}
-			INO_FI(inode) = fi;
-			inode->i_generation = generation;
-			fuse_init_inode(inode, attr);
-		} else if (inode->i_generation != generation)
-			printk("fuse_iget: bad generation for ino %lu\n", ino);
+	inode = iget5_locked(sb, nodeid, fuse_inode_eq, fuse_inode_set, &nodeid);
+	if (!inode)
+		return NULL;
 
-		change_attributes(inode, attr);
-		inode->i_version = version;
-	}
- out:
+	if ((inode->i_state & I_NEW)) {
+		inode->i_generation = generation;
+		fuse_init_inode(inode, attr);
+		unlock_new_inode(inode);
+	} else if (inode->i_generation != generation)
+		printk("fuse_iget: bad generation for node %lu\n", nodeid);
 
+	change_attributes(inode, attr);
+	inode->i_version = version;
 	return inode;
 }
 
+struct inode *fuse_ilookup(struct fuse_conn *fc, ino_t ino, unsigned long nodeid)
+{
+	return ilookup5(fc->sb, nodeid, fuse_inode_eq, &nodeid);
+}
+#else
+static int fuse_inode_eq(struct inode *inode, unsigned long ino, void *_nodeidp){
+	unsigned long nodeid = *(unsigned long *) _nodeidp;
+	struct fuse_inode *fi = INO_FI(inode);
+	if (inode->u.generic_ip && fi->nodeid == nodeid)
+		return 1;
+	else
+		return 0;
+}
+
+struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
+			int generation, struct fuse_attr *attr, int version)
+{
+	struct inode *inode;
+
+	inode = iget4(sb, attr->ino, fuse_inode_eq, &nodeid);
+	if (!inode)
+		return NULL;
+
+	if (!inode->u.generic_ip) {
+		struct fuse_inode *fi = INO_FI(inode);
+		fi->nodeid = nodeid;
+		inode->u.generic_ip = inode;
+		inode->i_generation = generation;
+		fuse_init_inode(inode, attr);
+	} else if (inode->i_generation != generation)
+		printk("fuse_iget: bad generation for node %lu\n", nodeid);
+
+	change_attributes(inode, attr);
+	inode->i_version = version;
+	return inode;
+}
+
+struct inode *fuse_ilookup(struct fuse_conn *fc, ino_t ino, unsigned long nodeid)
+{
+	struct inode *inode = iget4(fc->sb, ino, fuse_inode_eq, &nodeid);
+	if (inode && !inode->u.generic_ip) {
+		iput(inode);
+		inode = NULL;
+	}
+	return inode;
+}
+
+#endif
+
 static int fuse_send_lookup(struct fuse_conn *fc, struct fuse_req *req,
 			    struct inode *dir, struct dentry *entry, 
 			    struct fuse_entry_out *outarg, int *version)
 {
+	struct fuse_inode *fi = INO_FI(dir);
 	req->in.h.opcode = FUSE_LOOKUP;
-	req->in.h.ino = dir->i_ino;
+	req->in.h.nodeid = fi->nodeid;
 	req->in.numargs = 1;
 	req->in.args[0].size = entry->d_name.len + 1;
 	req->in.args[0].value = entry->d_name.name;
@@ -171,10 +234,10 @@
 
 	err = fuse_send_lookup(fc, req, dir, entry, &outarg, &version);
 	if (!err) {
-		inode = fuse_iget(dir->i_sb, outarg.ino, outarg.generation,
+		inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
 				  &outarg.attr, version);
 		if (!inode) {
-			fuse_send_forget(fc, req, outarg.ino, version);
+			fuse_send_forget(fc, req, outarg.nodeid, version);
 			return -ENOMEM;
 		}
 	} 
@@ -208,10 +271,10 @@
 {
 	struct inode *inode;
 	struct fuse_inode *fi;
-	inode = fuse_iget(dir->i_sb, outarg->ino, outarg->generation, 
+	inode = fuse_iget(dir->i_sb, outarg->nodeid, outarg->generation, 
 			  &outarg->attr, version);
 	if (!inode) {
-		fuse_send_forget(fc, req, outarg->ino, version);
+		fuse_send_forget(fc, req, outarg->nodeid, version);
 		return -ENOMEM;
 	}
 	fuse_put_request(fc, req);
@@ -240,6 +303,7 @@
 		      dev_t rdev)
 {
 	struct fuse_conn *fc = INO_FC(dir);
+	struct fuse_inode *fi = INO_FI(dir);
 	struct fuse_req *req = fuse_get_request(fc);
 	struct fuse_mknod_in inarg;
 	struct fuse_entry_out outarg;
@@ -252,7 +316,7 @@
 	inarg.mode = mode;
 	inarg.rdev = new_encode_dev(rdev);
 	req->in.h.opcode = FUSE_MKNOD;
-	req->in.h.ino = dir->i_ino;
+	req->in.h.nodeid = fi->nodeid;
 	req->in.numargs = 2;
 	req->in.args[0].size = sizeof(inarg);
 	req->in.args[0].value = &inarg;
@@ -280,6 +344,7 @@
 static int fuse_mkdir(struct inode *dir, struct dentry *entry, int mode)
 {
 	struct fuse_conn *fc = INO_FC(dir);
+	struct fuse_inode *fi = INO_FI(dir);
 	struct fuse_req *req = fuse_get_request(fc);
 	struct fuse_mkdir_in inarg;
 	struct fuse_entry_out outarg;
@@ -291,7 +356,7 @@
 	memset(&inarg, 0, sizeof(inarg));
 	inarg.mode = mode;
 	req->in.h.opcode = FUSE_MKDIR;
-	req->in.h.ino = dir->i_ino;
+	req->in.h.nodeid = fi->nodeid;
 	req->in.numargs = 2;
 	req->in.args[0].size = sizeof(inarg);
 	req->in.args[0].value = &inarg;
@@ -314,6 +379,7 @@
 			const char *link)
 {
 	struct fuse_conn *fc = INO_FC(dir);
+	struct fuse_inode *fi = INO_FI(dir);
 	struct fuse_req *req;
 	struct fuse_entry_out outarg;
 	unsigned int len = strlen(link) + 1;
@@ -327,7 +393,7 @@
 		return -ERESTARTSYS;
 
 	req->in.h.opcode = FUSE_SYMLINK;
-	req->in.h.ino = dir->i_ino;
+	req->in.h.nodeid = fi->nodeid;
 	req->in.numargs = 2;
 	req->in.args[0].size = entry->d_name.len + 1;
 	req->in.args[0].value = entry->d_name.name;
@@ -349,6 +415,7 @@
 static int fuse_unlink(struct inode *dir, struct dentry *entry)
 {
 	struct fuse_conn *fc = INO_FC(dir);
+	struct fuse_inode *fi = INO_FI(dir);
 	struct fuse_req *req = fuse_get_request(fc);
 	int err;
 	
@@ -356,7 +423,7 @@
 		return -ERESTARTSYS;
 
 	req->in.h.opcode = FUSE_UNLINK;
-	req->in.h.ino = dir->i_ino;
+	req->in.h.nodeid = fi->nodeid;
 	req->in.numargs = 1;
 	req->in.args[0].size = entry->d_name.len + 1;
 	req->in.args[0].value = entry->d_name.name;
@@ -379,6 +446,7 @@
 static int fuse_rmdir(struct inode *dir, struct dentry *entry)
 {
 	struct fuse_conn *fc = INO_FC(dir);
+	struct fuse_inode *fi = INO_FI(dir);
 	struct fuse_req *req = fuse_get_request(fc);
 	int err;
 	
@@ -386,7 +454,7 @@
 		return -ERESTARTSYS;
 
 	req->in.h.opcode = FUSE_RMDIR;
-	req->in.h.ino = dir->i_ino;
+	req->in.h.nodeid = fi->nodeid;
 	req->in.numargs = 1;
 	req->in.args[0].size = entry->d_name.len + 1;
 	req->in.args[0].value = entry->d_name.name;
@@ -404,6 +472,8 @@
 		       struct inode *newdir, struct dentry *newent)
 {
 	struct fuse_conn *fc = INO_FC(olddir);
+	struct fuse_inode *oldfi = INO_FI(olddir);
+	struct fuse_inode *newfi = INO_FI(newdir);
 	struct fuse_req *req = fuse_get_request(fc);
 	struct fuse_rename_in inarg;
 	int err;
@@ -412,9 +482,9 @@
 		return -ERESTARTSYS;
 
 	memset(&inarg, 0, sizeof(inarg));
-	inarg.newdir = newdir->i_ino;
+	inarg.newdir = newfi->nodeid;
 	req->in.h.opcode = FUSE_RENAME;
-	req->in.h.ino = olddir->i_ino;
+	req->in.h.nodeid = oldfi->nodeid;
 	req->in.numargs = 3;
 	req->in.args[0].size = sizeof(inarg);
 	req->in.args[0].value = &inarg;
@@ -438,6 +508,8 @@
 {
 	struct inode *inode = entry->d_inode;
 	struct fuse_conn *fc = INO_FC(inode);
+	struct fuse_inode *fi = INO_FI(inode);
+	struct fuse_inode *newfi = INO_FI(newdir);
 	struct fuse_req *req = fuse_get_request(fc);
 	struct fuse_link_in inarg;
 	struct fuse_entry_out outarg;
@@ -447,9 +519,9 @@
 		return -ERESTARTSYS;
 
 	memset(&inarg, 0, sizeof(inarg));
-	inarg.newdir = newdir->i_ino;
+	inarg.newdir = newfi->nodeid;
 	req->in.h.opcode = FUSE_LINK;
-	req->in.h.ino = inode->i_ino;
+	req->in.h.nodeid = fi->nodeid;
 	req->in.numargs = 2;
 	req->in.args[0].size = sizeof(inarg);
 	req->in.args[0].value = &inarg;
@@ -482,7 +554,7 @@
 		return -ERESTARTSYS;
 
 	req->in.h.opcode = FUSE_GETATTR;
-	req->in.h.ino = inode->i_ino;
+	req->in.h.nodeid = fi->nodeid;
 	req->out.numargs = 1;
 	req->out.args[0].size = sizeof(arg);
 	req->out.args[0].value = &arg;
@@ -503,7 +575,7 @@
 	struct fuse_inode *fi = INO_FI(inode);
 	struct fuse_conn *fc = INO_FC(inode);
 
-	if (inode->i_ino == FUSE_ROOT_INO) {
+	if (fi->nodeid == FUSE_ROOT_ID) {
 		if (!(fc->flags & FUSE_ALLOW_OTHER) &&
 		    current->fsuid != fc->uid &&
 		    (!(fc->flags & FUSE_ALLOW_ROOT) ||
@@ -598,6 +670,7 @@
 {
 	struct inode *inode = file->f_dentry->d_inode;
 	struct fuse_conn *fc = INO_FC(inode);
+	struct fuse_inode *fi = INO_FI(inode);
 	struct fuse_req *req = fuse_get_request(fc);
 	struct fuse_getdir_out_i outarg;
 	int err;
@@ -606,7 +679,7 @@
 		return -ERESTARTSYS;
 
 	req->in.h.opcode = FUSE_GETDIR;
-	req->in.h.ino = inode->i_ino;
+	req->in.h.nodeid = fi->nodeid;
 	req->out.numargs = 1;
 	req->out.args[0].size = sizeof(struct fuse_getdir_out);
 	req->out.args[0].value = &outarg;
@@ -651,6 +724,7 @@
 {
 	struct inode *inode = dentry->d_inode;
 	struct fuse_conn *fc = INO_FC(inode);
+	struct fuse_inode *fi = INO_FI(inode);
 	struct fuse_req *req = fuse_get_request(fc);
 	char *link;
 
@@ -663,7 +737,7 @@
 		goto out;
 	}
 	req->in.h.opcode = FUSE_READLINK;
-	req->in.h.ino = inode->i_ino;
+	req->in.h.nodeid = fi->nodeid;
 	req->out.argvar = 1;
 	req->out.numargs = 1;
 	req->out.args[0].size = PAGE_SIZE - 1;
@@ -793,7 +867,7 @@
 	memset(&inarg, 0, sizeof(inarg));
 	inarg.valid = iattr_to_fattr(attr, &inarg.attr);
 	req->in.h.opcode = FUSE_SETATTR;
-	req->in.h.ino = inode->i_ino;
+	req->in.h.nodeid = fi->nodeid;
 	req->in.numargs = 1;
 	req->in.args[0].size = sizeof(inarg);
 	req->in.args[0].value = &inarg;
@@ -837,7 +911,7 @@
 		if (ret)
 			return 0;
 		
-		if (outarg.ino != inode->i_ino)
+		if (outarg.nodeid != fi->nodeid)
 			return 0;
 		
 		change_attributes(inode, &outarg.attr);
@@ -942,6 +1016,7 @@
 {
 	struct inode *inode = entry->d_inode;
 	struct fuse_conn *fc = INO_FC(inode);
+	struct fuse_inode *fi = INO_FI(inode);
 	struct fuse_req *req;
 	struct fuse_setxattr_in inarg;
 	int err;
@@ -960,7 +1035,7 @@
 	inarg.size = size;
 	inarg.flags = flags;
 	req->in.h.opcode = FUSE_SETXATTR;
-	req->in.h.ino = inode->i_ino;
+	req->in.h.nodeid = fi->nodeid;
 	req->in.numargs = 3;
 	req->in.args[0].size = sizeof(inarg);
 	req->in.args[0].value = &inarg;
@@ -983,6 +1058,7 @@
 {
 	struct inode *inode = entry->d_inode;
 	struct fuse_conn *fc = INO_FC(inode);
+	struct fuse_inode *fi = INO_FI(inode);
 	struct fuse_req *req;
 	struct fuse_getxattr_in inarg;
 	struct fuse_getxattr_out outarg;
@@ -998,7 +1074,7 @@
 	memset(&inarg, 0, sizeof(inarg));
 	inarg.size = size;
 	req->in.h.opcode = FUSE_GETXATTR;
-	req->in.h.ino = inode->i_ino;
+	req->in.h.nodeid = fi->nodeid;
 	req->in.numargs = 2;
 	req->in.args[0].size = sizeof(inarg);
 	req->in.args[0].value = &inarg;
@@ -1032,6 +1108,7 @@
 {
 	struct inode *inode = entry->d_inode;
 	struct fuse_conn *fc = INO_FC(inode);
+	struct fuse_inode *fi = INO_FI(inode);
 	struct fuse_req *req;
 	struct fuse_getxattr_in inarg;
 	struct fuse_getxattr_out outarg;
@@ -1047,7 +1124,7 @@
 	memset(&inarg, 0, sizeof(inarg));
 	inarg.size = size;
 	req->in.h.opcode = FUSE_LISTXATTR;
-	req->in.h.ino = inode->i_ino;
+	req->in.h.nodeid = fi->nodeid;
 	req->in.numargs = 1;
 	req->in.args[0].size = sizeof(inarg);
 	req->in.args[0].value = &inarg;
@@ -1079,6 +1156,7 @@
 {
 	struct inode *inode = entry->d_inode;
 	struct fuse_conn *fc = INO_FC(inode);
+	struct fuse_inode *fi = INO_FI(inode);
 	struct fuse_req *req;
 	int err;
 	
@@ -1090,7 +1168,7 @@
 		return -ERESTARTSYS;
 
 	req->in.h.opcode = FUSE_REMOVEXATTR;
-	req->in.h.ino = inode->i_ino;
+	req->in.h.nodeid = fi->nodeid;
 	req->in.numargs = 1;
 	req->in.args[0].size = strlen(name) + 1;
 	req->in.args[0].value = name;