/* reiserfs.c - ReiserFS versions up to 3.6 */
/*
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 2003,2004,2005,2008  Free Software Foundation, Inc.
 *
 *  GRUB is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  GRUB is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
  TODO:
  implement journal handling (ram replay)
  test tail packing & direct files
  validate partition label position
*/

#if 0
# define GRUB_REISERFS_DEBUG
# define GRUB_REISERFS_JOURNALING
# define GRUB_HEXDUMP
#endif

#include <grub/err.h>
#include <grub/file.h>
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/disk.h>
#include <grub/dl.h>
#include <grub/types.h>
#include <grub/fshelp.h>
#include <grub/i18n.h>

GRUB_MOD_LICENSE ("GPLv3+");

#define MIN(a, b) \
  ({ typeof (a) _a = (a); \
     typeof (b) _b = (b); \
     _a < _b ? _a : _b; })

#define MAX(a, b) \
  ({ typeof (a) _a = (a); \
     typeof (b) _b = (b); \
     _a > _b ? _a : _b; })

#define REISERFS_SUPER_BLOCK_OFFSET 0x10000
#define REISERFS_MAGIC_LEN 12
#define REISERFS_MAGIC_STRING "ReIsEr"
#define REISERFS_MAGIC_DESC_BLOCK "ReIsErLB"
/* If the 3rd bit of an item state is set, then it's visible.  */
#define GRUB_REISERFS_VISIBLE_MASK ((grub_uint16_t) 0x04)

#define S_IFLNK 0xA000

static grub_dl_t my_mod;

#define assert(boolean) real_assert (boolean, GRUB_FILE, __LINE__)
static inline void
real_assert (int boolean, const char *file, const int line)
{
  if (! boolean)
    grub_printf ("Assertion failed at %s:%d\n", file, line);
}

enum grub_reiserfs_item_type
  {
    GRUB_REISERFS_STAT,
    GRUB_REISERFS_DIRECTORY,
    GRUB_REISERFS_DIRECT,
    GRUB_REISERFS_INDIRECT,
    /* Matches both _DIRECT and _INDIRECT when searching.  */
    GRUB_REISERFS_ANY,
    GRUB_REISERFS_UNKNOWN
  };

struct grub_reiserfs_superblock
{
  grub_uint32_t block_count;
  grub_uint32_t block_free_count;
  grub_uint32_t root_block;
  grub_uint32_t journal_block;
  grub_uint32_t journal_device;
  grub_uint32_t journal_original_size;
  grub_uint32_t journal_max_transaction_size;
  grub_uint32_t journal_block_count;
  grub_uint32_t journal_max_batch;
  grub_uint32_t journal_max_commit_age;
  grub_uint32_t journal_max_transaction_age;
  grub_uint16_t block_size;
  grub_uint16_t oid_max_size;
  grub_uint16_t oid_current_size;
  grub_uint16_t state;
  grub_uint8_t magic_string[REISERFS_MAGIC_LEN];
  grub_uint32_t function_hash_code;
  grub_uint16_t tree_height;
  grub_uint16_t bitmap_number;
  grub_uint16_t version;
  grub_uint16_t reserved;
  grub_uint32_t inode_generation;
  grub_uint8_t unused[4];
  grub_uint16_t uuid[8];
  char label[16];
} GRUB_PACKED;

struct grub_reiserfs_journal_header
{
  grub_uint32_t last_flush_uid;
  grub_uint32_t unflushed_offset;
  grub_uint32_t mount_id;
} GRUB_PACKED;

struct grub_reiserfs_description_block
{
  grub_uint32_t id;
  grub_uint32_t len;
  grub_uint32_t mount_id;
  grub_uint32_t real_blocks[0];
} GRUB_PACKED;

struct grub_reiserfs_commit_block
{
  grub_uint32_t id;
  grub_uint32_t len;
  grub_uint32_t real_blocks[0];
} GRUB_PACKED;

struct grub_reiserfs_stat_item_v1
{
  grub_uint16_t mode;
  grub_uint16_t hardlink_count;
  grub_uint16_t uid;
  grub_uint16_t gid;
  grub_uint32_t size;
  grub_uint32_t atime;
  grub_uint32_t mtime;
  grub_uint32_t ctime;
  grub_uint32_t rdev;
  grub_uint32_t first_direct_byte;
} GRUB_PACKED;

struct grub_reiserfs_stat_item_v2
{
  grub_uint16_t mode;
  grub_uint16_t reserved;
  grub_uint32_t hardlink_count;
  grub_uint64_t size;
  grub_uint32_t uid;
  grub_uint32_t gid;
  grub_uint32_t atime;
  grub_uint32_t mtime;
  grub_uint32_t ctime;
  grub_uint32_t blocks;
  grub_uint32_t first_direct_byte;
} GRUB_PACKED;

struct grub_reiserfs_key
{
  grub_uint32_t directory_id;
  grub_uint32_t object_id;
  union
  {
    struct
    {
      grub_uint32_t offset;
      grub_uint32_t type;
    } GRUB_PACKED v1;
    struct
    {
      grub_uint64_t offset_type;
    } GRUB_PACKED v2;
  } u;
} GRUB_PACKED;

struct grub_reiserfs_item_header
{
  struct grub_reiserfs_key key;
  union
  {
    grub_uint16_t free_space;
    grub_uint16_t entry_count;
  } GRUB_PACKED u;
  grub_uint16_t item_size;
  grub_uint16_t item_location;
  grub_uint16_t version;
} GRUB_PACKED;

struct grub_reiserfs_block_header
{
  grub_uint16_t level;
  grub_uint16_t item_count;
  grub_uint16_t free_space;
  grub_uint16_t reserved;
  struct grub_reiserfs_key block_right_delimiting_key;
} GRUB_PACKED;

struct grub_reiserfs_disk_child
{
  grub_uint32_t block_number;
  grub_uint16_t size;
  grub_uint16_t reserved;
} GRUB_PACKED;

struct grub_reiserfs_directory_header
{
  grub_uint32_t offset;
  grub_uint32_t directory_id;
  grub_uint32_t object_id;
  grub_uint16_t location;
  grub_uint16_t state;
} GRUB_PACKED;

