/* xfs.c - XFS.  */
/*
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 2005,2006,2007,2008,2009  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/>.
 */

#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>

GRUB_MOD_LICENSE ("GPLv3+");

#define	XFS_INODE_EXTENTS	9

#define XFS_INODE_FORMAT_INO	1
#define XFS_INODE_FORMAT_EXT	2
#define XFS_INODE_FORMAT_BTREE	3

/* Superblock version field flags */
#define XFS_SB_VERSION_NUMBITS		0x000f
#define	XFS_SB_VERSION_ATTRBIT		0x0010
#define	XFS_SB_VERSION_NLINKBIT		0x0020
#define	XFS_SB_VERSION_QUOTABIT		0x0040
#define	XFS_SB_VERSION_ALIGNBIT		0x0080
#define	XFS_SB_VERSION_DALIGNBIT	0x0100
#define	XFS_SB_VERSION_LOGV2BIT		0x0400
#define	XFS_SB_VERSION_SECTORBIT	0x0800
#define	XFS_SB_VERSION_EXTFLGBIT	0x1000
#define	XFS_SB_VERSION_DIRV2BIT		0x2000
#define XFS_SB_VERSION_MOREBITSBIT	0x8000
#define XFS_SB_VERSION_BITS_SUPPORTED \
	(XFS_SB_VERSION_NUMBITS | \
	 XFS_SB_VERSION_ATTRBIT | \
	 XFS_SB_VERSION_NLINKBIT | \
	 XFS_SB_VERSION_QUOTABIT | \
	 XFS_SB_VERSION_ALIGNBIT | \
	 XFS_SB_VERSION_DALIGNBIT | \
	 XFS_SB_VERSION_LOGV2BIT | \
	 XFS_SB_VERSION_SECTORBIT | \
	 XFS_SB_VERSION_EXTFLGBIT | \
	 XFS_SB_VERSION_DIRV2BIT | \
	 XFS_SB_VERSION_MOREBITSBIT)

/* Recognized xfs format versions */
#define XFS_SB_VERSION_4		4	/* Good old XFS filesystem */
#define XFS_SB_VERSION_5		5	/* CRC enabled filesystem */

/* features2 field flags */
#define XFS_SB_VERSION2_LAZYSBCOUNTBIT	0x00000002	/* Superblk counters */
#define XFS_SB_VERSION2_ATTR2BIT	0x00000008	/* Inline attr rework */
#define XFS_SB_VERSION2_PROJID32BIT	0x00000080	/* 32-bit project ids */
#define XFS_SB_VERSION2_FTYPE		0x00000200	/* inode type in dir */
#define XFS_SB_VERSION2_BITS_SUPPORTED \
	(XFS_SB_VERSION2_LAZYSBCOUNTBIT | \
	 XFS_SB_VERSION2_ATTR2BIT | \
	 XFS_SB_VERSION2_PROJID32BIT | \
	 XFS_SB_VERSION2_FTYPE)

/* incompat feature flags */
#define XFS_SB_FEAT_INCOMPAT_FTYPE      (1 << 0)        /* filetype in dirent */
#define XFS_SB_FEAT_INCOMPAT_SPINODES   (1 << 1)        /* sparse inode chunks */
#define XFS_SB_FEAT_INCOMPAT_META_UUID  (1 << 2)        /* metadata UUID */

/* We do not currently verify metadata UUID so it is safe to read such filesystem */
#define XFS_SB_FEAT_INCOMPAT_SUPPORTED \
	(XFS_SB_FEAT_INCOMPAT_FTYPE | \
	 XFS_SB_FEAT_INCOMPAT_META_UUID)

struct grub_xfs_sblock
{
  grub_uint8_t magic[4];
  grub_uint32_t bsize;
  grub_uint8_t unused1[24];
  grub_uint16_t uuid[8];
  grub_uint8_t unused2[8];
  grub_uint64_t rootino;
  grub_uint8_t unused3[20];
  grub_uint32_t agsize;
  grub_uint8_t unused4[12];
  grub_uint16_t version;
  grub_uint8_t unused5[6];
  grub_uint8_t label[12];
  grub_uint8_t log2_bsize;
  grub_uint8_t log2_sect;
  grub_uint8_t log2_inode;
  grub_uint8_t log2_inop;
  grub_uint8_t log2_agblk;
  grub_uint8_t unused6[67];
  grub_uint8_t log2_dirblk;
  grub_uint8_t unused7[7];
  grub_uint32_t features2;
  grub_uint8_t unused8[4];
  grub_uint32_t sb_features_compat;
  grub_uint32_t sb_features_ro_compat;
  grub_uint32_t sb_features_incompat;
  grub_uint32_t sb_features_log_incompat;
} GRUB_PACKED;

