# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.1017  -> 1.1018 
#	include/linux/ext3_fs.h	1.11    -> 1.12   
#	      fs/ext3/hash.c	1.1     -> 1.2    
#	       fs/ext3/dir.c	1.2     -> 1.3    
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/03/13	tytso@think.thunk.org	1.1018
# Htree EOF/Hash cookie kludge for buggy Linux NFS code 
# 
# We now use 0x7ffffff as the EOF cookie, because Linux NFS  
# stupidly interpret the cookie (which is supposed to be a bag of bits 
# without necessarily any semantic value) as a signed 64 bit integer,
# and then convert it to a unsigned integer, and then blow up if 
# it cannot be expressed be expressed as a 32-bit value!!
# 
# In order to do this, we have to fold the hash value 0x7ffffff into
# the hash value 0x7ffffffe.  This is relatively safe; the only time
# we will lose if the directory contains filenames that hash to both
# 0x7ffffffe and 0x7fffffff (under the original hash), and the last
# directory entry which hashes to 0x7ffffffe is at the end of a leaf 
# block, and the first directory entry which hashes to 0x7fffffff is
# at the beginning of a leaf block.
#  
# --------------------------------------------
#
diff -Nru a/fs/ext3/dir.c b/fs/ext3/dir.c
--- a/fs/ext3/dir.c	Thu Mar 13 00:37:36 2003
+++ b/fs/ext3/dir.c	Thu Mar 13 00:37:36 2003
@@ -431,7 +431,7 @@
 		filp->private_data = info;
 	}
 
-	if (filp->f_pos == -1)
+	if (filp->f_pos == EXT3_HTREE_EOF)
 		return 0;	/* EOF */
 
 	/* Some one has messed with f_pos; reset the world */
@@ -471,7 +471,7 @@
 			if (ret < 0)
 				return ret;
 			if (ret == 0) {
-				filp->f_pos = -1;
+				filp->f_pos = EXT3_HTREE_EOF;
 				break;
 			}
 			info->curr_node = rb_get_first(&info->root);
@@ -486,7 +486,7 @@
 		info->curr_node = rb_get_next(info->curr_node);
 		if (!info->curr_node) {
 			if (info->next_hash == ~0) {
-				filp->f_pos = -1;
+				filp->f_pos = EXT3_HTREE_EOF;
 				break;
 			}
 			info->curr_hash = info->next_hash;
diff -Nru a/fs/ext3/hash.c b/fs/ext3/hash.c
--- a/fs/ext3/hash.c	Thu Mar 13 00:37:36 2003
+++ b/fs/ext3/hash.c	Thu Mar 13 00:37:36 2003
@@ -209,7 +209,10 @@
 		hinfo->hash = 0;
 		return -1;
 	}
-	hinfo->hash = hash & ~1;
+	hash = hash & ~1;
+	if (hash == (EXT3_HTREE_EOF << 1))
+		hash = (EXT3_HTREE_EOF-1) << 1;
+	hinfo->hash = hash;
 	hinfo->minor_hash = minor_hash;
 	return 0;
 }
diff -Nru a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
--- a/include/linux/ext3_fs.h	Thu Mar 13 00:37:36 2003
+++ b/include/linux/ext3_fs.h	Thu Mar 13 00:37:36 2003
@@ -630,6 +630,8 @@
 	u32		*seed;
 };
 
+#define EXT3_HTREE_EOF	0x7fffffff
+
 #ifdef __KERNEL__
 /*
  * Control parameters used by ext3_htree_next_block