struct grub_fshelp_node
{
  struct grub_reiserfs_data *data;
  grub_uint32_t block_number; /* 0 if node is not found.  */
  grub_uint16_t block_position;
  grub_uint64_t next_offset;
  grub_int32_t mtime;
  grub_off_t size;
  enum grub_reiserfs_item_type type; /* To know how to read the header.  */
  struct grub_reiserfs_item_header header;
};

/* Returned when opening a file.  */
struct grub_reiserfs_data
{
  struct grub_reiserfs_superblock superblock;
  grub_disk_t disk;
};

static grub_ssize_t
grub_reiserfs_read_real (struct grub_fshelp_node *node,
			 grub_off_t off, char *buf, grub_size_t len,
			 grub_disk_read_hook_t read_hook,
			 void *read_hook_data);

/* Internal-only functions. Not to be used outside of this file.  */

/* Return the type of given v2 key.  */
static enum grub_reiserfs_item_type
grub_reiserfs_get_key_v2_type (const struct grub_reiserfs_key *key)
{
  switch (grub_le_to_cpu64 (key->u.v2.offset_type) >> 60)
    {
    case 0:
      return GRUB_REISERFS_STAT;
    case 15:
      return GRUB_REISERFS_ANY;
    case 3:
      return GRUB_REISERFS_DIRECTORY;
    case 2:
      return GRUB_REISERFS_DIRECT;
    case 1:
      return GRUB_REISERFS_INDIRECT;
    }
  return GRUB_REISERFS_UNKNOWN;
}

/* Return the type of given v1 key.  */
static enum grub_reiserfs_item_type
grub_reiserfs_get_key_v1_type (const struct grub_reiserfs_key *key)
{
  switch (grub_le_to_cpu32 (key->u.v1.type))
    {
    case 0:
      return GRUB_REISERFS_STAT;
    case 555:
      return GRUB_REISERFS_ANY;
    case 500:
      return GRUB_REISERFS_DIRECTORY;
    case 0x20000000:
    case 0xFFFFFFFF:
      return GRUB_REISERFS_DIRECT;
    case 0x10000000:
    case 0xFFFFFFFE:
      return GRUB_REISERFS_INDIRECT;
    }
  return GRUB_REISERFS_UNKNOWN;
}

/* Return 1 if the given key is version 1 key, 2 otherwise.  */
static int
grub_reiserfs_get_key_version (const struct grub_reiserfs_key *key)
{
  return grub_reiserfs_get_key_v1_type (key) == GRUB_REISERFS_UNKNOWN ? 2 : 1;
}

#ifdef GRUB_HEXDUMP
static void
grub_hexdump (char *buffer, grub_size_t len)
{
  grub_size_t a;
  for (a = 0; a < len; a++)
    {
      if (! (a & 0x0F))
        grub_printf ("\n%08x  ", a);
      grub_printf ("%02x ",
                   ((unsigned int) ((unsigned char *) buffer)[a]) & 0xFF);
    }
  grub_printf ("\n");
}
#endif

#ifdef GRUB_REISERFS_DEBUG
static grub_uint64_t
grub_reiserfs_get_key_offset (const struct grub_reiserfs_key *key);

static enum grub_reiserfs_item_type
grub_reiserfs_get_key_type (const struct grub_reiserfs_key *key);

static void
grub_reiserfs_print_key (const struct grub_reiserfs_key *key)
{
  unsigned int a;
  char *reiserfs_type_strings[] = {
    "stat     ",
    "directory",
    "direct   ",
    "indirect ",
    "any      ",
    "unknown  "
  };

  for (a = 0; a < sizeof (struct grub_reiserfs_key); a++)
    grub_printf ("%02x ", ((unsigned int) ((unsigned char *) key)[a]) & 0xFF);
  grub_printf ("parent id = 0x%08x, self id = 0x%08x, type = %s, offset = ",
               grub_le_to_cpu32 (key->directory_id),
               grub_le_to_cpu32 (key->object_id),
               reiserfs_type_strings [grub_reiserfs_get_key_type (key)]);
  if (grub_reiserfs_get_key_version (key) == 1)
    grub_printf("%08x", (unsigned int) grub_reiserfs_get_key_offset (key));
  else
    grub_printf("0x%07x%08x",
                (unsigned) (grub_reiserfs_get_key_offset (key) >> 32),
                (unsigned) (grub_reiserfs_get_key_offset (key) & 0xFFFFFFFF));
  grub_printf ("\n");
}
#endif

/* Return the offset of given key.  */
static grub_uint64_t
grub_reiserfs_get_key_offset (const struct grub_reiserfs_key *key)
{
  if (grub_reiserfs_get_key_version (key) == 1)
    return grub_le_to_cpu32 (key->u.v1.offset);
  else
    return grub_le_to_cpu64 (key->u.v2.offset_type) & (~0ULL >> 4);
}

/* Set the offset of given key.  */
static void
grub_reiserfs_set_key_offset (struct grub_reiserfs_key *key,
                              grub_uint64_t value)
{
  if (grub_reiserfs_get_key_version (key) == 1)
    key->u.v1.offset = grub_cpu_to_le32 (value);
  else
    key->u.v2.offset_type \
      = ((key->u.v2.offset_type & grub_cpu_to_le64_compile_time (15ULL << 60))
         | grub_cpu_to_le64 (value & (~0ULL >> 4)));
}

/* Return the type of given key.  */
static enum grub_reiserfs_item_type
grub_reiserfs_get_key_type (const struct grub_reiserfs_key *key)
{
  if (grub_reiserfs_get_key_version (key) == 1)
    return grub_reiserfs_get_key_v1_type (key);
  else
    return grub_reiserfs_get_key_v2_type (key);
}