struct grub_xfs_dir_header
{
  grub_uint8_t count;
  grub_uint8_t largeino;
  union
  {
    grub_uint32_t i4;
    grub_uint64_t i8;
  } GRUB_PACKED parent;
} GRUB_PACKED;

/* Structure for directory entry inlined in the inode */
struct grub_xfs_dir_entry
{
  grub_uint8_t len;
  grub_uint16_t offset;
  char name[1];
  /* Inode number follows, 32 / 64 bits.  */
} GRUB_PACKED;

/* Structure for directory entry in a block */
struct grub_xfs_dir2_entry
{
  grub_uint64_t inode;
  grub_uint8_t len;
} GRUB_PACKED;

struct grub_xfs_extent
{
  /* This should be a bitfield but bietfields are unportable, so just have
     a raw array and functions extracting useful info from it.
   */
  grub_uint32_t raw[4];
} GRUB_PACKED;

struct grub_xfs_btree_node
{
  grub_uint8_t magic[4];
  grub_uint16_t level;
  grub_uint16_t numrecs;
  grub_uint64_t left;
  grub_uint64_t right;
  /* In V5 here follow crc, uuid, etc. */
  /* Then follow keys and block pointers */
} GRUB_PACKED;

struct grub_xfs_btree_root
{
  grub_uint16_t level;
  grub_uint16_t numrecs;
  grub_uint64_t keys[1];
} GRUB_PACKED;

struct grub_xfs_time
{
  grub_uint32_t sec;
  grub_uint32_t nanosec;
} GRUB_PACKED;

struct grub_xfs_inode
{
  grub_uint8_t magic[2];
  grub_uint16_t mode;
  grub_uint8_t version;
  grub_uint8_t format;
  grub_uint8_t unused2[26];
  struct grub_xfs_time atime;
  struct grub_xfs_time mtime;
  struct grub_xfs_time ctime;
  grub_uint64_t size;
  grub_uint64_t nblocks;
  grub_uint32_t extsize;
  grub_uint32_t nextents;
  grub_uint16_t unused3;
  grub_uint8_t fork_offset;
  grub_uint8_t unused4[17];
} GRUB_PACKED;

#define XFS_V2_INODE_SIZE sizeof(struct grub_xfs_inode)
#define XFS_V3_INODE_SIZE (XFS_V2_INODE_SIZE + 76)

struct grub_xfs_dirblock_tail
{
  grub_uint32_t leaf_count;
  grub_uint32_t leaf_stale;
} GRUB_PACKED;

struct grub_fshelp_node
{
  struct grub_xfs_data *data;
  grub_uint64_t ino;
  int inode_read;
  struct grub_xfs_inode inode;
};

struct grub_xfs_data
{
  struct grub_xfs_sblock sblock;
  grub_disk_t disk;
  int pos;
  int bsize;
  grub_uint32_t agsize;
  unsigned int hasftype:1;
  unsigned int hascrc:1;
  struct grub_fshelp_node diropen;
};

static grub_dl_t my_mod;



static int grub_xfs_sb_hascrc(struct grub_xfs_data *data)
{
  return (data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_NUMBITS)) ==
	  grub_cpu_to_be16_compile_time(XFS_SB_VERSION_5);
}

static int grub_xfs_sb_hasftype(struct grub_xfs_data *data)
{
  if ((data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_NUMBITS)) ==
	grub_cpu_to_be16_compile_time(XFS_SB_VERSION_5) &&
      data->sblock.sb_features_incompat & grub_cpu_to_be32_compile_time(XFS_SB_FEAT_INCOMPAT_FTYPE))
    return 1;
  if (data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_MOREBITSBIT) &&
      data->sblock.features2 & grub_cpu_to_be32_compile_time(XFS_SB_VERSION2_FTYPE))
    return 1;
  return 0;
}

