Index: /trunk/ChangeLog
===================================================================
--- /trunk/ChangeLog	(revision 963)
+++ /trunk/ChangeLog	(revision 964)
@@ -9,4 +9,5 @@
  * fixed #283: XCache admin APIs (admin page) cause SEGV if XCache failed to initize
  * fixed possible re-include a file by mixing include/include_once
+ * fixed #264, #284: __FILE__ __DIR__ handling for moved/hardlinked files (set "xcache.experimental = on" to eanble this fix)
 
 2.0.0 2012-04-20
Index: /trunk/NEWS
===================================================================
--- /trunk/NEWS	(revision 963)
+++ /trunk/NEWS	(revision 964)
@@ -4,4 +4,5 @@
  * admin/ config changed. please update accordingly
  * PHP 5.3.14 is unstable. Please upgrade to new version. You have been warned
+ * fixed __FILE__ __DIR__ handling for moved/hardlinked files (set "xcache.experimental = on" to eanble this fix)
 
 2.0.0 2012-04-20
Index: /trunk/processor/processor.m4
===================================================================
--- /trunk/processor/processor.m4	(revision 963)
+++ /trunk/processor/processor.m4	(revision 964)
@@ -1165,8 +1165,6 @@
 	PROCESS(time_t, file_mtime)
 	PROCESS(size_t, file_size)
-#ifdef HAVE_INODE
 	PROCESS(int, file_device)
 	PROCESS(int, file_inode)
-#endif
 
 	PROCESS(int, filepath_len)
Index: /trunk/xcache.c
===================================================================
--- /trunk/xcache.c	(revision 963)
+++ /trunk/xcache.c	(revision 964)
@@ -189,21 +189,30 @@
 	switch (type) {
 		case XC_TYPE_PHP:
-#ifdef HAVE_INODE
 			{
 				const xc_entry_php_t *php_entry1 = (const xc_entry_php_t *) entry1;
 				const xc_entry_php_t *php_entry2 = (const xc_entry_php_t *) entry2;
-				if (php_entry1->file_inode) {
-					return php_entry1->file_inode == php_entry2->file_inode
-						&& php_entry1->file_device == php_entry2->file_device;
+				if (php_entry1->file_inode && php_entry2->file_inode) {
+					zend_bool inodeIsSame = php_entry1->file_inode == php_entry2->file_inode
+						                 && php_entry1->file_device == php_entry2->file_device;
+					if (XG(experimental)) {
+						/* new experimental behavior: quick check by inode, first */
+						if (!inodeIsSame) {
+							return 0;
+						}
+
+						/* and then opened_path compare */
+					}
+					else {
+						/* old behavior: inode check only */
+						return inodeIsSame;
+					}
 				}
 			}
-#endif
+
 			assert(IS_ABSOLUTE_PATH(entry1->name.str.val, entry1->name.str.len));
 			assert(IS_ABSOLUTE_PATH(entry2->name.str.val, entry2->name.str.len));
 
-			if (entry1->name.str.len != entry2->name.str.len) {
-				return 0;
-			}
-			return memcmp(entry1->name.str.val, entry2->name.str.val, entry1->name.str.len + 1) == 0;
+			return entry1->name.str.len == entry2->name.str.len
+				&& memcmp(entry1->name.str.val, entry2->name.str.val, entry1->name.str.len + 1) == 0;
 
 		case XC_TYPE_VAR:
@@ -212,18 +221,12 @@
 				return 0;
 			}
-			else if (entry1->name_type == IS_UNICODE) {
-				if (entry1->name.ustr.len != entry2->name.ustr.len) {
-					return 0;
-				}
-				return memcmp(entry1->name.ustr.val, entry2->name.ustr.val, (entry1->name.ustr.len + 1) * sizeof(UChar)) == 0;
-			}
-			else
-#endif
-			{
-				if (entry1->name.str.len != entry2->name.str.len) {
-					return 0;
-				}
-				return memcmp(entry1->name.str.val, entry2->name.str.val, entry1->name.str.len + 1) == 0;
-			}
+
+			if (entry1->name_type == IS_UNICODE) {
+				return entry1->name.ustr.len == entry2->name.ustr.len
+				    && memcmp(entry1->name.ustr.val, entry2->name.ustr.val, (entry1->name.ustr.len + 1) * sizeof(UChar)) == 0;
+			}
+#endif
+			return entry1->name.str.len == entry2->name.str.len
+			    && memcmp(entry1->name.str.val, entry2->name.str.val, entry1->name.str.len + 1) == 0;
 			break;
 
@@ -693,8 +696,6 @@
 			add_assoc_long_ex(ei, ZEND_STRS("file_mtime"),    entry_php->file_mtime);
 			add_assoc_long_ex(ei, ZEND_STRS("file_size"),     entry_php->file_size);
-#ifdef HAVE_INODE
 			add_assoc_long_ex(ei, ZEND_STRS("file_device"),   entry_php->file_device);
 			add_assoc_long_ex(ei, ZEND_STRS("file_inode"),    entry_php->file_inode);
-#endif
 
 #ifdef HAVE_XCACHE_CONSTANT
@@ -1154,8 +1155,6 @@
 		compiler->new_entry.file_mtime   = buf.st_mtime;
 		compiler->new_entry.file_size    = buf.st_size;
-#ifdef HAVE_INODE
 		compiler->new_entry.file_device  = buf.st_dev;
 		compiler->new_entry.file_inode   = buf.st_ino;
-#endif
 	}
 	else {
@@ -1164,19 +1163,12 @@
 		compiler->new_entry.file_mtime   = 0;
 		compiler->new_entry.file_size    = 0;
-#ifdef HAVE_INODE
 		compiler->new_entry.file_device  = 0;
 		compiler->new_entry.file_inode   = 0;
-#endif
 	}
 
 	{
 		xc_hash_value_t basename_hash_value;
-		if (
-			xc_php_hcache.size > 1
-#ifdef HAVE_INODE
-			|| !compiler->new_entry.file_inode
-#endif
-			)
-		{
+		if (xc_php_hcache.size > 1
+		 || !compiler->new_entry.file_inode) {
 			const char *filename_end = compiler->filename + compiler->filename_len;
 			const char *basename = filename_end - 1;
@@ -1194,10 +1186,7 @@
 		compiler->entry_hash.cacheid = xc_php_hcache.size > 1 ? xc_hash_fold(basename_hash_value, &xc_php_hcache) : 0;
 		compiler->entry_hash.entryslotid = xc_hash_fold(
-#ifdef HAVE_INODE
 				compiler->new_entry.file_inode
 				? HASH(compiler->new_entry.file_device + compiler->new_entry.file_inode)
-				:
-#endif
-				basename_hash_value
+				: basename_hash_value
 				, &xc_php_hentry);
 	}
Index: /trunk/xcache.h
===================================================================
--- /trunk/xcache.h	(revision 963)
+++ /trunk/xcache.h	(revision 964)
@@ -23,5 +23,4 @@
 #include "lock.h"
 
-#define HAVE_INODE
 #if !defined(ZEND_ENGINE_2_4) && (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 4 || PHP_MAJOR_VERSION > 5)
 #	define ZEND_ENGINE_2_4
@@ -434,8 +433,6 @@
 	time_t file_mtime;
 	size_t file_size;
-#ifdef HAVE_INODE
 	int file_device;
 	int file_inode;
-#endif
 
 	int    filepath_len;