/* Set the type of given key, with given version number.  */
static void
grub_reiserfs_set_key_type (struct grub_reiserfs_key *key,
                            enum grub_reiserfs_item_type grub_type,
                            int version)
{
  grub_uint32_t type;

  switch (grub_type)
    {
    case GRUB_REISERFS_STAT:
      type = 0;
      break;
    case GRUB_REISERFS_ANY:
      type = (version == 1) ? 555 : 15;
      break;
    case GRUB_REISERFS_DIRECTORY:
      type = (version == 1) ? 500 : 3;
      break;
    case GRUB_REISERFS_DIRECT:
      type = (version == 1) ? 0xFFFFFFFF : 2;
      break;
    case GRUB_REISERFS_INDIRECT:
      type = (version == 1) ? 0xFFFFFFFE : 1;
      break;
    default:
      return;
    }

  if (version == 1)
    key->u.v1.type = grub_cpu_to_le32 (type);
  else
    key->u.v2.offset_type
      = ((key->u.v2.offset_type & grub_cpu_to_le64_compile_time (~0ULL >> 4))
         | grub_cpu_to_le64 ((grub_uint64_t) type << 60));

  assert (grub_reiserfs_get_key_type (key) == grub_type);
}

/* -1 if key 1 if lower than key 2.
   0 if key 1 is equal to key 2.
   1 if key 1 is higher than key 2.  */
static int
grub_reiserfs_compare_keys (const struct grub_reiserfs_key *key1,
                            const struct grub_reiserfs_key *key2)
{
  grub_uint64_t offset1, offset2;
  enum grub_reiserfs_item_type type1, type2;
  grub_uint32_t id1, id2;

  if (! key1 || ! key2)
    return -2;

  id1 = grub_le_to_cpu32 (key1->directory_id);
  id2 = grub_le_to_cpu32 (key2->directory_id);
  if (id1 < id2)
    return -1;
  if (id1 > id2)
    return 1;

  id1 = grub_le_to_cpu32 (key1->object_id);
  id2 = grub_le_to_cpu32 (key2->object_id);
  if (id1 < id2)
    return -1;
  if (id1 > id2)
    return 1;

  offset1 = grub_reiserfs_get_key_offset (key1);
  offset2 = grub_reiserfs_get_key_offset (key2);
  if (offset1 < offset2)
    return -1;
  if (offset1 > offset2)
    return 1;

  type1 = grub_reiserfs_get_key_type (key1);
  type2 = grub_reiserfs_get_key_type (key2);
  if ((type1 == GRUB_REISERFS_ANY
       && (type2 == GRUB_REISERFS_DIRECT
           || type2 == GRUB_REISERFS_INDIRECT))
      || (type2 == GRUB_REISERFS_ANY
          && (type1 == GRUB_REISERFS_DIRECT
              || type1 == GRUB_REISERFS_INDIRECT)))
    return 0;
  if (type1 < type2)
    return -1;
  if (type1 > type2)
    return 1;

  return 0;
}

/* Find the item identified by KEY in mounted filesystem DATA, and fill ITEM
   accordingly to what was found.  */
static grub_err_t
grub_reiserfs_get_item (struct grub_reiserfs_data *data,
                        const struct grub_reiserfs_key *key,
                        struct grub_fshelp_node *item, int exact)
{
  grub_uint32_t block_number;
  struct grub_reiserfs_block_header *block_header = 0;
  struct grub_reiserfs_key *block_key = 0;
  grub_uint16_t block_size, item_count, current_level;
  grub_uint16_t i;
  grub_uint16_t previous_level = ~0;
  struct grub_reiserfs_item_header *item_headers = 0;

#if 0
  if (! data)
    {
      grub_error (GRUB_ERR_BAD_FS, "data is NULL");
      goto fail;
    }

  if (! key)
    {
      grub_error (GRUB_ERR_BAD_FS, "key is NULL");
      goto fail;
    }

  if (! item)
    {
      grub_error (GRUB_ERR_BAD_FS, "item is NULL");
      goto fail;
    }
#endif

  block_size = grub_le_to_cpu16 (data->superblock.block_size);
  block_number = grub_le_to_cpu32 (data->superblock.root_block);
#ifdef GRUB_REISERFS_DEBUG
  grub_printf("Searching for ");
  grub_reiserfs_print_key (key);
#endif
  block_header = grub_malloc (block_size);
  if (! block_header)
    goto fail;

  item->next_offset = 0;
  do
    {
      grub_disk_read (data->disk,
                      block_number * (block_size >> GRUB_DISK_SECTOR_BITS),
                      (((grub_off_t) block_number * block_size)
                       & (GRUB_DISK_SECTOR_SIZE - 1)),
                      block_size, block_header);
      if (grub_errno)
        goto fail;
      current_level = grub_le_to_cpu16 (block_header->level);
      grub_dprintf ("reiserfs_tree", " at level %d\n", current_level);
      if (current_level >= previous_level)
        {
          grub_dprintf ("reiserfs_tree", "level loop detected, aborting\n");
          grub_error (GRUB_ERR_BAD_FS, "level loop");
          goto fail;
        }
      previous_level = current_level;
      item_count = grub_le_to_cpu16 (block_header->item_count);
      grub_dprintf ("reiserfs_tree", " number of contained items : %d\n",
                    item_count);
      if (current_level > 1)
        {
          /* Internal node. Navigate to the child that should contain
             the searched key.  */
          struct grub_reiserfs_key *keys
            = (struct grub_reiserfs_key *) (block_header + 1);
          struct grub_reiserfs_disk_child *children
            = ((struct grub_reiserfs_disk_child *)
               (keys + item_count));

          for (i = 0;
               i < item_count
                 && grub_reiserfs_compare_keys (key, &(keys[i])) >= 0;
               i++)
            {
#ifdef GRUB_REISERFS_DEBUG
              grub_printf("i %03d/%03d ", i + 1, item_count + 1);
              grub_reiserfs_print_key (&(keys[i]));
#endif
            }
          block_number = grub_le_to_cpu32 (children[i].block_number);
	  if ((i < item_count) && (key->directory_id == keys[i].directory_id)
	       && (key->object_id == keys[i].object_id))
	    item->next_offset = grub_reiserfs_get_key_offset(&(keys[i]));
#ifdef GRUB_REISERFS_DEBUG
          if (i == item_count
              || grub_reiserfs_compare_keys (key, &(keys[i])) == 0)
            grub_printf(">");
          else
            grub_printf("<");
          if (i < item_count)
            {
              grub_printf (" %03d/%03d ", i + 1, item_count + 1);
              grub_reiserfs_print_key (&(keys[i]));
              if (i + 1 < item_count)
                {
                  grub_printf ("+ %03d/%03d ", i + 2, item_count);
                  grub_reiserfs_print_key (&(keys[i + 1]));
                }
            }
          else
            grub_printf ("Accessing rightmost child at block %d.\n",
                         block_number);
#endif
        }
      else
        {
          /* Leaf node.  Check that the key is actually present.  */
          item_headers
            = (struct grub_reiserfs_item_header *) (block_header + 1);
          for (i = 0;
               i < item_count;
               i++)
	    {
	      int val;
	      val = grub_reiserfs_compare_keys (key, &(item_headers[i].key));
	      if (val == 0)
		{
		  block_key = &(item_headers[i].key);
		  break;
		}
	      if (val < 0 && exact)
		break;
	      if (val < 0)
		{
		  if (i == 0)
		    {
		      grub_error (GRUB_ERR_READ_ERROR, "unexpected btree node");
		      goto fail;
		    }
		  i--;
		  block_key = &(item_headers[i].key);
		  break;
		}
	    }
	  if (!exact && i == item_count)
	    {
	      if (i == 0)
		{
		  grub_error (GRUB_ERR_READ_ERROR, "unexpected btree node");
		  goto fail;
		}
	      i--;
	      block_key = &(item_headers[i].key);
	    }
        }
    }
  while (current_level > 1);

