Index: trunk/xcache.c
===================================================================
--- trunk/xcache.c	(revision 164)
+++ trunk/xcache.c	(revision 165)
@@ -121,6 +121,8 @@
 				xc_entry_data_php_t *ap = a->data.php;
 				xc_entry_data_php_t *bp = b->data.php;
-				return ap->inode == bp->inode
-					&& ap->device == bp->device;
+				if (ap->inode) {
+					return ap->inode == bp->inode
+						&& ap->device == bp->device;
+				}
 			} while(0);
 #endif
@@ -618,5 +620,5 @@
 static int xc_stat(const char *filename, const char *include_path, struct stat *pbuf TSRMLS_DC) /* {{{ */
 {
-	char filepath[1024];
+	char filepath[MAXPATHLEN];
 	char *paths, *path;
 	char *tokbuf;
@@ -628,8 +630,7 @@
 
 	for (path = php_strtok_r(paths, tokens, &tokbuf); path; path = php_strtok_r(NULL, tokens, &tokbuf)) {
-		if (strlen(path) + strlen(filename) + 1 > 1024) {
+		if (snprintf(filepath, sizeof(filepath), "%s/%s", path, filename) >= MAXPATHLEN - 1) {
 			continue;
 		}
-		snprintf(filepath, sizeof(filepath), "%s/%s", path, filename);
 		if (VCWD_STAT(filepath, pbuf) == 0) {
 			free_alloca(paths);
@@ -649,5 +650,5 @@
 #define HASH_STR(s) HASH_STR_L(s, strlen(s) + 1)
 #define HASH_NUM(n) HASH(n)
-static inline xc_hash_value_t xc_entry_hash_var(xc_entry_t *xce TSRMLS_DC) /* {{{ */
+static inline xc_hash_value_t xc_entry_hash_name(xc_entry_t *xce TSRMLS_DC) /* {{{ */
 {
 	return UNISW(NOTHING, UG(unicode) ? HASH_USTR_L(xce->name_type, xce->name.uni.val, xce->name.uni.len) :)
@@ -655,14 +656,16 @@
 }
 /* }}} */
+#define xc_entry_hash_var xc_entry_hash_name
 static inline xc_hash_value_t xc_entry_hash_php(xc_entry_t *xce TSRMLS_DC) /* {{{ */
 {
 #ifdef HAVE_INODE
-	return HASH(xce->data.php->device + xce->data.php->inode);
-#else
-	return xc_entry_hash_var(xce TSRMLS_CC);
-#endif
-}
-/* }}} */
-static int xc_entry_init_key_php(xc_entry_t *xce, char *filename TSRMLS_DC) /* {{{ */
+	if (xce->data.php->inode) {
+		return HASH(xce->data.php->device + xce->data.php->inode);
+	}
+#endif
+	return xc_entry_hash_name(xce TSRMLS_CC);
+}
+/* }}} */
+static int xc_entry_init_key_php(xc_entry_t *xce, char *filename, char *opened_path_buffer TSRMLS_DC) /* {{{ */
 {
 	struct stat buf, *pbuf;
@@ -676,10 +679,12 @@
 	}
 
-	do {
+	php = xce->data.php;
+
+	if (XG(stat)) {
 		if (strcmp(SG(request_info).path_translated, filename) == 0) {
 			/* sapi has already done this stat() for us */
 			pbuf = sapi_get_stat(TSRMLS_C);
 			if (pbuf) {
-				break;
+				goto stat_done;
 			}
 		}
@@ -691,5 +696,5 @@
 				return 0;
 			}
-			break;
+			goto stat_done;
 		}
 
@@ -707,5 +712,5 @@
 				return 0;
 			}
-			break;
+			goto stat_done;
 		}
 not_relative_path:
@@ -715,8 +720,37 @@
 			return 0;
 		}
-	} while (0);
-
-	if (XG(request_time) - pbuf->st_mtime < 2) {
-		return 0;
+
+		/* fall */
+
+stat_done:
+		if (XG(request_time) - pbuf->st_mtime < 2) {
+			return 0;
+		}
+
+		php->mtime        = pbuf->st_mtime;
+#ifdef HAVE_INODE
+		php->device       = pbuf->st_dev;
+		php->inode        = pbuf->st_ino;
+#endif
+		php->sourcesize   = pbuf->st_size;
+	}
+	else { /* XG(inode) */
+		php->mtime        = 0;
+#ifdef HAVE_INODE
+		php->device       = 0;
+		php->inode        = 0;
+#endif
+		php->sourcesize   = 0;
+	}
+
+#ifdef HAVE_INODE
+	if (!php->inode)
+#endif
+	{
+		/* hash on filename, let's expand it to real path */
+		filename = expand_filepath(filename, opened_path_buffer TSRMLS_CC);
+		if (filename == NULL) {
+			return 0;
+		}
 	}
 
@@ -724,13 +758,4 @@
 	xce->name.str.val = filename;
 	xce->name.str.len = strlen(filename);
-
-	php = xce->data.php;
-	php->mtime        = pbuf->st_mtime;
-#ifdef HAVE_INODE
-	php->device       = pbuf->st_dev;
-	php->inode        = pbuf->st_ino;
-#endif
-	php->sourcesize   = pbuf->st_size;
-
 
 	hv = xc_entry_hash_php(xce TSRMLS_CC);
@@ -754,4 +779,5 @@
 	zend_bool catched = 0;
 	char *filename;
+	char opened_path_buffer[MAXPATHLEN];
 	int old_constinfo_cnt, old_funcinfo_cnt, old_classinfo_cnt;
 
@@ -779,5 +805,5 @@
 	filename = h->opened_path ? h->opened_path : h->filename;
 	xce.data.php = &php;
-	if (!xc_entry_init_key_php(&xce, filename TSRMLS_CC)) {
+	if (!xc_entry_init_key_php(&xce, filename, opened_path_buffer TSRMLS_CC)) {
 		return origin_compile_file(h, type TSRMLS_CC);
 	}
@@ -860,7 +886,15 @@
 
 	filename = h->opened_path ? h->opened_path : h->filename;
-	if (xce.name.str.val != filename) {
-		xce.name.str.val = filename;
-		xce.name.str.len = strlen(filename);
+	/* none-inode enabled entry hash/compare on name
+	 * do not update to its name to real pathname
+	 */
+#ifdef HAVE_INODE
+	if (xce.data.php->inode)
+#endif
+	{
+		if (xce.name.str.val != filename) {
+			xce.name.str.val = filename;
+			xce.name.str.len = strlen(filename);
+		}
 	}
 
@@ -2116,4 +2150,5 @@
 
 	STD_PHP_INI_BOOLEAN("xcache.cacher",                 "1", PHP_INI_ALL,    OnUpdateBool,        cacher,            zend_xcache_globals, xcache_globals)
+	STD_PHP_INI_BOOLEAN("xcache.stat",                   "1", PHP_INI_ALL,    OnUpdateBool,        stat,              zend_xcache_globals, xcache_globals)
 #ifdef HAVE_XCACHE_OPTIMIZER
 	STD_PHP_INI_BOOLEAN("xcache.optimizer",              "0", PHP_INI_ALL,    OnUpdateBool,        optimizer,         zend_xcache_globals, xcache_globals)