static int grub_xfs_sb_valid(struct grub_xfs_data *data)
{
  grub_dprintf("xfs", "Validating superblock\n");
  if (grub_strncmp ((char *) (data->sblock.magic), "XFSB", 4)
      || data->sblock.log2_bsize < GRUB_DISK_SECTOR_BITS
      || ((int) data->sblock.log2_bsize
	  + (int) data->sblock.log2_dirblk) >= 27)
    {
      grub_error (GRUB_ERR_BAD_FS, "not a XFS filesystem");
      return 0;
    }
  if ((data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_NUMBITS)) ==
       grub_cpu_to_be16_compile_time(XFS_SB_VERSION_5))
    {
      grub_dprintf("xfs", "XFS v5 superblock detected\n");
      if (data->sblock.sb_features_incompat &
          grub_cpu_to_be32_compile_time(~XFS_SB_FEAT_INCOMPAT_SUPPORTED))
        {
	  grub_error (GRUB_ERR_BAD_FS, "XFS filesystem has unsupported "
		      "incompatible features");
	  return 0;
        }
      return 1;
    }
  else if ((data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_NUMBITS)) ==
	   grub_cpu_to_be16_compile_time(XFS_SB_VERSION_4))
    {
      grub_dprintf("xfs", "XFS v4 superblock detected\n");
      if (!(data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_DIRV2BIT)))
	{
	  grub_error (GRUB_ERR_BAD_FS, "XFS filesystem without V2 directories "
		      "is unsupported");
	  return 0;
	}
      if (data->sblock.version & grub_cpu_to_be16_compile_time(~XFS_SB_VERSION_BITS_SUPPORTED) ||
	  (data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_MOREBITSBIT) &&
	   data->sblock.features2 & grub_cpu_to_be16_compile_time(~XFS_SB_VERSION2_BITS_SUPPORTED)))
	{
	  grub_error (GRUB_ERR_BAD_FS, "XFS filesystem has unsupported version "
		      "bits");
	  return 0;
	}
      return 1;
    }
  return 0;
}

/* Filetype information as used in inodes.  */
#define FILETYPE_INO_MASK	0170000
#define FILETYPE_INO_REG	0100000
#define FILETYPE_INO_DIRECTORY	0040000
#define FILETYPE_INO_SYMLINK	0120000

static inline int
GRUB_XFS_INO_AGBITS(struct grub_xfs_data *data)
{
  return ((data)->sblock.log2_agblk + (data)->sblock.log2_inop);
}

static inline grub_uint64_t
GRUB_XFS_INO_INOINAG (struct grub_xfs_data *data,
		      grub_uint64_t ino)
{
  return (ino & ((1LL << GRUB_XFS_INO_AGBITS (data)) - 1));
}

static inline grub_uint64_t
GRUB_XFS_INO_AG (struct grub_xfs_data *data,
		 grub_uint64_t ino)
{
  return (ino >> GRUB_XFS_INO_AGBITS (data));
}

static inline grub_disk_addr_t
GRUB_XFS_FSB_TO_BLOCK (struct grub_xfs_data *data, grub_disk_addr_t fsb)
{
  return ((fsb >> data->sblock.log2_agblk) * data->agsize
	  + (fsb & ((1LL << data->sblock.log2_agblk) - 1)));
}

static inline grub_uint64_t
GRUB_XFS_EXTENT_OFFSET (struct grub_xfs_extent *exts, int ex)
{
  return ((grub_be_to_cpu32 (exts[ex].raw[0]) & ~(1 << 31)) << 23
	  | grub_be_to_cpu32 (exts[ex].raw[1]) >> 9);
}

static inline grub_uint64_t
GRUB_XFS_EXTENT_BLOCK (struct grub_xfs_extent *exts, int ex)
{
  return ((grub_uint64_t) (grub_be_to_cpu32 (exts[ex].raw[1])
			   & (0x1ff)) << 43
	  | (grub_uint64_t) grub_be_to_cpu32 (exts[ex].raw[2]) << 11
	  | grub_be_to_cpu32 (exts[ex].raw[3]) >> 21);
}

static inline grub_uint64_t
GRUB_XFS_EXTENT_SIZE (struct grub_xfs_extent *exts, int ex)
{
  return (grub_be_to_cpu32 (exts[ex].raw[3]) & ((1 << 21) - 1));
}


static inline grub_uint64_t
grub_xfs_inode_block (struct grub_xfs_data *data,
		      grub_uint64_t ino)
{
  long long int inoinag = GRUB_XFS_INO_INOINAG (data, ino);
  long long ag = GRUB_XFS_INO_AG (data, ino);
  long long block;

  block = (inoinag >> data->sblock.log2_inop) + ag * data->agsize;
  block <<= (data->sblock.log2_bsize - GRUB_DISK_SECTOR_BITS);
  return block;
}


static inline int
grub_xfs_inode_offset (struct grub_xfs_data *data,
		       grub_uint64_t ino)
{
  int inoag = GRUB_XFS_INO_INOINAG (data, ino);
  return ((inoag & ((1 << data->sblock.log2_inop) - 1)) <<
	  data->sblock.log2_inode);
}

static inline grub_size_t
grub_xfs_inode_size(struct grub_xfs_data *data)
{
  return (grub_size_t)1 << data->sblock.log2_inode;
}

/*
 * Returns size occupied by XFS inode stored in memory - we store struct
 * grub_fshelp_node there but on disk inode size may be actually larger than
 * struct grub_xfs_inode so we need to account for that so that we can read
 * from disk directly into in-memory structure.
 */