  item->data = data;

  if (!block_key)
    {
      item->block_number = 0;
      item->block_position = 0;
      item->type = GRUB_REISERFS_UNKNOWN;
#ifdef GRUB_REISERFS_DEBUG
      grub_printf("Not found.\n");
#endif
    }
  else
    {
      item->block_number = block_number;
      item->block_position = i;
      item->type = grub_reiserfs_get_key_type (block_key);
      grub_memcpy (&(item->header), &(item_headers[i]),
                   sizeof (struct grub_reiserfs_item_header));
#ifdef GRUB_REISERFS_DEBUG
      grub_printf ("F %03d/%03d ", i + 1, item_count);
      grub_reiserfs_print_key (block_key);
#endif
    }

  assert (grub_errno == GRUB_ERR_NONE);
  grub_free (block_header);
  return GRUB_ERR_NONE;

 fail:
  assert (grub_errno != GRUB_ERR_NONE);
  grub_free (block_header);
  assert (grub_errno != GRUB_ERR_NONE);
  return grub_errno;
}

/* Return the path of the file which is pointed at by symlink NODE.  */
static char *
grub_reiserfs_read_symlink (grub_fshelp_node_t node)
{
  char *symlink_buffer = 0;
  grub_size_t len = node->size;
  grub_ssize_t ret;

  symlink_buffer = grub_malloc (len + 1);
  if (! symlink_buffer)
    return 0;

  ret = grub_reiserfs_read_real (node, 0, symlink_buffer, len, 0, 0);
  if (ret < 0)
    {
      grub_free (symlink_buffer);
      return 0;
    }

  symlink_buffer[ret] = 0;
  return symlink_buffer;
}

/* Fill the mounted filesystem structure and return it.  */
static struct grub_reiserfs_data *
grub_reiserfs_mount (grub_disk_t disk)
{
  struct grub_reiserfs_data *data = 0;
  data = grub_malloc (sizeof (*data));
  if (! data)
    goto fail;
  grub_disk_read (disk, REISERFS_SUPER_BLOCK_OFFSET / GRUB_DISK_SECTOR_SIZE,
                  0, sizeof (data->superblock), &(data->superblock));
  if (grub_errno)
    goto fail;
  if (grub_memcmp (data->superblock.magic_string,
                   REISERFS_MAGIC_STRING, sizeof (REISERFS_MAGIC_STRING) - 1))
    {
      grub_error (GRUB_ERR_BAD_FS, "not a ReiserFS filesystem");
      goto fail;
    }
  data->disk = disk;
  return data;

 fail:
  /* Disk is too small to contain a ReiserFS.  */
  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
    grub_error (GRUB_ERR_BAD_FS, "not a ReiserFS filesystem");

  grub_free (data);
  return 0;
}

