if (likely(dx_dir))
                return generic_file_llseek_size(file, offset, origin,
-                                               ext3_get_htree_eof(file));
+                                               ext3_get_htree_eof(file),
+                                               i_size_read(inode));
        else
                return generic_file_llseek(file, offset, origin);
 }
 
        else
                maxbytes = inode->i_sb->s_maxbytes;
 
-       return generic_file_llseek_size(file, offset, origin, maxbytes);
+       return generic_file_llseek_size(file, offset, origin,
+                                       maxbytes, i_size_read(inode));
 }
 
 const struct file_operations ext4_file_operations = {
 
  * @file:      file structure to seek on
  * @offset:    file offset to seek to
  * @origin:    type of seek
- * @size:      max size of file system
+ * @size:      max size of this file in file system
+ * @eof:       offset used for SEEK_END position
  *
  * This is a variant of generic_file_llseek that allows passing in a custom
- * file size.
+ * maximum file size and a custom EOF position, for e.g. hashed directories
  *
  * Synchronization:
  * SEEK_SET and SEEK_END are unsynchronized (but atomic on 64bit platforms)
  */
 loff_t
 generic_file_llseek_size(struct file *file, loff_t offset, int origin,
-               loff_t maxsize)
+               loff_t maxsize, loff_t eof)
 {
        struct inode *inode = file->f_mapping->host;
 
        switch (origin) {
        case SEEK_END:
-               offset += i_size_read(inode);
+               offset += eof;
                break;
        case SEEK_CUR:
                /*
                 * In the generic case the entire file is data, so as long as
                 * offset isn't at the end of the file then the offset is data.
                 */
-               if (offset >= i_size_read(inode))
+               if (offset >= eof)
                        return -ENXIO;
                break;
        case SEEK_HOLE:
                 * There is a virtual hole at the end of the file, so as long as
                 * offset isn't i_size or larger, return i_size.
                 */
-               if (offset >= i_size_read(inode))
+               if (offset >= eof)
                        return -ENXIO;
-               offset = i_size_read(inode);
+               offset = eof;
                break;
        }
 
        struct inode *inode = file->f_mapping->host;
 
        return generic_file_llseek_size(file, offset, origin,
-                                       inode->i_sb->s_maxbytes);
+                                       inode->i_sb->s_maxbytes,
+                                       i_size_read(inode));
 }
 EXPORT_SYMBOL(generic_file_llseek);
 
 
 extern loff_t no_llseek(struct file *file, loff_t offset, int origin);
 extern loff_t generic_file_llseek(struct file *file, loff_t offset, int origin);
 extern loff_t generic_file_llseek_size(struct file *file, loff_t offset,
-               int origin, loff_t maxsize);
+               int origin, loff_t maxsize, loff_t eof);
 extern int generic_file_open(struct inode * inode, struct file * filp);
 extern int nonseekable_open(struct inode * inode, struct file * filp);