static inline grub_size_t
grub_xfs_fshelp_size(struct grub_xfs_data *data)
{
  return sizeof (struct grub_fshelp_node) - sizeof (struct grub_xfs_inode)
	       + grub_xfs_inode_size(data);
}

/* This should return void * but XFS code is error-prone with alignment, so
   return char to retain cast-align.
 */
static char *
grub_xfs_inode_data(struct grub_xfs_inode *inode)
{
	if (inode->version <= 2)
		return ((char *)inode) + XFS_V2_INODE_SIZE;
	return ((char *)inode) + XFS_V3_INODE_SIZE;
}

static struct grub_xfs_dir_entry *
grub_xfs_inline_de(struct grub_xfs_dir_header *head)
{
  /*
    With small inode numbers the header is 4 bytes smaller because of
    smaller parent pointer
  */
  return (struct grub_xfs_dir_entry *)
    (((char *) head) + sizeof(struct grub_xfs_dir_header) -
     (head->largeino ? 0 : sizeof(grub_uint32_t)));
}

static grub_uint8_t *
grub_xfs_inline_de_inopos(struct grub_xfs_data *data,
			  struct grub_xfs_dir_entry *de)
{
  return ((grub_uint8_t *)(de + 1)) + de->len - 1 + (data->hasftype ? 1 : 0);
}

static struct grub_xfs_dir_entry *
grub_xfs_inline_next_de(struct grub_xfs_data *data,
			struct grub_xfs_dir_header *head,
			struct grub_xfs_dir_entry *de)
{
  char *p = (char *)de + sizeof(struct grub_xfs_dir_entry) - 1 + de->len;

  p += head->largeino ? sizeof(grub_uint64_t) : sizeof(grub_uint32_t);
  if (data->hasftype)
    p++;

  return (struct grub_xfs_dir_entry *)p;
}

static struct grub_xfs_dirblock_tail *
grub_xfs_dir_tail(struct grub_xfs_data *data, void *dirblock)
{
  int dirblksize = 1 << (data->sblock.log2_bsize + data->sblock.log2_dirblk);

  return (struct grub_xfs_dirblock_tail *)
    ((char *)dirblock + dirblksize - sizeof (struct grub_xfs_dirblock_tail));
}

static struct grub_xfs_dir2_entry *
grub_xfs_first_de(struct grub_xfs_data *data, void *dirblock)
{
  if (data->hascrc)
    return (struct grub_xfs_dir2_entry *)((char *)dirblock + 64);
  return (struct grub_xfs_dir2_entry *)((char *)dirblock + 16);
}

static struct grub_xfs_dir2_entry *
grub_xfs_next_de(struct grub_xfs_data *data, struct grub_xfs_dir2_entry *de)
{
  int size = sizeof (struct grub_xfs_dir2_entry) + de->len + 2 /* Tag */;

  if (data->hasftype)
    size++;		/* File type */
  return (struct grub_xfs_dir2_entry *)(((char *)de) + ALIGN_UP(size, 8));
}

/* This should return void * but XFS code is error-prone with alignment, so
   return char to retain cast-align.
 */
static char *
grub_xfs_btree_keys(struct grub_xfs_data *data,
		    struct grub_xfs_btree_node *leaf)
{
  char *keys = (char *)(leaf + 1);

  if (data->hascrc)
    keys += 48;	/* skip crc, uuid, ... */
  return keys;
}

static grub_err_t
grub_xfs_read_inode (struct grub_xfs_data *data, grub_uint64_t ino,
		     struct grub_xfs_inode *inode)
{
  grub_uint64_t block = grub_xfs_inode_block (data, ino);
  int offset = grub_xfs_inode_offset (data, ino);

  grub_dprintf("xfs", "Reading inode (%"PRIuGRUB_UINT64_T") - %"PRIuGRUB_UINT64_T", %d\n",
	       ino, block, offset);
  /* Read the inode.  */
  if (grub_disk_read (data->disk, block, offset, grub_xfs_inode_size(data),
		      inode))
    return grub_errno;

  if (grub_strncmp ((char *) inode->magic, "IN", 2))
    return grub_error (GRUB_ERR_BAD_FS, "not a correct XFS inode");

  return 0;
}

static grub_uint64_t
get_fsb (const void *keys, int idx)
{
  const char *p = (const char *) keys + sizeof(grub_uint64_t) * idx;
  return grub_be_to_cpu64 (grub_get_unaligned64 (p));
}