/* Call HOOK for each file in directory ITEM.  */
static int
grub_reiserfs_iterate_dir (grub_fshelp_node_t item,
                           grub_fshelp_iterate_dir_hook_t hook,
			   void *hook_data)
{
  struct grub_reiserfs_data *data = item->data;
  struct grub_reiserfs_block_header *block_header = 0;
  grub_uint16_t block_size, block_position;
  grub_uint32_t block_number;
  grub_uint64_t next_offset = item->next_offset;
  int ret = 0;

  if (item->type != GRUB_REISERFS_DIRECTORY)
    {
      grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
      goto fail;
    }
  block_size = grub_le_to_cpu16 (data->superblock.block_size);
  block_header = grub_malloc (block_size + 1);
  if (! block_header)
    goto fail;
  block_number = item->block_number;
  block_position = item->block_position;
  grub_dprintf ("reiserfs", "Iterating directory...\n");
  do
    {
      struct grub_reiserfs_directory_header *directory_headers;
      struct grub_fshelp_node directory_item;
      grub_uint16_t entry_count, entry_number;
      struct grub_reiserfs_item_header *item_headers;

      grub_disk_read (data->disk,
                      block_number * (block_size >> GRUB_DISK_SECTOR_BITS),
                      (((grub_off_t) block_number * block_size)
                       & (GRUB_DISK_SECTOR_SIZE - 1)),
                      block_size, (char *) block_header);
      if (grub_errno)
        goto fail;

      ((char *) block_header)[block_size] = 0;

#if 0
      if (grub_le_to_cpu16 (block_header->level) != 1)
        {
          grub_error (GRUB_ERR_BAD_FS,
                      "reiserfs: block %d is not a leaf block",
                      block_number);
          goto fail;
        }
#endif

      item_headers = (struct grub_reiserfs_item_header *) (block_header + 1);
      directory_headers
        = ((struct grub_reiserfs_directory_header *)
           ((char *) block_header
            + grub_le_to_cpu16 (item_headers[block_position].item_location)));
      entry_count
        = grub_le_to_cpu16 (item_headers[block_position].u.entry_count);
      for (entry_number = 0; entry_number < entry_count; entry_number++)
        {
          struct grub_reiserfs_directory_header *directory_header
            = &directory_headers[entry_number];
          grub_uint16_t entry_state
            = grub_le_to_cpu16 (directory_header->state);
	  grub_fshelp_node_t entry_item;
	  struct grub_reiserfs_key entry_key;
	  enum grub_fshelp_filetype entry_type;
	  char *entry_name;
	  char *entry_name_end = 0;
	  char c;
	  
          if (!(entry_state & GRUB_REISERFS_VISIBLE_MASK))
	    continue;

	  entry_name = (((char *) directory_headers)
			+ grub_le_to_cpu16 (directory_header->location));
	  if (entry_number == 0)
	    {
	      entry_name_end = (char *) block_header
		+ grub_le_to_cpu16 (item_headers[block_position].item_location)
		+ grub_le_to_cpu16 (item_headers[block_position].item_size);
	    }
	  else
	    {
	      entry_name_end = (((char *) directory_headers)
			+ grub_le_to_cpu16 (directory_headers[entry_number - 1].location));
	    }
	  if (entry_name_end < entry_name || entry_name_end > (char *) block_header + block_size)
	    {
	      entry_name_end = (char *) block_header + block_size;
	    }

	  entry_key.directory_id = directory_header->directory_id;
	  entry_key.object_id = directory_header->object_id;
	  entry_key.u.v2.offset_type = 0;
	  grub_reiserfs_set_key_type (&entry_key, GRUB_REISERFS_DIRECTORY,
				      2);
	  grub_reiserfs_set_key_offset (&entry_key, 1);

	  entry_item = grub_malloc (sizeof (*entry_item));
	  if (! entry_item)
	    goto fail;

	  if (grub_reiserfs_get_item (data, &entry_key, entry_item, 1)
	      != GRUB_ERR_NONE)
	    {
	      grub_free (entry_item);
	      goto fail;
	    }

	  if (entry_item->type == GRUB_REISERFS_DIRECTORY)
	    entry_type = GRUB_FSHELP_DIR;
	  else
	    {
	      grub_uint32_t entry_block_number;
	      /* Order is very important here.
		 First set the offset to 0 using current key version.
		 Then change the key type, which affects key version
		 detection.  */
	      grub_reiserfs_set_key_offset (&entry_key, 0);
	      grub_reiserfs_set_key_type (&entry_key, GRUB_REISERFS_STAT,
					  2);
	      if (grub_reiserfs_get_item (data, &entry_key, entry_item, 1)
		  != GRUB_ERR_NONE)
		{
		  grub_free (entry_item);
		  goto fail;
		}

	      if (entry_item->block_number != 0)
		{
		  grub_uint16_t entry_version;
		  entry_version
		    = grub_le_to_cpu16 (entry_item->header.version);
		  entry_block_number = entry_item->block_number;
#if 0
		  grub_dprintf ("reiserfs",
				"version %04x block %08x (%08x) position %08x\n",
				entry_version, entry_block_number,
				((grub_disk_addr_t) entry_block_number * block_size) / GRUB_DISK_SECTOR_SIZE,
				grub_le_to_cpu16 (entry_item->header.item_location));
#endif
		  if (entry_version == 0) /* Version 1 stat item. */
		    {
		      struct grub_reiserfs_stat_item_v1 entry_v1_stat;
		      grub_disk_read (data->disk,
				      entry_block_number * (block_size >> GRUB_DISK_SECTOR_BITS),
				      grub_le_to_cpu16 (entry_item->header.item_location),
				      sizeof (entry_v1_stat),
				      (char *) &entry_v1_stat);
		      if (grub_errno)
			goto fail;
#if 0
		      grub_dprintf ("reiserfs",
				    "%04x %04x %04x %04x %08x %08x | %08x %08x %08x %08x\n",
				    grub_le_to_cpu16 (entry_v1_stat.mode),
				    grub_le_to_cpu16 (entry_v1_stat.hardlink_count),
				    grub_le_to_cpu16 (entry_v1_stat.uid),
				    grub_le_to_cpu16 (entry_v1_stat.gid),
				    grub_le_to_cpu32 (entry_v1_stat.size),
				    grub_le_to_cpu32 (entry_v1_stat.atime),
				    grub_le_to_cpu32 (entry_v1_stat.mtime),
				    grub_le_to_cpu32 (entry_v1_stat.ctime),
				    grub_le_to_cpu32 (entry_v1_stat.rdev),
				    grub_le_to_cpu32 (entry_v1_stat.first_direct_byte));
		      grub_dprintf ("reiserfs",
				    "%04x %04x %04x %04x %08x %08x | %08x %08x %08x %08x\n",
				    entry_v1_stat.mode,
				    entry_v1_stat.hardlink_count,
				    entry_v1_stat.uid,
				    entry_v1_stat.gid,
				    entry_v1_stat.size,
				    entry_v1_stat.atime,
				    entry_v1_stat.mtime,
				    entry_v1_stat.ctime,
				    entry_v1_stat.rdev,
				    entry_v1_stat.first_direct_byte);
#endif
		      entry_item->mtime = grub_le_to_cpu32 (entry_v1_stat.mtime);
		      if ((grub_le_to_cpu16 (entry_v1_stat.mode) & S_IFLNK)
			  == S_IFLNK)
			entry_type = GRUB_FSHELP_SYMLINK;
		      else
			entry_type = GRUB_FSHELP_REG;
		      entry_item->size = (grub_off_t) grub_le_to_cpu32 (entry_v1_stat.size);
		    }
		  else
		    {
		      struct grub_reiserfs_stat_item_v2 entry_v2_stat;
		      grub_disk_read (data->disk,
				      entry_block_number * (block_size >> GRUB_DISK_SECTOR_BITS),
				      grub_le_to_cpu16 (entry_item->header.item_location),
				      sizeof (entry_v2_stat),
				      (char *) &entry_v2_stat);
		      if (grub_errno)
			goto fail;
#if 0
		      grub_dprintf ("reiserfs",
				    "%04x %04x %08x %08x%08x | %08x %08x %08x %08x | %08x %08x %08x\n",
				    grub_le_to_cpu16 (entry_v2_stat.mode),
				    grub_le_to_cpu16 (entry_v2_stat.reserved),
				    grub_le_to_cpu32 (entry_v2_stat.hardlink_count),
				    (unsigned int) (grub_le_to_cpu64 (entry_v2_stat.size) >> 32),
				    (unsigned int) (grub_le_to_cpu64 (entry_v2_stat.size) && 0xFFFFFFFF),
				    grub_le_to_cpu32 (entry_v2_stat.uid),
				    grub_le_to_cpu32 (entry_v2_stat.gid),
				    grub_le_to_cpu32 (entry_v2_stat.atime),
				    grub_le_to_cpu32 (entry_v2_stat.mtime),
				    grub_le_to_cpu32 (entry_v2_stat.ctime),
				    grub_le_to_cpu32 (entry_v2_stat.blocks),
				    grub_le_to_cpu32 (entry_v2_stat.first_direct_byte));
		      grub_dprintf ("reiserfs",
				    "%04x %04x %08x %08x%08x | %08x %08x %08x %08x | %08x %08x %08x\n",
				    entry_v2_stat.mode,
				    entry_v2_stat.reserved,
				    entry_v2_stat.hardlink_count,
				    (unsigned int) (entry_v2_stat.size >> 32),
				    (unsigned int) (entry_v2_stat.size && 0xFFFFFFFF),
				    entry_v2_stat.uid,
				    entry_v2_stat.gid,
				    entry_v2_stat.atime,
				    entry_v2_stat.mtime,
				    entry_v2_stat.ctime,
				    entry_v2_stat.blocks,
				    entry_v2_stat.first_direct_byte);
#endif
		      entry_item->mtime = grub_le_to_cpu32 (entry_v2_stat.mtime);
		      entry_item->size = (grub_off_t) grub_le_to_cpu64 (entry_v2_stat.size);
		      if ((grub_le_to_cpu16 (entry_v2_stat.mode) & S_IFLNK)
			  == S_IFLNK)
			entry_type = GRUB_FSHELP_SYMLINK;
		      else
			entry_type = GRUB_FSHELP_REG;
		    }
		}
	      else
		{
		  /* Pseudo file ".." never has stat block.  */
		  if (entry_name_end == entry_name + 2 && grub_memcmp (entry_name, "..", 2) != 0)
		    grub_dprintf ("reiserfs",
				  "Warning : %s has no stat block !\n",
				  entry_name);
		  grub_free (entry_item);
		  goto next;
		}
	    }

	  c = *entry_name_end;
	  *entry_name_end = 0;
	  if (hook (entry_name, entry_type, entry_item, hook_data))
	    {
	      *entry_name_end = c;
	      grub_dprintf ("reiserfs", "Found : %s, type=%d\n",
			    entry_name, entry_type);
	      ret = 1;
	      goto found;
	    }
	  *entry_name_end = c;

	next:
	  ;
        }

      if (next_offset == 0)
        break;

      grub_reiserfs_set_key_offset (&(item_headers[block_position].key),
                                    next_offset);
      if (grub_reiserfs_get_item (data, &(item_headers[block_position].key),
                                  &directory_item, 1) != GRUB_ERR_NONE)
        goto fail;
      block_number = directory_item.block_number;
      block_position = directory_item.block_position;
      next_offset = directory_item.next_offset;
    }
  while (block_number);

 found:
  assert (grub_errno == GRUB_ERR_NONE);
  grub_free (block_header);
  return ret;
 fail:
  assert (grub_errno != GRUB_ERR_NONE);
  grub_free (block_header);
  return 0;
}

