add access operation
diff --git a/kernel/dir.c b/kernel/dir.c
index 6753636..20a6aae 100644
--- a/kernel/dir.c
+++ b/kernel/dir.c
@@ -482,6 +482,40 @@
 	return fuse_do_getattr(inode);
 }
 
+#ifdef KERNEL_2_6
+static int fuse_access(struct inode *inode, int mask)
+{
+	struct fuse_conn *fc = get_fuse_conn(inode);
+	struct fuse_req *req;
+	struct fuse_access_in inarg;
+	int err;
+
+	if (fc->no_access)
+		return 0;
+
+	req = fuse_get_request(fc);
+	if (!req)
+		return -EINTR;
+
+	memset(&inarg, 0, sizeof(inarg));
+	inarg.mask = mask;
+	req->in.h.opcode = FUSE_ACCESS;
+	req->in.h.nodeid = get_node_id(inode);
+	req->inode = inode;
+	req->in.numargs = 1;
+	req->in.args[0].size = sizeof(inarg);
+	req->in.args[0].value = &inarg;
+	request_send(fc, req);
+	err = req->out.h.error;
+	fuse_put_request(fc, req);
+	if (err == -ENOSYS) {
+		fc->no_access = 1;
+		err = 0;
+	}
+	return err;
+}
+#endif
+
 static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
 {
 	struct fuse_conn *fc = get_fuse_conn(inode);
@@ -525,6 +559,11 @@
                         return -EROFS;
 		if ((mask & MAY_EXEC) && !S_ISDIR(mode) && !(mode & S_IXUGO))
 			return -EACCES;
+
+#ifdef KERNEL_2_6
+		if (nd && (nd->flags & LOOKUP_ACCESS))
+			return fuse_access(inode, mask);
+#endif
 		return 0;
 	}
 }