static grub_disk_addr_t
grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
{
  struct grub_xfs_btree_node *leaf = 0;
  int ex, nrec;
  struct grub_xfs_extent *exts;
  grub_uint64_t ret = 0;

  if (node->inode.format == XFS_INODE_FORMAT_BTREE)
    {
      struct grub_xfs_btree_root *root;
      const char *keys;
      int recoffset;

      leaf = grub_malloc (node->data->bsize);
      if (leaf == 0)
        return 0;

      root = (struct grub_xfs_btree_root *) grub_xfs_inode_data(&node->inode);
      nrec = grub_be_to_cpu16 (root->numrecs);
      keys = (char *) &root->keys[0];
      if (node->inode.fork_offset)
	recoffset = (node->inode.fork_offset - 1) / 2;
      else
	recoffset = (grub_xfs_inode_size(node->data)
		     - ((char *) keys - (char *) &node->inode))
				/ (2 * sizeof (grub_uint64_t));
      do
        {
          int i;

          for (i = 0; i < nrec; i++)
            {
              if (fileblock < get_fsb(keys, i))
                break;
            }

          /* Sparse block.  */
          if (i == 0)
            {
              grub_free (leaf);
              return 0;
            }

          if (grub_disk_read (node->data->disk,
                              GRUB_XFS_FSB_TO_BLOCK (node->data, get_fsb (keys, i - 1 + recoffset)) << (node->data->sblock.log2_bsize - GRUB_DISK_SECTOR_BITS),
                              0, node->data->bsize, leaf))
            return 0;

	  if ((!node->data->hascrc &&
	       grub_strncmp ((char *) leaf->magic, "BMAP", 4)) ||
	      (node->data->hascrc &&
	       grub_strncmp ((char *) leaf->magic, "BMA3", 4)))
            {
              grub_free (leaf);
              grub_error (GRUB_ERR_BAD_FS, "not a correct XFS BMAP node");
              return 0;
            }

          nrec = grub_be_to_cpu16 (leaf->numrecs);
          keys = grub_xfs_btree_keys(node->data, leaf);
	  recoffset = ((node->data->bsize - ((char *) keys
					     - (char *) leaf))
		       / (2 * sizeof (grub_uint64_t)));
	}
      while (leaf->level);
      exts = (struct grub_xfs_extent *) keys;
    }
  else if (node->inode.format == XFS_INODE_FORMAT_EXT)
    {
      nrec = grub_be_to_cpu32 (node->inode.nextents);
      exts = (struct grub_xfs_extent *) grub_xfs_inode_data(&node->inode);
    }
  else
    {
      grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
		  "XFS does not support inode format %d yet",
		  node->inode.format);
      return 0;
    }

  /* Iterate over each extent to figure out which extent has
     the block we are looking for.  */
  for (ex = 0; ex < nrec; ex++)
    {
      grub_uint64_t start = GRUB_XFS_EXTENT_BLOCK (exts, ex);
      grub_uint64_t offset = GRUB_XFS_EXTENT_OFFSET (exts, ex);
      grub_uint64_t size = GRUB_XFS_EXTENT_SIZE (exts, ex);

      /* Sparse block.  */
      if (fileblock < offset)
        break;
      else if (fileblock < offset + size)
        {
          ret = (fileblock - offset + start);
          break;
        }
    }

  grub_free (leaf);

  return GRUB_XFS_FSB_TO_BLOCK(node->data, ret);
}


/* Read LEN bytes from the file described by DATA starting with byte
   POS.  Return the amount of read bytes in READ.  */
static grub_ssize_t
grub_xfs_read_file (grub_fshelp_node_t node,
		    grub_disk_read_hook_t read_hook, void *read_hook_data,
		    grub_off_t pos, grub_size_t len, char *buf, grub_uint32_t header_size)
{
  return grub_fshelp_read_file (node->data->disk, node,
				read_hook, read_hook_data,
				pos, len, buf, grub_xfs_read_block,
				grub_be_to_cpu64 (node->inode.size) + header_size,
				node->data->sblock.log2_bsize
				- GRUB_DISK_SECTOR_BITS, 0);
}


static char *
grub_xfs_read_symlink (grub_fshelp_node_t node)
{
  grub_ssize_t size = grub_be_to_cpu64 (node->inode.size);

  if (size < 0)
    {
      grub_error (GRUB_ERR_BAD_FS, "invalid symlink");
      return 0;
    }

  switch (node->inode.format)
    {
    case XFS_INODE_FORMAT_INO:
      return grub_strndup (grub_xfs_inode_data(&node->inode), size);

    case XFS_INODE_FORMAT_EXT:
      {
	char *symlink;
	grub_ssize_t numread;
	int off = 0;

	if (node->data->hascrc)
	  off = 56;

	symlink = grub_malloc (size + 1);
	if (!symlink)
	  return 0;

	node->inode.size = grub_be_to_cpu64 (size + off);
	numread = grub_xfs_read_file (node, 0, 0, off, size, symlink, off);
	if (numread != size)
	  {
	    grub_free (symlink);
	    return 0;
	  }
	symlink[size] = '\0';
	return symlink;
      }
    }

  return 0;
}