/****************************************************************************/
/* grub api functions */
/****************************************************************************/

/* Open a file named NAME and initialize FILE.  */
static grub_err_t
grub_reiserfs_open (struct grub_file *file, const char *name)
{
  struct grub_reiserfs_data *data = 0;
  struct grub_fshelp_node root, *found = 0;
  struct grub_reiserfs_key key;

  grub_dl_ref (my_mod);
  data = grub_reiserfs_mount (file->device->disk);
  if (! data)
    goto fail;
  key.directory_id = grub_cpu_to_le32_compile_time (1);
  key.object_id = grub_cpu_to_le32_compile_time (2);
  key.u.v2.offset_type = 0;
  grub_reiserfs_set_key_type (&key, GRUB_REISERFS_DIRECTORY, 2);
  grub_reiserfs_set_key_offset (&key, 1);
  if (grub_reiserfs_get_item (data, &key, &root, 1) != GRUB_ERR_NONE)
    goto fail;
  if (root.block_number == 0)
    {
      grub_error (GRUB_ERR_BAD_FS, "unable to find root item");
      goto fail; /* Should never happen since checked at mount.  */
    }
  grub_fshelp_find_file (name, &root, &found,
                         grub_reiserfs_iterate_dir,
                         grub_reiserfs_read_symlink, GRUB_FSHELP_REG);
  if (grub_errno)
    goto fail;
  file->size = found->size;

  grub_dprintf ("reiserfs", "file size : %d (%08x%08x)\n",
                (unsigned int) file->size,
                (unsigned int) (file->size >> 32), (unsigned int) file->size);
  file->offset = 0;
  file->data = found;
  return GRUB_ERR_NONE;

 fail:
  assert (grub_errno != GRUB_ERR_NONE);
  if (found != &root)
    grub_free (found);
  grub_free (data);
  grub_dl_unref (my_mod);
  return grub_errno;
}

static grub_ssize_t
grub_reiserfs_read_real (struct grub_fshelp_node *node,
			 grub_off_t off, char *buf, grub_size_t len,
			 grub_disk_read_hook_t read_hook, void *read_hook_data)
{
  unsigned int indirect_block, indirect_block_count;
  struct grub_reiserfs_key key;
  struct grub_reiserfs_data *data = node->data;
  struct grub_fshelp_node found;
  grub_uint16_t block_size = grub_le_to_cpu16 (data->superblock.block_size);
  grub_uint16_t item_size;
  grub_uint32_t *indirect_block_ptr = 0;
  grub_uint64_t current_key_offset = 1;
  grub_off_t initial_position, current_position, final_position, length;
  grub_disk_addr_t block;
  grub_off_t offset;

  key.directory_id = node->header.key.directory_id;
  key.object_id = node->header.key.object_id;
  key.u.v2.offset_type = 0;
  grub_reiserfs_set_key_type (&key, GRUB_REISERFS_ANY, 2);
  initial_position = off;
  current_position = 0;
  final_position = MIN (len + initial_position, node->size);
  grub_dprintf ("reiserfs",
		"Reading from %lld to %lld (%lld instead of requested %ld)\n",
		(unsigned long long) initial_position,
		(unsigned long long) final_position,
		(unsigned long long) (final_position - initial_position),
		(unsigned long) len);

  grub_reiserfs_set_key_offset (&key, initial_position + 1);

  if (grub_reiserfs_get_item (data, &key, &found, 0) != GRUB_ERR_NONE)
    goto fail;

  if (found.block_number == 0)
    {
      grub_error (GRUB_ERR_READ_ERROR, "offset %lld not found",
		  (unsigned long long) initial_position);
      goto fail;
    }

  current_key_offset = grub_reiserfs_get_key_offset (&found.header.key);
  current_position = current_key_offset - 1;

  while (current_position < final_position)
    {
      grub_reiserfs_set_key_offset (&key, current_key_offset);

      if (grub_reiserfs_get_item (data, &key, &found, 1) != GRUB_ERR_NONE)
        goto fail;
      if (found.block_number == 0)
        goto fail;
      item_size = grub_le_to_cpu16 (found.header.item_size);
      switch (found.type)
        {
        case GRUB_REISERFS_DIRECT:
          block = ((grub_disk_addr_t) found.block_number) * (block_size  >> GRUB_DISK_SECTOR_BITS);
          grub_dprintf ("reiserfs_blocktype", "D: %u\n", (unsigned) block);
          if (initial_position < current_position + item_size)
            {
              offset = MAX ((signed) (initial_position - current_position), 0);
              length = (MIN (item_size, final_position - current_position)
                        - offset);
              grub_dprintf ("reiserfs",
                            "Reading direct block %u from %u to %u...\n",
                            (unsigned) block, (unsigned) offset,
                            (unsigned) (offset + length));
              found.data->disk->read_hook = read_hook;
              found.data->disk->read_hook_data = read_hook_data;
              grub_disk_read (found.data->disk,
                              block,
                              offset
                              + grub_le_to_cpu16 (found.header.item_location),
                              length, buf);
              found.data->disk->read_hook = 0;
              if (grub_errno)
                goto fail;
              buf += length;
              current_position += offset + length;
            }
          else
            current_position += item_size;
          break;
        case GRUB_REISERFS_INDIRECT:
          indirect_block_count = item_size / sizeof (*indirect_block_ptr);
          indirect_block_ptr = grub_malloc (item_size);
          if (! indirect_block_ptr)
            goto fail;
          grub_disk_read (found.data->disk,
                          found.block_number * (block_size >> GRUB_DISK_SECTOR_BITS),
                          grub_le_to_cpu16 (found.header.item_location),
                          item_size, indirect_block_ptr);
          if (grub_errno)
            goto fail;
          found.data->disk->read_hook = read_hook;
          found.data->disk->read_hook_data = read_hook_data;
          for (indirect_block = 0;
               indirect_block < indirect_block_count
                 && current_position < final_position;
               indirect_block++)
            {
              block = grub_le_to_cpu32 (indirect_block_ptr[indirect_block]) *
                      (block_size >> GRUB_DISK_SECTOR_BITS);
              grub_dprintf ("reiserfs_blocktype", "I: %u\n", (unsigned) block);
              if (current_position + block_size >= initial_position)
                {
                  offset = MAX ((signed) (initial_position - current_position),
                                0);
                  length = (MIN (block_size, final_position - current_position)
                            - offset);
                  grub_dprintf ("reiserfs",
                                "Reading indirect block %u from %u to %u...\n",
                                (unsigned) block, (unsigned) offset,
                                (unsigned) (offset + length));
#if 0
                  grub_dprintf ("reiserfs",
                                "\nib=%04d/%04d, ip=%d, cp=%d, fp=%d, off=%d, l=%d, tl=%d\n",
                                indirect_block + 1, indirect_block_count,
                                initial_position, current_position,
                                final_position, offset, length, len);
#endif
                  grub_disk_read (found.data->disk, block, offset, length, buf);
                  if (grub_errno)
                    goto fail;
                  buf += length;
                  current_position += offset + length;
                }
              else
                current_position += block_size;
            }
          found.data->disk->read_hook = 0;
          grub_free (indirect_block_ptr);
          indirect_block_ptr = 0;
          break;
        default:
          goto fail;
        }
      current_key_offset = current_position + 1;
    }

  grub_dprintf ("reiserfs",
		"Have successfully read %lld bytes (%ld requested)\n",
		(unsigned long long) (current_position - initial_position),
		(unsigned long) len);
  return current_position - initial_position;

#if 0
  switch (found.type)
    {
      case GRUB_REISERFS_DIRECT:
        read_length = MIN (len, item_size - file->offset);
        grub_disk_read (found.data->disk,
                        (found.block_number * block_size) / GRUB_DISK_SECTOR_SIZE,
                        grub_le_to_cpu16 (found.header.item_location) + file->offset,
                        read_length, buf);
        if (grub_errno)
          goto fail;
        break;
      case GRUB_REISERFS_INDIRECT:
        indirect_block_count = item_size / sizeof (*indirect_block_ptr);
        indirect_block_ptr = grub_malloc (item_size);
        if (!indirect_block_ptr)
          goto fail;
        grub_disk_read (found.data->disk,
                        (found.block_number * block_size) / GRUB_DISK_SECTOR_SIZE,
                        grub_le_to_cpu16 (found.header.item_location),
                        item_size, (char *) indirect_block_ptr);
        if (grub_errno)
          goto fail;
        len = MIN (len, file->size - file->offset);
        for (indirect_block = file->offset / block_size;
             indirect_block < indirect_block_count && read_length < len;
             indirect_block++)
          {
            read = MIN (block_size, len - read_length);
            grub_disk_read (found.data->disk,
                            (grub_le_to_cpu32 (indirect_block_ptr[indirect_block]) * block_size) / GRUB_DISK_SECTOR_SIZE,
                            file->offset % block_size, read,
                            ((void *) buf) + read_length);
            if (grub_errno)
              goto fail;
            read_length += read;
          }
        grub_free (indirect_block_ptr);
        break;
      default:
        goto fail;
    }

  return read_length;
#endif

 fail:
  grub_free (indirect_block_ptr);
  return -1;
}