static enum grub_fshelp_filetype
grub_xfs_mode_to_filetype (grub_uint16_t mode)
{
  if ((grub_be_to_cpu16 (mode)
       & FILETYPE_INO_MASK) == FILETYPE_INO_DIRECTORY)
    return GRUB_FSHELP_DIR;
  else if ((grub_be_to_cpu16 (mode)
	    & FILETYPE_INO_MASK) == FILETYPE_INO_SYMLINK)
    return GRUB_FSHELP_SYMLINK;
  else if ((grub_be_to_cpu16 (mode)
	    & FILETYPE_INO_MASK) == FILETYPE_INO_REG)
    return GRUB_FSHELP_REG;
  return GRUB_FSHELP_UNKNOWN;
}


/* Context for grub_xfs_iterate_dir.  */
struct grub_xfs_iterate_dir_ctx
{
  grub_fshelp_iterate_dir_hook_t hook;
  void *hook_data;
  struct grub_fshelp_node *diro;
};

/* Helper for grub_xfs_iterate_dir.  */
static int iterate_dir_call_hook (grub_uint64_t ino, const char *filename,
				  struct grub_xfs_iterate_dir_ctx *ctx)
{
  struct grub_fshelp_node *fdiro;
  grub_err_t err;

  fdiro = grub_malloc (grub_xfs_fshelp_size(ctx->diro->data) + 1);
  if (!fdiro)
    {
      grub_print_error ();
      return 0;
    }

  /* The inode should be read, otherwise the filetype can
     not be determined.  */
  fdiro->ino = ino;
  fdiro->inode_read = 1;
  fdiro->data = ctx->diro->data;
  err = grub_xfs_read_inode (ctx->diro->data, ino, &fdiro->inode);
  if (err)
    {
      grub_print_error ();
      return 0;
    }

  return ctx->hook (filename, grub_xfs_mode_to_filetype (fdiro->inode.mode),
		    fdiro, ctx->hook_data);
}