static grub_ssize_t
grub_reiserfs_read (grub_file_t file, char *buf, grub_size_t len)
{
  return grub_reiserfs_read_real (file->data, file->offset, buf, len,
				  file->read_hook, file->read_hook_data);
}

/* Close the file FILE.  */
static grub_err_t
grub_reiserfs_close (grub_file_t file)
{
  struct grub_fshelp_node *node = file->data;
  struct grub_reiserfs_data *data = node->data;

  grub_free (data);
  grub_free (node);
  grub_dl_unref (my_mod);
  return GRUB_ERR_NONE;
}

/* Context for grub_reiserfs_dir.  */
struct grub_reiserfs_dir_ctx
{
  grub_fs_dir_hook_t hook;
  void *hook_data;
};

/* Helper for grub_reiserfs_dir.  */
static int
grub_reiserfs_dir_iter (const char *filename,
			enum grub_fshelp_filetype filetype,
			grub_fshelp_node_t node, void *data)
{
  struct grub_reiserfs_dir_ctx *ctx = data;
  struct grub_dirhook_info info;

  grub_memset (&info, 0, sizeof (info));
  info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
  info.mtimeset = 1;
  info.mtime = node->mtime;
  grub_free (node);
  return ctx->hook (filename, &info, ctx->hook_data);
}

/* Call HOOK with each file under DIR.  */
static grub_err_t
grub_reiserfs_dir (grub_device_t device, const char *path,
                   grub_fs_dir_hook_t hook, void *hook_data)
{
  struct grub_reiserfs_dir_ctx ctx = { hook, hook_data };
  struct grub_reiserfs_data *data = 0;
  struct grub_fshelp_node root, *found;
  struct grub_reiserfs_key root_key;

  grub_dl_ref (my_mod);
  data = grub_reiserfs_mount (device->disk);
  if (! data)
    goto fail;
  root_key.directory_id = grub_cpu_to_le32_compile_time (1);
  root_key.object_id = grub_cpu_to_le32_compile_time (2);
  root_key.u.v2.offset_type = 0;
  grub_reiserfs_set_key_type (&root_key, GRUB_REISERFS_DIRECTORY, 2);
  grub_reiserfs_set_key_offset (&root_key, 1);
  if (grub_reiserfs_get_item (data, &root_key, &root, 1) != GRUB_ERR_NONE)
    goto fail;
  if (root.block_number == 0)
    {
      grub_error(GRUB_ERR_BAD_FS, "root not found");
      goto fail;
    }
  grub_fshelp_find_file (path, &root, &found, grub_reiserfs_iterate_dir,
                         grub_reiserfs_read_symlink, GRUB_FSHELP_DIR);
  if (grub_errno)
    goto fail;
  grub_reiserfs_iterate_dir (found, grub_reiserfs_dir_iter, &ctx);
  grub_free (data);
  grub_dl_unref (my_mod);
  return GRUB_ERR_NONE;

 fail:
  grub_free (data);
  grub_dl_unref (my_mod);
  return grub_errno;
}

/* Return the label of the device DEVICE in LABEL.  The label is
   returned in a grub_malloc'ed buffer and should be freed by the
   caller.  */
static grub_err_t
grub_reiserfs_label (grub_device_t device, char **label)
{
  struct grub_reiserfs_data *data;
  grub_disk_t disk = device->disk;

  grub_dl_ref (my_mod);

  data = grub_reiserfs_mount (disk);
  if (data)
    {
      *label = grub_strndup (data->superblock.label,
			     sizeof (data->superblock.label));
    }
  else
    *label = NULL;

  grub_dl_unref (my_mod);

  grub_free (data);

  return grub_errno;
}

static grub_err_t
grub_reiserfs_uuid (grub_device_t device, char **uuid)
{
  struct grub_reiserfs_data *data;
  grub_disk_t disk = device->disk;

  grub_dl_ref (my_mod);

  *uuid = NULL;
  data = grub_reiserfs_mount (disk);
  if (data)
    {
      unsigned i;
      for (i = 0; i < ARRAY_SIZE (data->superblock.uuid); i++)
	if (data->superblock.uuid[i])
	  break;
      if (i < ARRAY_SIZE (data->superblock.uuid))
	*uuid = grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x",
				grub_be_to_cpu16 (data->superblock.uuid[0]),
				grub_be_to_cpu16 (data->superblock.uuid[1]),
				grub_be_to_cpu16 (data->superblock.uuid[2]),
				grub_be_to_cpu16 (data->superblock.uuid[3]),
				grub_be_to_cpu16 (data->superblock.uuid[4]),
				grub_be_to_cpu16 (data->superblock.uuid[5]),
				grub_be_to_cpu16 (data->superblock.uuid[6]),
				grub_be_to_cpu16 (data->superblock.uuid[7]));
    }

  grub_dl_unref (my_mod);

  grub_free (data);

  return grub_errno;
}

static struct grub_fs grub_reiserfs_fs =
  {
    .name = "reiserfs",
    .dir = grub_reiserfs_dir,
    .open = grub_reiserfs_open,
    .read = grub_reiserfs_read,
    .close = grub_reiserfs_close,
    .label = grub_reiserfs_label,
    .uuid = grub_reiserfs_uuid,
#ifdef GRUB_UTIL
    .reserved_first_sector = 1,
    .blocklist_install = 1,
#endif
    .next = 0
  };

GRUB_MOD_INIT(reiserfs)
{
  grub_fs_register (&grub_reiserfs_fs);
  my_mod = mod;
}

GRUB_MOD_FINI(reiserfs)
{
  grub_fs_unregister (&grub_reiserfs_fs);
}