static int
grub_xfs_iterate_dir (grub_fshelp_node_t dir,
		      grub_fshelp_iterate_dir_hook_t hook, void *hook_data)
{
  struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir;
  struct grub_xfs_iterate_dir_ctx ctx = {
    .hook = hook,
    .hook_data = hook_data,
    .diro = diro
  };

  switch (diro->inode.format)
    {
    case XFS_INODE_FORMAT_INO:
      {
	struct grub_xfs_dir_header *head = (struct grub_xfs_dir_header *) grub_xfs_inode_data(&diro->inode);
	struct grub_xfs_dir_entry *de = grub_xfs_inline_de(head);
	int smallino = !head->largeino;
	int i;
	grub_uint64_t parent;

	/* If small inode numbers are used to pack the direntry, the
	   parent inode number is small too.  */
	if (smallino)
	  parent = grub_be_to_cpu32 (head->parent.i4);
	else
	  parent = grub_be_to_cpu64 (head->parent.i8);

	/* Synthesize the direntries for `.' and `..'.  */
	if (iterate_dir_call_hook (diro->ino, ".", &ctx))
	  return 1;

	if (iterate_dir_call_hook (parent, "..", &ctx))
	  return 1;

	for (i = 0; i < head->count; i++)
	  {
	    grub_uint64_t ino;
	    grub_uint8_t *inopos = grub_xfs_inline_de_inopos(dir->data, de);
	    grub_uint8_t c;

	    /* inopos might be unaligned.  */
	    if (smallino)
	      ino = (((grub_uint32_t) inopos[0]) << 24)
		| (((grub_uint32_t) inopos[1]) << 16)
		| (((grub_uint32_t) inopos[2]) << 8)
		| (((grub_uint32_t) inopos[3]) << 0);
	    else
	      ino = (((grub_uint64_t) inopos[0]) << 56)
		| (((grub_uint64_t) inopos[1]) << 48)
		| (((grub_uint64_t) inopos[2]) << 40)
		| (((grub_uint64_t) inopos[3]) << 32)
		| (((grub_uint64_t) inopos[4]) << 24)
		| (((grub_uint64_t) inopos[5]) << 16)
		| (((grub_uint64_t) inopos[6]) << 8)
		| (((grub_uint64_t) inopos[7]) << 0);

	    c = de->name[de->len];
	    de->name[de->len] = '\0';
	    if (iterate_dir_call_hook (ino, de->name, &ctx))
	      {
		de->name[de->len] = c;
		return 1;
	      }
	    de->name[de->len] = c;

	    de = grub_xfs_inline_next_de(dir->data, head, de);
	  }
	break;
      }

    case XFS_INODE_FORMAT_BTREE:
    case XFS_INODE_FORMAT_EXT:
      {
	grub_ssize_t numread;
	char *dirblock;
	grub_uint64_t blk;
        int dirblk_size, dirblk_log2;

        dirblk_log2 = (dir->data->sblock.log2_bsize
                       + dir->data->sblock.log2_dirblk);
        dirblk_size = 1 << dirblk_log2;

	dirblock = grub_malloc (dirblk_size);
	if (! dirblock)
	  return 0;

	/* Iterate over every block the directory has.  */
	for (blk = 0;
	     blk < (grub_be_to_cpu64 (dir->inode.size)
		    >> dirblk_log2);
	     blk++)
	  {
	    struct grub_xfs_dir2_entry *direntry =
					grub_xfs_first_de(dir->data, dirblock);
	    int entries;
	    struct grub_xfs_dirblock_tail *tail =
					grub_xfs_dir_tail(dir->data, dirblock);

	    numread = grub_xfs_read_file (dir, 0, 0,
					  blk << dirblk_log2,
					  dirblk_size, dirblock, 0);
	    if (numread != dirblk_size)
	      return 0;

	    entries = (grub_be_to_cpu32 (tail->leaf_count)
		       - grub_be_to_cpu32 (tail->leaf_stale));

	    /* Iterate over all entries within this block.  */
	    while ((char *)direntry < (char *)tail)
	      {
		grub_uint8_t *freetag;
		char *filename;

		freetag = (grub_uint8_t *) direntry;

		if (grub_get_unaligned16 (freetag) == 0XFFFF)
		  {
		    grub_uint8_t *skip = (freetag + sizeof (grub_uint16_t));

		    /* This entry is not used, go to the next one.  */
		    direntry = (struct grub_xfs_dir2_entry *)
				(((char *)direntry) +
				grub_be_to_cpu16 (grub_get_unaligned16 (skip)));

		    continue;
		  }

		filename = (char *)(direntry + 1);
		/* The byte after the filename is for the filetype, padding, or
		   tag, which is not used by GRUB.  So it can be overwritten. */
		filename[direntry->len] = '\0';

		if (iterate_dir_call_hook (grub_be_to_cpu64(direntry->inode), 
					   filename, &ctx))
		  {
		    grub_free (dirblock);
		    return 1;
		  }

		/* Check if last direntry in this block is
		   reached.  */
		entries--;
		if (!entries)
		  break;

		/* Select the next directory entry.  */
		direntry = grub_xfs_next_de(dir->data, direntry);
	      }
	  }
	grub_free (dirblock);
	break;
      }

    default:
      grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
		  "XFS does not support inode format %d yet",
		  diro->inode.format);
    }
  return 0;
}


static struct grub_xfs_data *
grub_xfs_mount (grub_disk_t disk)
{
  struct grub_xfs_data *data = 0;

  data = grub_zalloc (sizeof (struct grub_xfs_data));
  if (!data)
    return 0;

  grub_dprintf("xfs", "Reading sb\n");
  /* Read the superblock.  */
  if (grub_disk_read (disk, 0, 0,
		      sizeof (struct grub_xfs_sblock), &data->sblock))
    goto fail;

  if (!grub_xfs_sb_valid(data))
    goto fail;

  data = grub_realloc (data,
		       sizeof (struct grub_xfs_data)
		       - sizeof (struct grub_xfs_inode)
		       + grub_xfs_inode_size(data) + 1);

  if (! data)
    goto fail;

  data->diropen.data = data;
  data->diropen.ino = grub_be_to_cpu64(data->sblock.rootino);
  data->diropen.inode_read = 1;
  data->bsize = grub_be_to_cpu32 (data->sblock.bsize);
  data->agsize = grub_be_to_cpu32 (data->sblock.agsize);
  data->hasftype = grub_xfs_sb_hasftype(data);
  data->hascrc = grub_xfs_sb_hascrc(data);

  data->disk = disk;
  data->pos = 0;
  grub_dprintf("xfs", "Reading root ino %"PRIuGRUB_UINT64_T"\n",
	       grub_cpu_to_be64(data->sblock.rootino));

  grub_xfs_read_inode (data, data->diropen.ino, &data->diropen.inode);

  return data;
 fail:

  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
    grub_error (GRUB_ERR_BAD_FS, "not an XFS filesystem");

  grub_free (data);

  return 0;
}


/* Context for grub_xfs_dir.  */
struct grub_xfs_dir_ctx
{
  grub_fs_dir_hook_t hook;
  void *hook_data;
};

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

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

static grub_err_t
grub_xfs_dir (grub_device_t device, const char *path,
	      grub_fs_dir_hook_t hook, void *hook_data)
{
  struct grub_xfs_dir_ctx ctx = { hook, hook_data };
  struct grub_xfs_data *data = 0;
  struct grub_fshelp_node *fdiro = 0;

  grub_dl_ref (my_mod);

  data = grub_xfs_mount (device->disk);
  if (!data)
    goto mount_fail;

  grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_xfs_iterate_dir,
			 grub_xfs_read_symlink, GRUB_FSHELP_DIR);
  if (grub_errno)
    goto fail;

  grub_xfs_iterate_dir (fdiro, grub_xfs_dir_iter, &ctx);

 fail:
  if (fdiro != &data->diropen)
    grub_free (fdiro);
  grub_free (data);

 mount_fail:

  grub_dl_unref (my_mod);

  return grub_errno;
}


/* Open a file named NAME and initialize FILE.  */
static grub_err_t
grub_xfs_open (struct grub_file *file, const char *name)
{
  struct grub_xfs_data *data;
  struct grub_fshelp_node *fdiro = 0;

  grub_dl_ref (my_mod);

  data = grub_xfs_mount (file->device->disk);
  if (!data)
    goto mount_fail;

  grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_xfs_iterate_dir,
			 grub_xfs_read_symlink, GRUB_FSHELP_REG);
  if (grub_errno)
    goto fail;

  if (!fdiro->inode_read)
    {
      grub_xfs_read_inode (data, fdiro->ino, &fdiro->inode);
      if (grub_errno)
	goto fail;
    }

  if (fdiro != &data->diropen)
    {
      grub_memcpy (&data->diropen, fdiro, grub_xfs_fshelp_size(data));
      grub_free (fdiro);
    }

  file->size = grub_be_to_cpu64 (data->diropen.inode.size);
  file->data = data;
  file->offset = 0;

  return 0;

 fail:
  if (fdiro != &data->diropen)
    grub_free (fdiro);
  grub_free (data);

 mount_fail:
  grub_dl_unref (my_mod);

  return grub_errno;
}


static grub_ssize_t
grub_xfs_read (grub_file_t file, char *buf, grub_size_t len)
{
  struct grub_xfs_data *data =
    (struct grub_xfs_data *) file->data;

  return grub_xfs_read_file (&data->diropen,
			     file->read_hook, file->read_hook_data,
			     file->offset, len, buf, 0);
}


static grub_err_t
grub_xfs_close (grub_file_t file)
{
  grub_free (file->data);

  grub_dl_unref (my_mod);

  return GRUB_ERR_NONE;
}


static grub_err_t
grub_xfs_label (grub_device_t device, char **label)
{
  struct grub_xfs_data *data;
  grub_disk_t disk = device->disk;

  grub_dl_ref (my_mod);

  data = grub_xfs_mount (disk);
  if (data)
    *label = grub_strndup ((char *) (data->sblock.label), 12);
  else
    *label = 0;

  grub_dl_unref (my_mod);

  grub_free (data);

  return grub_errno;
}

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

  grub_dl_ref (my_mod);

  data = grub_xfs_mount (disk);
  if (data)
    {
      *uuid = grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x",
			     grub_be_to_cpu16 (data->sblock.uuid[0]),
			     grub_be_to_cpu16 (data->sblock.uuid[1]),
			     grub_be_to_cpu16 (data->sblock.uuid[2]),
			     grub_be_to_cpu16 (data->sblock.uuid[3]),
			     grub_be_to_cpu16 (data->sblock.uuid[4]),
			     grub_be_to_cpu16 (data->sblock.uuid[5]),
			     grub_be_to_cpu16 (data->sblock.uuid[6]),
			     grub_be_to_cpu16 (data->sblock.uuid[7]));
    }
  else
    *uuid = NULL;

  grub_dl_unref (my_mod);

  grub_free (data);

  return grub_errno;
}



static struct grub_fs grub_xfs_fs =
  {
    .name = "xfs",
    .dir = grub_xfs_dir,
    .open = grub_xfs_open,
    .read = grub_xfs_read,
    .close = grub_xfs_close,
    .label = grub_xfs_label,
    .uuid = grub_xfs_uuid,
#ifdef GRUB_UTIL
    .reserved_first_sector = 0,
    .blocklist_install = 1,
#endif
    .next = 0
  };

GRUB_MOD_INIT(xfs)
{
  grub_fs_register (&grub_xfs_fs);
  my_mod = mod;
}

GRUB_MOD_FINI(xfs)
{
  grub_fs_unregister (&grub_xfs_fs);
}
