/*
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 1999,2000,2001,2002,2003,2004,2009,2010,2011  Free Software Foundation, Inc.
 *  Copyright 2010  Sun Microsystems, Inc.
 *  Copyright (c) 2012 by Delphix. All rights reserved.
 *
 *  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/>.
 */
/*
 * The zfs plug-in routines for GRUB are:
 *
 * zfs_mount() - locates a valid uberblock of the root pool and reads
 *		in its MOS at the memory address MOS.
 *
 * zfs_open() - locates a plain file object by following the MOS
 *		and places its dnode at the memory address DNODE.
 *
 * zfs_read() - read in the data blocks pointed by the DNODE.
 *
 */

#include <grub/err.h>
#include <grub/file.h>
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/disk.h>
#include <grub/partition.h>
#include <grub/dl.h>
#include <grub/types.h>
#include <grub/zfs/zfs.h>
#include <grub/zfs/zio.h>
#include <grub/zfs/dnode.h>
#include <grub/zfs/uberblock_impl.h>
#include <grub/zfs/vdev_impl.h>
#include <grub/zfs/zio_checksum.h>
#include <grub/zfs/zap_impl.h>
#include <grub/zfs/zap_leaf.h>
#include <grub/zfs/zfs_znode.h>
#include <grub/zfs/dmu.h>
#include <grub/zfs/dmu_objset.h>
#include <grub/zfs/sa_impl.h>
#include <grub/zfs/dsl_dir.h>
#include <grub/zfs/dsl_dataset.h>
#include <grub/deflate.h>
#include <grub/crypto.h>
#include <grub/i18n.h>

GRUB_MOD_LICENSE ("GPLv3+");

#define	ZPOOL_PROP_BOOTFS		"bootfs"

/*
 * For nvlist manipulation. (from nvpair.h)
 */
#define	NV_ENCODE_NATIVE	0
#define	NV_ENCODE_XDR		1
#define	NV_BIG_ENDIAN	        0
#define	NV_LITTLE_ENDIAN	1
#define	DATA_TYPE_UINT64	8
#define	DATA_TYPE_STRING	9
#define	DATA_TYPE_NVLIST	19
#define	DATA_TYPE_NVLIST_ARRAY	20

#ifndef GRUB_UTIL
static grub_dl_t my_mod;
#endif

#define	P2PHASE(x, align)		((x) & ((align) - 1))

static inline grub_disk_addr_t
DVA_OFFSET_TO_PHYS_SECTOR (grub_disk_addr_t offset)
{
  return ((offset + VDEV_LABEL_START_SIZE) >> SPA_MINBLOCKSHIFT);
}

/*
 * FAT ZAP data structures
 */
#define	ZFS_CRC64_POLY 0xC96C5795D7870F42ULL	/* ECMA-182, reflected form */
static inline grub_uint64_t
ZAP_HASH_IDX (grub_uint64_t hash, grub_uint64_t n)
{
  return (((n) == 0) ? 0 : ((hash) >> (64 - (n))));
}

#define	CHAIN_END	0xffff	/* end of the chunk chain */

/*
 * The amount of space within the chunk available for the array is:
 * chunk size - space for type (1) - space for next pointer (2)
 */
#define	ZAP_LEAF_ARRAY_BYTES (ZAP_LEAF_CHUNKSIZE - 3)

static inline int
ZAP_LEAF_HASH_SHIFT (int bs)
{
  return bs - 5;
}

static inline int
ZAP_LEAF_HASH_NUMENTRIES (int bs)
{
  return 1 << ZAP_LEAF_HASH_SHIFT(bs);
}

static inline grub_size_t
LEAF_HASH (int bs, grub_uint64_t h, zap_leaf_phys_t *l)
{
  return ((ZAP_LEAF_HASH_NUMENTRIES (bs)-1)
	  & ((h) >> (64 - ZAP_LEAF_HASH_SHIFT (bs) - l->l_hdr.lh_prefix_len)));
}

/*
 * The amount of space available for chunks is:
 * block size shift - hash entry size (2) * number of hash
 * entries - header space (2*chunksize)
 */
static inline int
ZAP_LEAF_NUMCHUNKS (int bs)
{
  return (((1U << bs) - 2 * ZAP_LEAF_HASH_NUMENTRIES (bs)) /
	  ZAP_LEAF_CHUNKSIZE - 2);
}

/*
 * The chunks start immediately after the hash table.  The end of the
 * hash table is at l_hash + HASH_NUMENTRIES, which we simply cast to a
 * chunk_t.
 */
static inline zap_leaf_chunk_t *
ZAP_LEAF_CHUNK (zap_leaf_phys_t *l, int bs, int idx)
{
  return &((zap_leaf_chunk_t *) (l->l_entries 
				 + (ZAP_LEAF_HASH_NUMENTRIES(bs) * 2)
				 / sizeof (grub_properly_aligned_t)))[idx];
}

static inline struct zap_leaf_entry *
ZAP_LEAF_ENTRY(zap_leaf_phys_t *l, int bs, int idx)
{
  return &ZAP_LEAF_CHUNK(l, bs, idx)->l_entry;
}


/*
 * Decompression Entry - lzjb & lz4
 */

extern grub_err_t lzjb_decompress (void *, void *, grub_size_t, grub_size_t);

extern grub_err_t lz4_decompress (void *, void *, grub_size_t, grub_size_t);

typedef grub_err_t zfs_decomp_func_t (void *s_start, void *d_start,
				      grub_size_t s_len, grub_size_t d_len);
typedef struct decomp_entry
{
  const char *name;
  zfs_decomp_func_t *decomp_func;
} decomp_entry_t;

/*
 * Signature for checksum functions.
 */
typedef void zio_checksum_t(const void *data, grub_uint64_t size, 
			    grub_zfs_endian_t endian, zio_cksum_t *zcp);

/*
 * Information about each checksum function.
 */
typedef struct zio_checksum_info {
  zio_checksum_t	*ci_func; /* checksum function for each byteorder */
  int		ci_correctable;	/* number of correctable bits	*/
  int		ci_eck;		/* uses zio embedded checksum? */
  const char		*ci_name;	/* descriptive name */
} zio_checksum_info_t;

typedef struct dnode_end
{
  dnode_phys_t dn;
  grub_zfs_endian_t endian;
} dnode_end_t;

struct grub_zfs_device_desc
{
  enum { DEVICE_LEAF, DEVICE_MIRROR, DEVICE_RAIDZ } type;
  grub_uint64_t id;
  grub_uint64_t guid;
  unsigned ashift;
  unsigned max_children_ashift;

  /* Valid only for non-leafs.  */
  unsigned n_children;
  struct grub_zfs_device_desc *children;

  /* Valid only for RAIDZ.  */
  unsigned nparity;

  /* Valid only for leaf devices.  */
  grub_device_t dev;
  grub_disk_addr_t vdev_phys_sector;
  uberblock_t current_uberblock;
  int original;
};

struct subvolume
{
  dnode_end_t mdn;
  grub_uint64_t obj;
  grub_uint64_t case_insensitive;
  grub_size_t nkeys;
  struct
  {
    grub_crypto_cipher_handle_t cipher;
    grub_uint64_t txg;
    grub_uint64_t algo;
  } *keyring;
};

struct grub_zfs_data
{
  /* cache for a file block of the currently zfs_open()-ed file */
  char *file_buf;
  grub_uint64_t file_start;
  grub_uint64_t file_end;

  /* cache for a dnode block */
  dnode_phys_t *dnode_buf;
  dnode_phys_t *dnode_mdn;
  grub_uint64_t dnode_start;
  grub_uint64_t dnode_end;
  grub_zfs_endian_t dnode_endian;

  dnode_end_t mos;
  dnode_end_t dnode;
  struct subvolume subvol;

  struct grub_zfs_device_desc *devices_attached;
  unsigned n_devices_attached;
  unsigned n_devices_allocated;
  struct grub_zfs_device_desc *device_original;

  uberblock_t current_uberblock;

  grub_uint64_t guid;
};

/* Context for grub_zfs_dir.  */
struct grub_zfs_dir_ctx
{
  grub_fs_dir_hook_t hook;
  void *hook_data;
  struct grub_zfs_data *data;
};

grub_err_t (*grub_zfs_decrypt) (grub_crypto_cipher_handle_t cipher,
				grub_uint64_t algo,
				void *nonce,
				char *buf, grub_size_t size,
				const grub_uint32_t *expected_mac,
				grub_zfs_endian_t endian) = NULL;
grub_crypto_cipher_handle_t (*grub_zfs_load_key) (const struct grub_zfs_key *key,
						  grub_size_t keysize,
						  grub_uint64_t salt,
						  grub_uint64_t algo) = NULL;
/*
 * List of pool features that the grub implementation of ZFS supports for
 * read. Note that features that are only required for write do not need
 * to be listed here since grub opens pools in read-only mode.
 */
#define MAX_SUPPORTED_FEATURE_STRLEN 50
static const char *spa_feature_names[] = {
  "org.illumos:lz4_compress",
  "com.delphix:hole_birth",
  "com.delphix:embedded_data",
  "com.delphix:extensible_dataset",
  "org.open-zfs:large_blocks",
  NULL
};

static int
check_feature(const char *name, grub_uint64_t val, struct grub_zfs_dir_ctx *ctx);
static grub_err_t
check_mos_features(dnode_phys_t *mosmdn_phys,grub_zfs_endian_t endian,struct grub_zfs_data* data );

static grub_err_t 
zlib_decompress (void *s, void *d,
		 grub_size_t slen, grub_size_t dlen)
{
  if (grub_zlib_decompress (s, slen, 0, d, dlen) == (grub_ssize_t) dlen)
    return GRUB_ERR_NONE;

  if (!grub_errno)
    grub_error (GRUB_ERR_BAD_COMPRESSED_DATA,
		"premature end of compressed");
  return grub_errno;
}

static grub_err_t 
zle_decompress (void *s, void *d,
		grub_size_t slen, grub_size_t dlen)
{
  grub_uint8_t *iptr, *optr;
  grub_size_t clen;
  for (iptr = s, optr = d; iptr < (grub_uint8_t *) s + slen
	 && optr < (grub_uint8_t *) d + dlen;)
    {
      if (*iptr & 0x80)
	clen = ((*iptr) & 0x7f) + 0x41;
      else
	clen = ((*iptr) & 0x3f) + 1;
      if ((grub_ssize_t) clen > (grub_uint8_t *) d + dlen - optr)
	clen = (grub_uint8_t *) d + dlen - optr;
      if (*iptr & 0x40 || *iptr & 0x80)
	{
	  grub_memset (optr, 0, clen);
	  iptr++;
	  optr += clen;
	  continue;
	}
      if ((grub_ssize_t) clen > (grub_uint8_t *) s + slen - iptr - 1)
	clen = (grub_uint8_t *) s + slen - iptr - 1;
      grub_memcpy (optr, iptr + 1, clen);
      optr += clen;
      iptr += clen + 1;
    }
  if (optr < (grub_uint8_t *) d + dlen)
    grub_memset (optr, 0, (grub_uint8_t *) d + dlen - optr);
  return GRUB_ERR_NONE;
}

static decomp_entry_t decomp_table[ZIO_COMPRESS_FUNCTIONS] = {
  {"inherit", NULL},		/* ZIO_COMPRESS_INHERIT */
  {"on", lzjb_decompress},	/* ZIO_COMPRESS_ON */
  {"off", NULL},		/* ZIO_COMPRESS_OFF */
  {"lzjb", lzjb_decompress},	/* ZIO_COMPRESS_LZJB */
  {"empty", NULL},		/* ZIO_COMPRESS_EMPTY */
  {"gzip-1", zlib_decompress},  /* ZIO_COMPRESS_GZIP1 */
  {"gzip-2", zlib_decompress},  /* ZIO_COMPRESS_GZIP2 */
  {"gzip-3", zlib_decompress},  /* ZIO_COMPRESS_GZIP3 */
  {"gzip-4", zlib_decompress},  /* ZIO_COMPRESS_GZIP4 */
  {"gzip-5", zlib_decompress},  /* ZIO_COMPRESS_GZIP5 */
  {"gzip-6", zlib_decompress},  /* ZIO_COMPRESS_GZIP6 */
  {"gzip-7", zlib_decompress},  /* ZIO_COMPRESS_GZIP7 */
  {"gzip-8", zlib_decompress},  /* ZIO_COMPRESS_GZIP8 */
  {"gzip-9", zlib_decompress},  /* ZIO_COMPRESS_GZIP9 */
  {"zle", zle_decompress},      /* ZIO_COMPRESS_ZLE   */
  {"lz4", lz4_decompress},      /* ZIO_COMPRESS_LZ4   */
};

static grub_err_t zio_read_data (blkptr_t * bp, grub_zfs_endian_t endian,
				 void *buf, struct grub_zfs_data *data);

/*
 * Our own version of log2().  Same thing as highbit()-1.
 */
static int
zfs_log2 (grub_uint64_t num)
{
  int i = 0;

  while (num > 1)
    {
      i++;
      num = num >> 1;
    }

  return i;
}

/* Checksum Functions */
static void
zio_checksum_off (const void *buf __attribute__ ((unused)),
		  grub_uint64_t size __attribute__ ((unused)),
		  grub_zfs_endian_t endian __attribute__ ((unused)),
		  zio_cksum_t * zcp)
{
  ZIO_SET_CHECKSUM (zcp, 0, 0, 0, 0);
}

/* Checksum Table and Values */
static zio_checksum_info_t zio_checksum_table[ZIO_CHECKSUM_FUNCTIONS] = {
  {NULL, 0, 0, "inherit"},
  {NULL, 0, 0, "on"},
  {zio_checksum_off, 0, 0, "off"},
  {zio_checksum_SHA256, 1, 1, "label"},
  {zio_checksum_SHA256, 1, 1, "gang_header"},
  {NULL, 0, 0, "zilog"},
  {fletcher_2, 0, 0, "fletcher2"},
  {fletcher_4, 1, 0, "fletcher4"},
  {zio_checksum_SHA256, 1, 0, "SHA256"},
  {NULL, 0, 0, "zilog2"},
  {zio_checksum_SHA256, 1, 0, "SHA256+MAC"},
};

/*
 * zio_checksum_verify: Provides support for checksum verification.
 *
 * Fletcher2, Fletcher4, and SHA256 are supported.
 *
 */
static grub_err_t
zio_checksum_verify (zio_cksum_t zc, grub_uint32_t checksum,
		     grub_zfs_endian_t endian, 
		     char *buf, grub_size_t size)
{
  zio_eck_t *zec = (zio_eck_t *) (buf + size) - 1;
  zio_checksum_info_t *ci = &zio_checksum_table[checksum];
  zio_cksum_t actual_cksum, expected_cksum;

  if (checksum >= ZIO_CHECKSUM_FUNCTIONS || ci->ci_func == NULL)
    {
      grub_dprintf ("zfs", "unknown checksum function %d\n", checksum);
      return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, 
			 "unknown checksum function %d", checksum);
    }

  if (ci->ci_eck)
    {
      expected_cksum = zec->zec_cksum;  
      zec->zec_cksum = zc;  
      ci->ci_func (buf, size, endian, &actual_cksum);
      zec->zec_cksum = expected_cksum;
      zc = expected_cksum;
    }
  else
    ci->ci_func (buf, size, endian, &actual_cksum);

  if (grub_memcmp (&actual_cksum, &zc,
		   checksum != ZIO_CHECKSUM_SHA256_MAC ? 32 : 20) != 0)
    {
      grub_dprintf ("zfs", "checksum %s verification failed\n", ci->ci_name);
      grub_dprintf ("zfs", "actual checksum %016llx %016llx %016llx %016llx\n",
		    (unsigned long long) actual_cksum.zc_word[0], 
		    (unsigned long long) actual_cksum.zc_word[1],
		    (unsigned long long) actual_cksum.zc_word[2], 
		    (unsigned long long) actual_cksum.zc_word[3]);
      grub_dprintf ("zfs", "expected checksum %016llx %016llx %016llx %016llx\n",
		    (unsigned long long) zc.zc_word[0], 
		    (unsigned long long) zc.zc_word[1],
		    (unsigned long long) zc.zc_word[2], 
		    (unsigned long long) zc.zc_word[3]);
      return grub_error (GRUB_ERR_BAD_FS, N_("checksum verification failed"));
    }

  return GRUB_ERR_NONE;
}

/*
 * vdev_uberblock_compare takes two uberblock structures and returns an integer
 * indicating the more recent of the two.
 * 	Return Value = 1 if ub2 is more recent
 * 	Return Value = -1 if ub1 is more recent
 * The most recent uberblock is determined using its transaction number and
 * timestamp.  The uberblock with the highest transaction number is
 * considered "newer".  If the transaction numbers of the two blocks match, the
 * timestamps are compared to determine the "newer" of the two.
 */
static int
vdev_uberblock_compare (uberblock_t * ub1, uberblock_t * ub2)
{
  grub_zfs_endian_t ub1_endian, ub2_endian;
  if (grub_zfs_to_cpu64 (ub1->ub_magic, GRUB_ZFS_LITTLE_ENDIAN)
      == UBERBLOCK_MAGIC)
    ub1_endian = GRUB_ZFS_LITTLE_ENDIAN;
  else
    ub1_endian = GRUB_ZFS_BIG_ENDIAN;
  if (grub_zfs_to_cpu64 (ub2->ub_magic, GRUB_ZFS_LITTLE_ENDIAN)
      == UBERBLOCK_MAGIC)
    ub2_endian = GRUB_ZFS_LITTLE_ENDIAN;
  else
    ub2_endian = GRUB_ZFS_BIG_ENDIAN;

  if (grub_zfs_to_cpu64 (ub1->ub_txg, ub1_endian) 
      < grub_zfs_to_cpu64 (ub2->ub_txg, ub2_endian))
    return -1;
  if (grub_zfs_to_cpu64 (ub1->ub_txg, ub1_endian) 
      > grub_zfs_to_cpu64 (ub2->ub_txg, ub2_endian))
    return 1;

  if (grub_zfs_to_cpu64 (ub1->ub_timestamp, ub1_endian) 
      < grub_zfs_to_cpu64 (ub2->ub_timestamp, ub2_endian))
    return -1;
  if (grub_zfs_to_cpu64 (ub1->ub_timestamp, ub1_endian) 
      > grub_zfs_to_cpu64 (ub2->ub_timestamp, ub2_endian))
    return 1;

  return 0;
}

/*
 * Three pieces of information are needed to verify an uberblock: the magic
 * number, the version number, and the checksum.
 *
 * Currently Implemented: version number, magic number, checksum
 *
 */
static grub_err_t
uberblock_verify (uberblock_phys_t * ub, grub_uint64_t offset,
		  grub_size_t s)
{
  uberblock_t *uber = &ub->ubp_uberblock;
  grub_err_t err;
  grub_zfs_endian_t endian = GRUB_ZFS_UNKNOWN_ENDIAN;
  zio_cksum_t zc;

  if (grub_zfs_to_cpu64 (uber->ub_magic, GRUB_ZFS_LITTLE_ENDIAN)
      == UBERBLOCK_MAGIC
      && SPA_VERSION_IS_SUPPORTED(grub_zfs_to_cpu64 (uber->ub_version, GRUB_ZFS_LITTLE_ENDIAN)))
    endian = GRUB_ZFS_LITTLE_ENDIAN;

  if (grub_zfs_to_cpu64 (uber->ub_magic, GRUB_ZFS_BIG_ENDIAN) == UBERBLOCK_MAGIC
      && SPA_VERSION_IS_SUPPORTED(grub_zfs_to_cpu64 (uber->ub_version, GRUB_ZFS_BIG_ENDIAN)))
    endian = GRUB_ZFS_BIG_ENDIAN;

  if (endian == GRUB_ZFS_UNKNOWN_ENDIAN)
    return grub_error (GRUB_ERR_BAD_FS, "invalid uberblock magic");

  grub_memset (&zc, 0, sizeof (zc));

  zc.zc_word[0] = grub_cpu_to_zfs64 (offset, endian);
  err = zio_checksum_verify (zc, ZIO_CHECKSUM_LABEL, endian,
			     (char *) ub, s);

  return err;
}

/*
 * Find the best uberblock.
 * Return:
 *    Success - Pointer to the best uberblock.
 *    Failure - NULL
 */
static uberblock_phys_t *
find_bestub (uberblock_phys_t * ub_array,
	     const struct grub_zfs_device_desc *desc)
{
  uberblock_phys_t *ubbest = NULL, *ubptr;
  int i;
  grub_disk_addr_t offset;
  grub_err_t err = GRUB_ERR_NONE;
  int ub_shift;

  ub_shift = desc->ashift;
  if (ub_shift < VDEV_UBERBLOCK_SHIFT)
    ub_shift = VDEV_UBERBLOCK_SHIFT;

  for (i = 0; i < (VDEV_UBERBLOCK_RING >> ub_shift); i++)
    {
      offset = (desc->vdev_phys_sector << SPA_MINBLOCKSHIFT) + VDEV_PHYS_SIZE
	+ (i << ub_shift);

      ubptr = (uberblock_phys_t *) ((grub_properly_aligned_t *) ub_array
				    + ((i << ub_shift)
				       / sizeof (grub_properly_aligned_t)));
      err = uberblock_verify (ubptr, offset, 1 << ub_shift);
      if (err)
	{
	  grub_errno = GRUB_ERR_NONE;
	  continue;
	}
      if (ubbest == NULL 
	  || vdev_uberblock_compare (&(ubptr->ubp_uberblock),
				     &(ubbest->ubp_uberblock)) > 0)
	ubbest = ubptr;
    }
  if (!ubbest)
    grub_errno = err;

  return ubbest;
}

static inline grub_size_t
get_psize (blkptr_t * bp, grub_zfs_endian_t endian)
{
  return ((((grub_zfs_to_cpu64 ((bp)->blk_prop, endian) >> 16) & 0xffff) + 1)
	  << SPA_MINBLOCKSHIFT);
}

static grub_uint64_t
dva_get_offset (const dva_t *dva, grub_zfs_endian_t endian)
{
  grub_dprintf ("zfs", "dva=%llx, %llx\n", 
		(unsigned long long) dva->dva_word[0], 
		(unsigned long long) dva->dva_word[1]);
  return grub_zfs_to_cpu64 ((dva)->dva_word[1], 
			    endian) << SPA_MINBLOCKSHIFT;
}

static grub_err_t
zfs_fetch_nvlist (struct grub_zfs_device_desc *diskdesc, char **nvlist)
{
  grub_err_t err;

  *nvlist = 0;

  if (!diskdesc->dev)
    return grub_error (GRUB_ERR_BUG, "member drive unknown");

  *nvlist = grub_malloc (VDEV_PHYS_SIZE);

  /* Read in the vdev name-value pair list (112K). */
  err = grub_disk_read (diskdesc->dev->disk, diskdesc->vdev_phys_sector, 0,
			VDEV_PHYS_SIZE, *nvlist);
  if (err)
    {
      grub_free (*nvlist);
      *nvlist = 0;
      return err;
    }
  return GRUB_ERR_NONE;
}

static grub_err_t
fill_vdev_info_real (struct grub_zfs_data *data,
		     const char *nvlist,
		     struct grub_zfs_device_desc *fill,
		     struct grub_zfs_device_desc *insert,
		     int *inserted,
		     unsigned ashift)
{
  char *type;

  type = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_TYPE);

  if (!type)
    return grub_errno;

  if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "id", &(fill->id)))
    {
      grub_free (type);
      return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev id");
    }

  if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "guid", &(fill->guid)))
    {
      grub_free (type);
      return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev id");
    }

  {
    grub_uint64_t par;
    if (grub_zfs_nvlist_lookup_uint64 (nvlist, "ashift", &par))
      fill->ashift = par;
    else if (ashift != 0xffffffff)
      fill->ashift = ashift;
    else
      {
	grub_free (type);
	return grub_error (GRUB_ERR_BAD_FS, "couldn't find ashift");
      }
  }

  fill->max_children_ashift = 0;

  if (grub_strcmp (type, VDEV_TYPE_DISK) == 0
      || grub_strcmp (type, VDEV_TYPE_FILE) == 0)
    {
      fill->type = DEVICE_LEAF;

      if (!fill->dev && fill->guid == insert->guid)
	{
	  fill->dev = insert->dev;
	  fill->vdev_phys_sector = insert->vdev_phys_sector;
	  fill->current_uberblock = insert->current_uberblock;
	  fill->original = insert->original;
	  if (!data->device_original)
	    data->device_original = fill;
	  insert->ashift = fill->ashift;
	  *inserted = 1;
	}

      grub_free (type);

      return GRUB_ERR_NONE;
    }

  if (grub_strcmp (type, VDEV_TYPE_MIRROR) == 0
      || grub_strcmp (type, VDEV_TYPE_RAIDZ) == 0)
    {
      int nelm, i;

      if (grub_strcmp (type, VDEV_TYPE_MIRROR) == 0)
	fill->type = DEVICE_MIRROR;
      else
	{
	  grub_uint64_t par;
	  fill->type = DEVICE_RAIDZ;
	  if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "nparity", &par))
	    {
	      grub_free (type);
	      return grub_error (GRUB_ERR_BAD_FS, "couldn't find raidz parity");
	    }
	  fill->nparity = par;
	}

      nelm = grub_zfs_nvlist_lookup_nvlist_array_get_nelm (nvlist,
							   ZPOOL_CONFIG_CHILDREN);

      if (nelm <= 0)
	{
	  grub_free (type);
	  return grub_error (GRUB_ERR_BAD_FS, "incorrect mirror VDEV");
	}

      if (!fill->children)
	{
	  fill->n_children = nelm;
	  
	  fill->children = grub_zalloc (fill->n_children
					* sizeof (fill->children[0]));
	}

      for (i = 0; i < nelm; i++)
	{
	  char *child;
	  grub_err_t err;

	  child = grub_zfs_nvlist_lookup_nvlist_array
	    (nvlist, ZPOOL_CONFIG_CHILDREN, i);

	  err = fill_vdev_info_real (data, child, &fill->children[i], insert,
				     inserted, fill->ashift);

	  grub_free (child);

	  if (err)
	    {
	      grub_free (type);
	      return err;
	    }
	  if (fill->children[i].ashift > fill->max_children_ashift)
	    fill->max_children_ashift = fill->children[i].ashift;
	}
      grub_free (type);
      return GRUB_ERR_NONE;
    }

  grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "vdev %s isn't supported", type);
  grub_free (type);
  return grub_errno;
}

static grub_err_t
fill_vdev_info (struct grub_zfs_data *data,
		char *nvlist, struct grub_zfs_device_desc *diskdesc,
		int *inserted)
{
  grub_uint64_t id;
  unsigned i;

  *inserted = 0;

  if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "id", &id))
    return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev id");

  for (i = 0; i < data->n_devices_attached; i++)
    if (data->devices_attached[i].id == id)
      return fill_vdev_info_real (data, nvlist, &data->devices_attached[i],
				  diskdesc, inserted, 0xffffffff);

  data->n_devices_attached++;
  if (data->n_devices_attached > data->n_devices_allocated)
    {
      void *tmp;
      data->n_devices_allocated = 2 * data->n_devices_attached + 1;
      data->devices_attached
	= grub_realloc (tmp = data->devices_attached,
			data->n_devices_allocated
			* sizeof (data->devices_attached[0]));
      if (!data->devices_attached)
	{
	  data->devices_attached = tmp;
	  return grub_errno;
	}
    }

  grub_memset (&data->devices_attached[data->n_devices_attached - 1],
	       0, sizeof (data->devices_attached[data->n_devices_attached - 1]));

  return fill_vdev_info_real (data, nvlist,
			      &data->devices_attached[data->n_devices_attached - 1],
			      diskdesc, inserted, 0xffffffff);
}

/*
 * For a given XDR packed nvlist, verify the first 4 bytes and move on.
 *
 * An XDR packed nvlist is encoded as (comments from nvs_xdr_create) :
 *
 *      encoding method/host endian     (4 bytes)
 *      nvl_version                     (4 bytes)
 *      nvl_nvflag                      (4 bytes)
 *	encoded nvpairs:
 *		encoded size of the nvpair      (4 bytes)
 *		decoded size of the nvpair      (4 bytes)
 *		name string size                (4 bytes)
 *		name string data                (sizeof(NV_ALIGN4(string))
 *		data type                       (4 bytes)
 *		# of elements in the nvpair     (4 bytes)
 *		data
 *      2 zero's for the last nvpair
 *		(end of the entire list)	(8 bytes)
 *
 */

/*
 * The nvlist_next_nvpair() function returns a handle to the next nvpair in the
 * list following nvpair. If nvpair is NULL, the first pair is returned. If
 * nvpair is the last pair in the nvlist, NULL is returned.
 */
static const char *
nvlist_next_nvpair (const char *nvl, const char *nvpair)
{
  const char *nvp;
  int encode_size;
  int name_len;
  if (nvl == NULL)
    return NULL;

  if (nvpair == NULL)
    {
      /* skip over header, nvl_version and nvl_nvflag */
      nvpair = nvl + 4 * 3;
    } 
  else
    {
      /* skip to the next nvpair */
      encode_size = grub_be_to_cpu32 (grub_get_unaligned32(nvpair));
      nvpair += encode_size;
      /*If encode_size equals 0 nvlist_next_nvpair would return
       * the same pair received in input, leading to an infinite loop.
       * If encode_size is less than 0, this will move the pointer
       * backwards, *possibly* examinining two times the same nvpair
       * and potentially getting into an infinite loop. */
      if(encode_size <= 0)
	{
	  grub_dprintf ("zfs", "nvpair with size <= 0\n");
	  grub_error (GRUB_ERR_BAD_FS, "incorrect nvlist");
	  return NULL;
	}
    }
  /* 8 bytes of 0 marks the end of the list */
  if (grub_get_unaligned64 (nvpair) == 0)
    return NULL;
  /*consistency checks*/
  if (nvpair + 4 * 3 >= nvl + VDEV_PHYS_SIZE)
    {
      grub_dprintf ("zfs", "nvlist overflow\n");
      grub_error (GRUB_ERR_BAD_FS, "incorrect nvlist");
      return NULL;
    }
  encode_size = grub_be_to_cpu32 (grub_get_unaligned32(nvpair));

  nvp = nvpair + 4*2;
  name_len = grub_be_to_cpu32 (grub_get_unaligned32 (nvp));
  nvp += 4;

  nvp = nvp + ((name_len + 3) & ~3); // align 
  if (nvp + 4 >= nvl + VDEV_PHYS_SIZE                        
      || encode_size < 0
      || nvp + 4 + encode_size > nvl + VDEV_PHYS_SIZE)       
    {
      grub_dprintf ("zfs", "nvlist overflow\n");
      grub_error (GRUB_ERR_BAD_FS, "incorrect nvlist");
      return NULL;
    }
  /* end consistency checks */

  return nvpair;
}

/*
 * This function returns 0 on success and 1 on failure. On success, a string
 * containing the name of nvpair is saved in buf.
 */
static int
nvpair_name (const char *nvp, char **buf, grub_size_t *buflen)
{
  /* skip over encode/decode size */
  nvp += 4 * 2;
	
  *buf = (char *) (nvp + 4);
  *buflen = grub_be_to_cpu32 (grub_get_unaligned32 (nvp));

  return 0;
}

/*
 * This function retrieves the value of the nvpair in the form of enumerated
 * type data_type_t.
 */
static int
nvpair_type (const char *nvp)
{
  int name_len, type;

  /* skip over encode/decode size */
  nvp += 4 * 2;

  /* skip over name_len */
  name_len = grub_be_to_cpu32 (grub_get_unaligned32 (nvp));
  nvp += 4;

  /* skip over name */
  nvp = nvp + ((name_len + 3) & ~3); /* align */

  type = grub_be_to_cpu32 (grub_get_unaligned32 (nvp));

  return type;
}

static int
nvpair_value (const char *nvp,char **val,
	      grub_size_t *size_out, grub_size_t *nelm_out)
{
  int name_len,nelm,encode_size;

  /* skip over encode/decode size */
  encode_size = grub_be_to_cpu32 (grub_get_unaligned32(nvp));
  nvp += 8;

  /* skip over name_len */
  name_len = grub_be_to_cpu32 (grub_get_unaligned32 (nvp));
  nvp += 4;

  /* skip over name */
  nvp = nvp + ((name_len + 3) & ~3); /* align */
	
  /* skip over type */
  nvp += 4;
  nelm = grub_be_to_cpu32 (grub_get_unaligned32 (nvp));
  nvp +=4;
  if (nelm < 1)
    {
      grub_error (GRUB_ERR_BAD_FS, "empty nvpair");
      return 0;
    }
  *val = (char *) nvp;
  *size_out = encode_size;
  if (nelm_out)
    *nelm_out = nelm;
	    
  return 1;
}

/*
 * Check the disk label information and retrieve needed vdev name-value pairs.
 *
 */
static grub_err_t
check_pool_label (struct grub_zfs_data *data,
		  struct grub_zfs_device_desc *diskdesc,
		  int *inserted, int original)
{
  grub_uint64_t pool_state, txg = 0;
  char *nvlist,*features;
#if 0
  char *nv;
#endif
  grub_uint64_t poolguid;
  grub_uint64_t version;
  int found;
  grub_err_t err;
  grub_zfs_endian_t endian;
  vdev_phys_t *phys;
  zio_cksum_t emptycksum;

  *inserted = 0;

  err = zfs_fetch_nvlist (diskdesc, &nvlist);
  if (err)
    return err;

  phys = (vdev_phys_t*) nvlist;
  if (grub_zfs_to_cpu64 (phys->vp_zbt.zec_magic,
			 GRUB_ZFS_LITTLE_ENDIAN)
      == ZEC_MAGIC)
    endian = GRUB_ZFS_LITTLE_ENDIAN;
  else if (grub_zfs_to_cpu64 (phys->vp_zbt.zec_magic,
			      GRUB_ZFS_BIG_ENDIAN)
	   == ZEC_MAGIC)
    endian = GRUB_ZFS_BIG_ENDIAN;
  else
    {
      grub_free (nvlist);
      return grub_error (GRUB_ERR_BAD_FS,
			 "bad vdev_phys_t.vp_zbt.zec_magic number");
    }
  /* Now check the integrity of the vdev_phys_t structure though checksum.  */
  ZIO_SET_CHECKSUM(&emptycksum, diskdesc->vdev_phys_sector << 9, 0, 0, 0);
  err = zio_checksum_verify (emptycksum, ZIO_CHECKSUM_LABEL, endian,
			     nvlist, VDEV_PHYS_SIZE);
  if (err)
    return err;

  grub_dprintf ("zfs", "check 2 passed\n");

  found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_STATE,
					 &pool_state);
  if (! found)
    {
      grub_free (nvlist);
      if (! grub_errno)
	grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_POOL_STATE " not found");
      return grub_errno;
    }
  grub_dprintf ("zfs", "check 3 passed\n");

  if (pool_state == POOL_STATE_DESTROYED)
    {
      grub_free (nvlist);
      return grub_error (GRUB_ERR_BAD_FS, "zpool is marked as destroyed");
    }
  grub_dprintf ("zfs", "check 4 passed\n");

  found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_TXG, &txg);
  if (!found)
    {
      grub_free (nvlist);
      if (! grub_errno)
	grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_POOL_TXG " not found");
      return grub_errno;
    }
  grub_dprintf ("zfs", "check 6 passed\n");

  /* not an active device */
  if (txg == 0)
    {
      grub_free (nvlist);
      return grub_error (GRUB_ERR_BAD_FS, "zpool isn't active");
    }
  grub_dprintf ("zfs", "check 7 passed\n");

  found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_VERSION,
					 &version);
  if (! found)
    {
      grub_free (nvlist);
      if (! grub_errno)
	grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_VERSION " not found");
      return grub_errno;
    }
  grub_dprintf ("zfs", "check 8 passed\n");

  if (!SPA_VERSION_IS_SUPPORTED(version))
    {
      grub_free (nvlist);
      return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
			 "too new version %llu > %llu",
			 (unsigned long long) version,
			 (unsigned long long) SPA_VERSION_BEFORE_FEATURES);
    }
  grub_dprintf ("zfs", "check 9 passed\n");

  found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_GUID,
					 &(diskdesc->guid));
  if (! found)
    {
      grub_free (nvlist);
      if (! grub_errno)
	grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_GUID " not found");
      return grub_errno;
    }

  found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_GUID,
					 &poolguid);
  if (! found)
    {
      grub_free (nvlist);
      if (! grub_errno)
	grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_POOL_GUID " not found");
      return grub_errno;
    }

  grub_dprintf ("zfs", "check 11 passed\n");

  if (original)
    data->guid = poolguid;

  if (data->guid != poolguid)
    return grub_error (GRUB_ERR_BAD_FS, "another zpool");

  {
    char *nv;
    nv = grub_zfs_nvlist_lookup_nvlist (nvlist, ZPOOL_CONFIG_VDEV_TREE);

    if (!nv)
      {
	grub_free (nvlist);
	return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev tree");
      }
    err = fill_vdev_info (data, nv, diskdesc, inserted);
    if (err)
      {
	grub_free (nv);
	grub_free (nvlist);
	return err;
      }
    grub_free (nv);
  }
  grub_dprintf ("zfs", "check 10 passed\n");
  features = grub_zfs_nvlist_lookup_nvlist(nvlist,
					   ZPOOL_CONFIG_FEATURES_FOR_READ);
  if (features)
    {
      const char *nvp=NULL;
      char name[MAX_SUPPORTED_FEATURE_STRLEN + 1];
      char *nameptr;
      grub_size_t namelen;
      while ((nvp = nvlist_next_nvpair(features, nvp)) != NULL)
	{
	  nvpair_name (nvp, &nameptr, &namelen);
	  if(namelen > MAX_SUPPORTED_FEATURE_STRLEN)
	    namelen = MAX_SUPPORTED_FEATURE_STRLEN;
	  grub_memcpy (name, nameptr, namelen);
	  name[namelen] = '\0';
	  grub_dprintf("zfs","str=%s\n",name);
	  if (check_feature(name,1, NULL) != 0)
	    {
	      grub_dprintf("zfs","feature missing in check_pool_label:%s\n",name);
	      err= grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET," check_pool_label missing feature '%s' for read",name);
	      return err;
	    }
	}
    }
  grub_dprintf ("zfs", "check 12 passed (feature flags)\n");
  grub_free (nvlist);

  return GRUB_ERR_NONE;
}

static grub_err_t
scan_disk (grub_device_t dev, struct grub_zfs_data *data,
	   int original, int *inserted)
{
  int label = 0;
  uberblock_phys_t *ub_array, *ubbest = NULL;
  vdev_boot_header_t *bh;
  grub_err_t err;
  int vdevnum;
  struct grub_zfs_device_desc desc;

  ub_array = grub_malloc (VDEV_UBERBLOCK_RING);
  if (!ub_array)
    return grub_errno;

  bh = grub_malloc (VDEV_BOOT_HEADER_SIZE);
  if (!bh)
    {
      grub_free (ub_array);
      return grub_errno;
    }

  vdevnum = VDEV_LABELS;

  desc.dev = dev;
  desc.original = original;

  /* Don't check back labels on CDROM.  */
  if (grub_disk_get_size (dev->disk) == GRUB_DISK_SIZE_UNKNOWN)
    vdevnum = VDEV_LABELS / 2;

  for (label = 0; ubbest == NULL && label < vdevnum; label++)
    {
      desc.vdev_phys_sector
	= label * (sizeof (vdev_label_t) >> SPA_MINBLOCKSHIFT)
	+ ((VDEV_SKIP_SIZE + VDEV_BOOT_HEADER_SIZE) >> SPA_MINBLOCKSHIFT)
	+ (label < VDEV_LABELS / 2 ? 0 : 
	   ALIGN_DOWN (grub_disk_get_size (dev->disk), sizeof (vdev_label_t))
	   - VDEV_LABELS * (sizeof (vdev_label_t) >> SPA_MINBLOCKSHIFT));

      /* Read in the uberblock ring (128K). */
      err = grub_disk_read (dev->disk, desc.vdev_phys_sector
			    + (VDEV_PHYS_SIZE >> SPA_MINBLOCKSHIFT),
			    0, VDEV_UBERBLOCK_RING, (char *) ub_array);
      if (err)
	{
	  grub_errno = GRUB_ERR_NONE;
	  continue;
	}
      grub_dprintf ("zfs", "label ok %d\n", label);

      err = check_pool_label (data, &desc, inserted, original);
      if (err || !*inserted)
	{
	  grub_errno = GRUB_ERR_NONE;
	  continue;
	}

      ubbest = find_bestub (ub_array, &desc);
      if (!ubbest)
	{
	  grub_dprintf ("zfs", "No uberblock found\n");
	  grub_errno = GRUB_ERR_NONE;
	  continue;
	}

      grub_memmove (&(desc.current_uberblock),
		    &ubbest->ubp_uberblock, sizeof (uberblock_t));
      if (original)
	grub_memmove (&(data->current_uberblock),
		      &ubbest->ubp_uberblock, sizeof (uberblock_t));

#if 0
      if (find_best_root &&
	  vdev_uberblock_compare (&ubbest->ubp_uberblock,
				  &(current_uberblock)) <= 0)
	continue;
#endif
      grub_free (ub_array);
      grub_free (bh);
      return GRUB_ERR_NONE;
    }
  
  grub_free (ub_array);
  grub_free (bh);

  return grub_error (GRUB_ERR_BAD_FS, "couldn't find a valid label");
}

/* Helper for scan_devices.  */
static int
scan_devices_iter (const char *name, void *hook_data)
{
  struct grub_zfs_data *data = hook_data;
  grub_device_t dev;
  grub_err_t err;
  int inserted;

  dev = grub_device_open (name);
  if (!dev)
    return 0;
  if (!dev->disk)
    {
      grub_device_close (dev);
      return 0;
    }
  err = scan_disk (dev, data, 0, &inserted);
  if (err == GRUB_ERR_BAD_FS)
    {
      grub_device_close (dev);
      grub_errno = GRUB_ERR_NONE;
      return 0;
    }
  if (err)
    {
      grub_device_close (dev);
      grub_print_error ();
      return 0;
    }

  if (!inserted)
    grub_device_close (dev);
  
  return 0;
}

static grub_err_t
scan_devices (struct grub_zfs_data *data)
{
  grub_device_iterate (scan_devices_iter, data);
  return GRUB_ERR_NONE;
}

/* x**y.  */
static grub_uint8_t powx[255 * 2];
/* Such an s that x**s = y */
static int powx_inv[256];
static const grub_uint8_t poly = 0x1d;

/* perform the operation a ^= b * (x ** (known_idx * recovery_pow) ) */
static inline void
xor_out (grub_uint8_t *a, const grub_uint8_t *b, grub_size_t s,
	 unsigned known_idx, unsigned recovery_pow)
{
  unsigned add;

  /* Simple xor.  */
  if (known_idx == 0 || recovery_pow == 0)
    {
      grub_crypto_xor (a, a, b, s);
      return;
    }
  add = (known_idx * recovery_pow) % 255;
  for (;s--; b++, a++)
    if (*b)
      *a ^= powx[powx_inv[*b] + add];
}

static inline grub_uint8_t
gf_mul (grub_uint8_t a, grub_uint8_t b)
{
  if (a == 0 || b == 0)
    return 0;
  return powx[powx_inv[a] + powx_inv[b]];
}

#define MAX_NBUFS 4

static grub_err_t
recovery (grub_uint8_t *bufs[4], grub_size_t s, const int nbufs,
	  const unsigned *powers,
	  const unsigned *idx)
{
  grub_dprintf ("zfs", "recovering %u buffers\n", nbufs);
  /* Now we have */
  /* b_i = sum (r_j* (x ** (powers[i] * idx[j])))*/
  /* Let's invert the matrix in question. */
  switch (nbufs)
    {
      /* Easy: r_0 = bufs[0] / (x << (powers[i] * idx[j])).  */
    case 1:
      {
	int add;
	grub_uint8_t *a;
	if (powers[0] == 0 || idx[0] == 0)
	  return GRUB_ERR_NONE;
	add = 255 - ((powers[0] * idx[0]) % 255);
	for (a = bufs[0]; s--; a++)
	  if (*a)
	    *a = powx[powx_inv[*a] + add];
	return GRUB_ERR_NONE;
      }
      /* Case 2x2: Let's use the determinant formula.  */
    case 2:
      {
	grub_uint8_t det, det_inv;
	grub_uint8_t matrixinv[2][2];
	unsigned i;
	/* The determinant is: */
	det = (powx[(powers[0] * idx[0] + powers[1] * idx[1]) % 255]
	       ^ powx[(powers[0] * idx[1] + powers[1] * idx[0]) % 255]);
	if (det == 0)
	  return grub_error (GRUB_ERR_BAD_FS, "singular recovery matrix");
	det_inv = powx[255 - powx_inv[det]];
	matrixinv[0][0] = gf_mul (powx[(powers[1] * idx[1]) % 255], det_inv);
	matrixinv[1][1] = gf_mul (powx[(powers[0] * idx[0]) % 255], det_inv);
	matrixinv[0][1] = gf_mul (powx[(powers[0] * idx[1]) % 255], det_inv);
	matrixinv[1][0] = gf_mul (powx[(powers[1] * idx[0]) % 255], det_inv);
	for (i = 0; i < s; i++)
	  {
	    grub_uint8_t b0, b1;
	    b0 = bufs[0][i];
	    b1 = bufs[1][i];

	    bufs[0][i] = (gf_mul (b0, matrixinv[0][0])
			  ^ gf_mul (b1, matrixinv[0][1]));
	    bufs[1][i] = (gf_mul (b0, matrixinv[1][0])
			  ^ gf_mul (b1, matrixinv[1][1]));
	  }
	return GRUB_ERR_NONE;
      }
      /* Otherwise use Gauss.  */
    case 3:
      {
	grub_uint8_t matrix1[MAX_NBUFS][MAX_NBUFS], matrix2[MAX_NBUFS][MAX_NBUFS];
	int i, j, k;

	for (i = 0; i < nbufs; i++)
	  for (j = 0; j < nbufs; j++)
	    matrix1[i][j] = powx[(powers[i] * idx[j]) % 255];
	for (i = 0; i < nbufs; i++)
	  for (j = 0; j < nbufs; j++)
	    matrix2[i][j] = 0;
	for (i = 0; i < nbufs; i++)
	  matrix2[i][i] = 1;

	for (i = 0; i < nbufs; i++)
	  {
	    grub_uint8_t mul;
	    for (j = i; j < nbufs; j++)	    
	      if (matrix1[i][j])
		break;
	    if (j == nbufs)
	      return grub_error (GRUB_ERR_BAD_FS, "singular recovery matrix");
	    if (j != i)
	      {
		int xchng;
		xchng = j;
		for (j = 0; j < nbufs; j++)
		  {
		    grub_uint8_t t;
		    t = matrix1[xchng][j];
		    matrix1[xchng][j] = matrix1[i][j];
		    matrix1[i][j] = t;
		  }
		for (j = 0; j < nbufs; j++)
		  {
		    grub_uint8_t t;
		    t = matrix2[xchng][j];
		    matrix2[xchng][j] = matrix2[i][j];
		    matrix2[i][j] = t;
		  }
	      }
	    mul = powx[255 - powx_inv[matrix1[i][i]]];
	    for (j = 0; j < nbufs; j++)
	      matrix1[i][j] = gf_mul (matrix1[i][j], mul);
	    for (j = 0; j < nbufs; j++)
	      matrix2[i][j] = gf_mul (matrix2[i][j], mul);
	    for (j = i + 1; j < nbufs; j++)
	      {
		mul = matrix1[j][i];
		for (k = 0; k < nbufs; k++)
		  matrix1[j][k] ^= gf_mul (matrix1[i][k], mul);
		for (k = 0; k < nbufs; k++)
		  matrix2[j][k] ^= gf_mul (matrix2[i][k], mul);
	      }
	  }
	for (i = nbufs - 1; i >= 0; i--)
	  {
	    for (j = 0; j < i; j++)
	      {
		grub_uint8_t mul;
		mul = matrix1[j][i];
		for (k = 0; k < nbufs; k++)
		  matrix1[j][k] ^= gf_mul (matrix1[i][k], mul);
		for (k = 0; k < nbufs; k++)
		  matrix2[j][k] ^= gf_mul (matrix2[i][k], mul);
	      }
	  }

	for (i = 0; i < (int) s; i++)
	  {
	    grub_uint8_t b[MAX_NBUFS];
	    for (j = 0; j < nbufs; j++)
	      b[j] = bufs[j][i];
	    for (j = 0; j < nbufs; j++)
	      {
		bufs[j][i] = 0;
		for (k = 0; k < nbufs; k++)
		  bufs[j][i] ^= gf_mul (matrix2[j][k], b[k]);
	      }
	  }
	return GRUB_ERR_NONE;
      }
    default:
      return grub_error (GRUB_ERR_BUG, "too big matrix");
    }      
}

static grub_err_t
read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc,
	     grub_size_t len, void *buf)
{
  switch (desc->type)
    {
    case DEVICE_LEAF:
      {
	grub_uint64_t sector;
	sector = DVA_OFFSET_TO_PHYS_SECTOR (offset);
	if (!desc->dev)
	  {
	    return grub_error (GRUB_ERR_BAD_FS,
			       N_("couldn't find a necessary member device "
				  "of multi-device filesystem"));
	  }
	/* read in a data block */
	return grub_disk_read (desc->dev->disk, sector, 0, len, buf);
      }
    case DEVICE_MIRROR:
      {
	grub_err_t err = GRUB_ERR_NONE;
	unsigned i;
	if (desc->n_children <= 0)
	  return grub_error (GRUB_ERR_BAD_FS,
			     "non-positive number of mirror children");
	for (i = 0; i < desc->n_children; i++)
	  {
	    err = read_device (offset, &desc->children[i],
			       len, buf);
	    if (!err)
	      break;
	    grub_errno = GRUB_ERR_NONE;
	  }
	grub_errno = err;

	return err;
      }
    case DEVICE_RAIDZ:
      {
	unsigned c = 0;
	grub_uint64_t high;
	grub_uint64_t devn;
	grub_uint64_t m;
	grub_uint32_t s, orig_s;
	void *orig_buf = buf;
	grub_size_t orig_len = len;
	grub_uint8_t *recovery_buf[4];
	grub_size_t recovery_len[4];
	unsigned recovery_idx[4];
	unsigned failed_devices = 0;
	int idx, orig_idx;

	if (desc->nparity < 1 || desc->nparity > 3)
	  return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, 
			     "raidz%d is not supported", desc->nparity);

	if (desc->n_children <= desc->nparity || desc->n_children < 1)
	  return grub_error(GRUB_ERR_BAD_FS, "too little devices for given parity");

	orig_s = (((len + (1 << desc->ashift) - 1) >> desc->ashift)
		  + (desc->n_children - desc->nparity) - 1);
	s = orig_s;

	high = grub_divmod64 ((offset >> desc->ashift),
			      desc->n_children, &m);
	if (desc->nparity == 2)
	  c = 2;
	if (desc->nparity == 3)
	  c = 3;
	if (((len + (1 << desc->ashift) - 1) >> desc->ashift)
	    >= (desc->n_children - desc->nparity))
	  idx = (desc->n_children - desc->nparity - 1);
	else
	  idx = ((len + (1 << desc->ashift) - 1) >> desc->ashift) - 1;
	orig_idx = idx;
	while (len > 0)
	  {
	    grub_size_t csize;
	    grub_uint32_t bsize;
	    grub_err_t err;
	    bsize = s / (desc->n_children - desc->nparity);

	    if (desc->nparity == 1
		&& ((offset >> (desc->ashift + 20 - desc->max_children_ashift))
		    & 1) == c)
	      c++;

	    high = grub_divmod64 ((offset >> desc->ashift) + c,
				  desc->n_children, &devn);
	    csize = bsize << desc->ashift;
	    if (csize > len)
	      csize = len;

	    grub_dprintf ("zfs", "RAIDZ mapping 0x%" PRIxGRUB_UINT64_T
			  "+%u (%" PRIxGRUB_SIZE ", %" PRIxGRUB_UINT32_T
			  ") -> (0x%" PRIxGRUB_UINT64_T ", 0x%"
			  PRIxGRUB_UINT64_T ")\n",
			  offset >> desc->ashift, c, len, bsize, high,
			  devn);
	    err = read_device ((high << desc->ashift)
			       | (offset & ((1 << desc->ashift) - 1)),
			       &desc->children[devn],
			       csize, buf);
	    if (err && failed_devices < desc->nparity)
	      {
		recovery_buf[failed_devices] = buf;
		recovery_len[failed_devices] = csize;
		recovery_idx[failed_devices] = idx;
		failed_devices++;
		grub_errno = err = 0;
	      }
	    if (err)
	      return err;

	    c++;
	    idx--;
	    s--;
	    buf = (char *) buf + csize;
	    len -= csize;
	  }
	if (failed_devices)
	  {
	    unsigned redundancy_pow[4];
	    unsigned cur_redundancy_pow = 0;
	    unsigned n_redundancy = 0;
	    unsigned i, j;
	    grub_err_t err;

	    /* Compute mul. x**s has a period of 255.  */
	    if (powx[0] == 0)
	      {
		grub_uint8_t cur = 1;
		for (i = 0; i < 255; i++)
		  {
		    powx[i] = cur;
		    powx[i + 255] = cur;
		    powx_inv[cur] = i;
		    if (cur & 0x80)
		      cur = (cur << 1) ^ poly;
		    else
		      cur <<= 1;
		  }
	      }

	    /* Read redundancy data.  */
	    for (n_redundancy = 0, cur_redundancy_pow = 0;
		 n_redundancy < failed_devices;
		 cur_redundancy_pow++)
	      {
		high = grub_divmod64 ((offset >> desc->ashift)
				      + cur_redundancy_pow
				      + ((desc->nparity == 1)
					 && ((offset >> (desc->ashift + 20
							 - desc->max_children_ashift))
					     & 1)),
				      desc->n_children, &devn);
		err = read_device ((high << desc->ashift)
				   | (offset & ((1 << desc->ashift) - 1)),
				   &desc->children[devn],
				   recovery_len[n_redundancy],
				   recovery_buf[n_redundancy]);
		/* Ignore error if we may still have enough devices.  */
		if (err && n_redundancy + desc->nparity - cur_redundancy_pow - 1
		    >= failed_devices)
		  {
		    grub_errno = GRUB_ERR_NONE;
		    continue;
		  }
		if (err)
		  return err;
		redundancy_pow[n_redundancy] = cur_redundancy_pow;
		n_redundancy++;
	      }
	    /* Now xor-our the parts we already know.  */
	    buf = orig_buf;
	    len = orig_len;
	    s = orig_s;
	    idx = orig_idx;

	    while (len > 0)
	      {
		grub_size_t csize;
		csize = ((s / (desc->n_children - desc->nparity))
			 << desc->ashift);
		if (csize > len)
		  csize = len;

		for (j = 0; j < failed_devices; j++)
		  if (buf == recovery_buf[j])
		    break;

		if (j == failed_devices)
		  for (j = 0; j < failed_devices; j++)
		    xor_out (recovery_buf[j], buf,
			     csize < recovery_len[j] ? csize : recovery_len[j],
			     idx, redundancy_pow[j]);

		s--;
		buf = (char *) buf + csize;
		len -= csize;
		idx--;
	      }
	    for (i = 0; i < failed_devices 
		   && recovery_len[i] == recovery_len[0];
		 i++);
	    /* Since the chunks have variable length handle the last block
	       separately.  */
	    if (i != failed_devices)
	      {
		grub_uint8_t *tmp_recovery_buf[4];
		for (j = 0; j < i; j++)
		  tmp_recovery_buf[j] = recovery_buf[j] + recovery_len[failed_devices - 1];
		err = recovery (tmp_recovery_buf, recovery_len[0] - recovery_len[failed_devices - 1], i, redundancy_pow,
				recovery_idx);
		if (err)
		  return err;
	      }
	    err = recovery (recovery_buf, recovery_len[failed_devices - 1],
			    failed_devices, redundancy_pow, recovery_idx);
	    if (err)
	      return err;
	  }
	return GRUB_ERR_NONE;
      }
    }
  return grub_error (GRUB_ERR_BAD_FS, "unsupported device type");
}

static grub_err_t
read_dva (const dva_t *dva,
	  grub_zfs_endian_t endian, struct grub_zfs_data *data,
	  void *buf, grub_size_t len)
{
  grub_uint64_t offset;
  unsigned i;
  grub_err_t err = 0;
  int try = 0;
  offset = dva_get_offset (dva, endian);

  for (try = 0; try < 2; try++)
    {
      for (i = 0; i < data->n_devices_attached; i++)
	if (data->devices_attached[i].id == DVA_GET_VDEV (dva))
	  {
	    err = read_device (offset, &data->devices_attached[i], len, buf);
	    if (!err)
	      return GRUB_ERR_NONE;
	    break;
	  }
      if (try == 1)
	break;
      err = scan_devices (data);
      if (err)
	return err;
    }
  if (!err)
    return grub_error (GRUB_ERR_BAD_FS, "unknown device %d",
		       (int) DVA_GET_VDEV (dva));
  return err;
}

/*
 * Read a block of data based on the gang block address dva,
 * and put its data in buf.
 *
 */
static grub_err_t
zio_read_gang (blkptr_t * bp, grub_zfs_endian_t endian, dva_t * dva, void *buf,
	       struct grub_zfs_data *data)
{
  zio_gbh_phys_t *zio_gb;
  unsigned i;
  grub_err_t err;
  zio_cksum_t zc;

  grub_memset (&zc, 0, sizeof (zc));

  zio_gb = grub_malloc (SPA_GANGBLOCKSIZE);
  if (!zio_gb)
    return grub_errno;
  grub_dprintf ("zfs", endian == GRUB_ZFS_LITTLE_ENDIAN ? "little-endian gang\n"
		:"big-endian gang\n");

  err = read_dva (dva, endian, data, zio_gb, SPA_GANGBLOCKSIZE);
  if (err)
    {
      grub_free (zio_gb);
      return err;
    }

  /* XXX */
  /* self checksuming the gang block header */
  ZIO_SET_CHECKSUM (&zc, DVA_GET_VDEV (dva),
		    dva_get_offset (dva, endian), bp->blk_birth, 0);
  err = zio_checksum_verify (zc, ZIO_CHECKSUM_GANG_HEADER, endian,
			     (char *) zio_gb, SPA_GANGBLOCKSIZE);
  if (err)
    {
      grub_free (zio_gb);
      return err;
    }

  endian = (grub_zfs_to_cpu64 (bp->blk_prop, endian) >> 63) & 1;

  for (i = 0; i < SPA_GBH_NBLKPTRS; i++)
    {
      if (BP_IS_HOLE(&zio_gb->zg_blkptr[i]))
	continue;

      err = zio_read_data (&zio_gb->zg_blkptr[i], endian, buf, data);
      if (err)
	{
	  grub_free (zio_gb);
	  return err;
	}
      buf = (char *) buf + get_psize (&zio_gb->zg_blkptr[i], endian);
    }
  grub_free (zio_gb);
  return GRUB_ERR_NONE;
}

/*
 * Read in a block of raw data to buf.
 */
static grub_err_t
zio_read_data (blkptr_t * bp, grub_zfs_endian_t endian, void *buf, 
	       struct grub_zfs_data *data)
{
  int i, psize;
  grub_err_t err = GRUB_ERR_NONE;

  psize = get_psize (bp, endian);

  /* pick a good dva from the block pointer */
  for (i = 0; i < SPA_DVAS_PER_BP; i++)
    {
      if (bp->blk_dva[i].dva_word[0] == 0 && bp->blk_dva[i].dva_word[1] == 0)
	continue;

      if ((grub_zfs_to_cpu64 (bp->blk_dva[i].dva_word[1], endian)>>63) & 1)
	err = zio_read_gang (bp, endian, &bp->blk_dva[i], buf, data);
      else
	err = read_dva (&bp->blk_dva[i], endian, data, buf, psize);
      if (!err)
	return GRUB_ERR_NONE;
      grub_errno = GRUB_ERR_NONE;
    }

  if (!err)
    err = grub_error (GRUB_ERR_BAD_FS, "couldn't find a valid DVA");
  grub_errno = err;

  return err;
}

/*
 * buf must be at least BPE_GET_PSIZE(bp) bytes long (which will never be
 * more than BPE_PAYLOAD_SIZE bytes).
 */
static grub_err_t
decode_embedded_bp_compressed(const blkptr_t *bp, void *buf)
{
  grub_size_t psize, i;
  grub_uint8_t *buf8 = buf;
  grub_uint64_t w = 0;
  const grub_uint64_t *bp64 = (const grub_uint64_t *)bp;

  psize = BPE_GET_PSIZE(bp);

  /*
   * Decode the words of the block pointer into the byte array.
   * Low bits of first word are the first byte (little endian).
   */
  for (i = 0; i < psize; i++)
    {
      if (i % sizeof (w) == 0)
       {
         /* beginning of a word */
         w = *bp64;
         bp64++;
         if (!BPE_IS_PAYLOADWORD(bp, bp64))
         bp64++;
       }
      buf8[i] = BF64_GET(w, (i % sizeof (w)) * 8, 8);
    }
  return GRUB_ERR_NONE;
}

/*
 * Read in a block of data, verify its checksum, decompress if needed,
 * and put the uncompressed data in buf.
 */
static grub_err_t
zio_read (blkptr_t *bp, grub_zfs_endian_t endian, void **buf, 
	  grub_size_t *size, struct grub_zfs_data *data)
{
  grub_size_t lsize, psize;
  unsigned int comp, encrypted;
  char *compbuf = NULL;
  grub_err_t err;
  zio_cksum_t zc = bp->blk_cksum;
  grub_uint32_t checksum;

  *buf = NULL;

  checksum = (grub_zfs_to_cpu64((bp)->blk_prop, endian) >> 40) & 0xff;
  comp = (grub_zfs_to_cpu64((bp)->blk_prop, endian)>>32) & 0x7f;
  encrypted = ((grub_zfs_to_cpu64((bp)->blk_prop, endian) >> 60) & 3);
  if (BP_IS_EMBEDDED(bp))
    {
      if (BPE_GET_ETYPE(bp) != BP_EMBEDDED_TYPE_DATA)
	return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
			   "unsupported embedded BP (type=%u)\n",
			   BPE_GET_ETYPE(bp));
      lsize = BPE_GET_LSIZE(bp);
      psize = BF64_GET_SB(grub_zfs_to_cpu64 ((bp)->blk_prop, endian), 25, 7, 0, 1);
    }
  else
    {
      lsize = (BP_IS_HOLE(bp) ? 0 :
	       (((grub_zfs_to_cpu64 ((bp)->blk_prop, endian) & 0xffff) + 1)
	        << SPA_MINBLOCKSHIFT));
      psize = get_psize (bp, endian);
    }
  grub_dprintf("zfs", "zio_read: E %d: size %" PRIdGRUB_SSIZE "/%"
	       PRIdGRUB_SSIZE "\n", (int)BP_IS_EMBEDDED(bp), lsize, psize);

  if (size)
    *size = lsize;

  if (comp >= ZIO_COMPRESS_FUNCTIONS)
    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
		       "compression algorithm %u not supported\n", (unsigned int) comp);

  if (comp != ZIO_COMPRESS_OFF && decomp_table[comp].decomp_func == NULL)
    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
		       "compression algorithm %s not supported\n", decomp_table[comp].name);

  if (comp != ZIO_COMPRESS_OFF)
    /* It's not really necessary to align to 16, just for safety.  */
    compbuf = grub_malloc (ALIGN_UP (psize, 16));
  else
    compbuf = *buf = grub_malloc (lsize);
  if (! compbuf)
    return grub_errno;

  grub_dprintf ("zfs", "endian = %d\n", endian);
  if (BP_IS_EMBEDDED(bp))
    err = decode_embedded_bp_compressed(bp, compbuf);
  else
    {
      err = zio_read_data (bp, endian, compbuf, data);
      /* FIXME is it really necessary? */
      if (comp != ZIO_COMPRESS_OFF)
	grub_memset (compbuf + psize, 0, ALIGN_UP (psize, 16) - psize);
    }
  if (err)
    {
      grub_free (compbuf);
      *buf = NULL;
      return err;
    }

  if (!BP_IS_EMBEDDED(bp))
    {
      err = zio_checksum_verify (zc, checksum, endian,
			         compbuf, psize);
      if (err)
        {
          grub_dprintf ("zfs", "incorrect checksum\n");
          grub_free (compbuf);
          *buf = NULL;
          return err;
        }
    }

  if (encrypted)
    {
      if (!grub_zfs_decrypt)
	err = grub_error (GRUB_ERR_BAD_FS, 
			  N_("module `%s' isn't loaded"),
			  "zfscrypt");
      else
	{
	  unsigned i, besti = 0;
	  grub_uint64_t bestval = 0;
	  for (i = 0; i < data->subvol.nkeys; i++)
	    if (data->subvol.keyring[i].txg <= grub_zfs_to_cpu64 (bp->blk_birth,
								  endian)
		&& data->subvol.keyring[i].txg > bestval)
	      {
		besti = i;
		bestval = data->subvol.keyring[i].txg;
	      }
	  if (bestval == 0)
	    {
	      grub_free (compbuf);
	      *buf = NULL;
	      grub_dprintf ("zfs", "no key for txg %" PRIxGRUB_UINT64_T "\n",
			    grub_zfs_to_cpu64 (bp->blk_birth,
					       endian));
	      return grub_error (GRUB_ERR_BAD_FS, "no key found in keychain");
	    }
	  grub_dprintf ("zfs", "using key %u (%" PRIxGRUB_UINT64_T 
			", %p) for txg %" PRIxGRUB_UINT64_T "\n",
			besti, data->subvol.keyring[besti].txg,
			data->subvol.keyring[besti].cipher,
			grub_zfs_to_cpu64 (bp->blk_birth,
					   endian));
	  err = grub_zfs_decrypt (data->subvol.keyring[besti].cipher,
				  data->subvol.keyring[besti].algo,
				  &(bp)->blk_dva[encrypted],
				  compbuf, psize, zc.zc_mac,
				  endian);
	}
      if (err)
	{
	  grub_free (compbuf);
	  *buf = NULL;
	  return err;
	}
    }

  if (comp != ZIO_COMPRESS_OFF)
    {
      *buf = grub_malloc (lsize);
      if (!*buf)
	{
	  grub_free (compbuf);
	  return grub_errno;
	}

      err = decomp_table[comp].decomp_func (compbuf, *buf, psize, lsize);
      grub_free (compbuf);
      if (err)
	{
	  grub_free (*buf);
	  *buf = NULL;
	  return err;
	}
    }

  return GRUB_ERR_NONE;
}

/*
 * Get the block from a block id.
 * push the block onto the stack.
 *
 */
static grub_err_t
dmu_read (dnode_end_t * dn, grub_uint64_t blkid, void **buf, 
	  grub_zfs_endian_t *endian_out, struct grub_zfs_data *data)
{
  int level;
  grub_off_t idx;
  blkptr_t *bp_array = dn->dn.dn_blkptr;
  int epbs = dn->dn.dn_indblkshift - SPA_BLKPTRSHIFT;
  blkptr_t *bp;
  void *tmpbuf = 0;
  grub_zfs_endian_t endian;
  grub_err_t err = GRUB_ERR_NONE;

  bp = grub_malloc (sizeof (blkptr_t));
  if (!bp)
    return grub_errno;

  endian = dn->endian;
  for (level = dn->dn.dn_nlevels - 1; level >= 0; level--)
    {
      grub_dprintf ("zfs", "endian = %d\n", endian);
      idx = (blkid >> (epbs * level)) & ((1 << epbs) - 1);
      *bp = bp_array[idx];
      if (bp_array != dn->dn.dn_blkptr)
	{
	  grub_free (bp_array);
	  bp_array = 0;
	}

      if (BP_IS_HOLE (bp))
	{
	  grub_size_t size = grub_zfs_to_cpu16 (dn->dn.dn_datablkszsec, 
						dn->endian) 
	    << SPA_MINBLOCKSHIFT;
	  *buf = grub_malloc (size);
	  if (!*buf)
	    {
	      err = grub_errno;
	      break;
	    }
	  grub_memset (*buf, 0, size);
	  endian = (grub_zfs_to_cpu64 (bp->blk_prop, endian) >> 63) & 1;
	  break;
	}
      if (level == 0)
	{
	  grub_dprintf ("zfs", "endian = %d\n", endian);
	  err = zio_read (bp, endian, buf, 0, data);
	  endian = (grub_zfs_to_cpu64 (bp->blk_prop, endian) >> 63) & 1;
	  break;
	}
      grub_dprintf ("zfs", "endian = %d\n", endian);
      err = zio_read (bp, endian, &tmpbuf, 0, data);
      endian = (grub_zfs_to_cpu64 (bp->blk_prop, endian) >> 63) & 1;
      if (err)
	break;
      bp_array = tmpbuf;
    }
  if (bp_array != dn->dn.dn_blkptr)
    grub_free (bp_array);
  if (endian_out)
    *endian_out = endian;

  grub_free (bp);
  return err;
}

/*
 * mzap_lookup: Looks up property described by "name" and returns the value
 * in "value".
 */
static grub_err_t
mzap_lookup (mzap_phys_t * zapobj, grub_zfs_endian_t endian,
	     grub_uint32_t objsize, const char *name, grub_uint64_t * value,
	     int case_insensitive)
{
  grub_uint32_t i, chunks;
  mzap_ent_phys_t *mzap_ent = zapobj->mz_chunk;

  if (objsize < MZAP_ENT_LEN)
    return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), name);
  chunks = objsize / MZAP_ENT_LEN - 1;
  for (i = 0; i < chunks; i++)
    {
      if (case_insensitive ? (grub_strcasecmp (mzap_ent[i].mze_name, name) == 0)
	  : (grub_strcmp (mzap_ent[i].mze_name, name) == 0))
	{
	  *value = grub_zfs_to_cpu64 (mzap_ent[i].mze_value, endian);
	  return GRUB_ERR_NONE;
	}
    }

  return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), name);
}

static int
mzap_iterate (mzap_phys_t * zapobj, grub_zfs_endian_t endian, int objsize, 
	      int (*hook) (const char *name, grub_uint64_t val,
			   struct grub_zfs_dir_ctx *ctx),
	      struct grub_zfs_dir_ctx *ctx)
{
  int i, chunks;
  mzap_ent_phys_t *mzap_ent = zapobj->mz_chunk;

  chunks = objsize / MZAP_ENT_LEN - 1;
  for (i = 0; i < chunks; i++)
    {
      grub_dprintf ("zfs", "zap: name = %s, value = %llx, cd = %x\n",
		    mzap_ent[i].mze_name, (long long)mzap_ent[i].mze_value,
		    (int)mzap_ent[i].mze_cd);
      if (hook (mzap_ent[i].mze_name, 
		grub_zfs_to_cpu64 (mzap_ent[i].mze_value, endian), ctx))
	return 1;
    }

  return 0;
}

static grub_uint64_t
zap_hash (grub_uint64_t salt, const char *name,
	  int case_insensitive)
{
  static grub_uint64_t table[256];
  const grub_uint8_t *cp;
  grub_uint8_t c;
  grub_uint64_t crc = salt;

  if (table[128] == 0)
    {
      grub_uint64_t *ct;
      int i, j;
      for (i = 0; i < 256; i++)
	{
	  for (ct = table + i, *ct = i, j = 8; j > 0; j--)
	    *ct = (*ct >> 1) ^ (-(*ct & 1) & ZFS_CRC64_POLY);
	}
    }

  if (case_insensitive)
    for (cp = (const grub_uint8_t *) name; (c = *cp) != '\0'; cp++)
      crc = (crc >> 8) ^ table[(crc ^ grub_toupper (c)) & 0xFF];
  else
    for (cp = (const grub_uint8_t *) name; (c = *cp) != '\0'; cp++)
      crc = (crc >> 8) ^ table[(crc ^ c) & 0xFF];

  /*
   * Only use 28 bits, since we need 4 bits in the cookie for the
   * collision differentiator.  We MUST use the high bits, since
   * those are the onces that we first pay attention to when
   * chosing the bucket.
   */
  crc &= ~((1ULL << (64 - ZAP_HASHBITS)) - 1);

  return crc;
}

/*
 * Only to be used on 8-bit arrays.
 * array_len is actual len in bytes (not encoded le_value_length).
 * buf is null-terminated.
 */

static inline int
name_cmp (const char *s1, const char *s2, grub_size_t n,
	  int case_insensitive)
{
  const char *t1 = (const char *) s1;
  const char *t2 = (const char *) s2;

  if (!case_insensitive)
    return grub_memcmp (t1, t2, n);
      
  while (n--)
    {
      if (grub_toupper (*t1) != grub_toupper (*t2))
	return (int) grub_toupper (*t1) - (int) grub_toupper (*t2);
	  
      t1++;
      t2++;
    }

  return 0;
}

/* XXX */
static int
zap_leaf_array_equal (zap_leaf_phys_t * l, grub_zfs_endian_t endian,
		      int blksft, int chunk, grub_size_t array_len,
		      const char *buf, int case_insensitive)
{
  grub_size_t bseen = 0;

  while (bseen < array_len)
    {
      struct zap_leaf_array *la = &ZAP_LEAF_CHUNK (l, blksft, chunk)->l_array;
      grub_size_t toread = array_len - bseen;

      if (toread > ZAP_LEAF_ARRAY_BYTES)
	toread = ZAP_LEAF_ARRAY_BYTES;

      if (chunk >= ZAP_LEAF_NUMCHUNKS (blksft))
	return 0;

      if (name_cmp ((char *) la->la_array, buf + bseen, toread,
		    case_insensitive) != 0)
	break;
      chunk = grub_zfs_to_cpu16 (la->la_next, endian);
      bseen += toread;
    }
  return (bseen == array_len);
}

/* XXX */
static grub_err_t
zap_leaf_array_get (zap_leaf_phys_t * l, grub_zfs_endian_t endian, int blksft, 
		    int chunk, grub_size_t array_len, char *buf)
{
  grub_size_t bseen = 0;

  while (bseen < array_len)
    {
      struct zap_leaf_array *la = &ZAP_LEAF_CHUNK (l, blksft, chunk)->l_array;
      grub_size_t toread = array_len - bseen;

      if (toread > ZAP_LEAF_ARRAY_BYTES)
	toread = ZAP_LEAF_ARRAY_BYTES;

      if (chunk >= ZAP_LEAF_NUMCHUNKS (blksft))
	/* Don't use grub_error because this error is to be ignored.  */
	return GRUB_ERR_BAD_FS;

      grub_memcpy (buf + bseen,la->la_array,  toread);
      chunk = grub_zfs_to_cpu16 (la->la_next, endian);
      bseen += toread;
    }
  return GRUB_ERR_NONE;
}


/*
 * Given a zap_leaf_phys_t, walk thru the zap leaf chunks to get the
 * value for the property "name".
 *
 */
/* XXX */
static grub_err_t
zap_leaf_lookup (zap_leaf_phys_t * l, grub_zfs_endian_t endian,
		 int blksft, grub_uint64_t h,
		 const char *name, grub_uint64_t * value,
		 int case_insensitive)
{
  grub_uint16_t chunk;
  struct zap_leaf_entry *le;

  /* Verify if this is a valid leaf block */
  if (grub_zfs_to_cpu64 (l->l_hdr.lh_block_type, endian) != ZBT_LEAF)
    return grub_error (GRUB_ERR_BAD_FS, "invalid leaf type");
  if (grub_zfs_to_cpu32 (l->l_hdr.lh_magic, endian) != ZAP_LEAF_MAGIC)
    return grub_error (GRUB_ERR_BAD_FS, "invalid leaf magic");

  for (chunk = grub_zfs_to_cpu16 (l->l_hash[LEAF_HASH (blksft, h, l)], endian);
       chunk != CHAIN_END; chunk = grub_zfs_to_cpu16 (le->le_next, endian))
    {

      if (chunk >= ZAP_LEAF_NUMCHUNKS (blksft))
	return grub_error (GRUB_ERR_BAD_FS, "invalid chunk number");

      le = ZAP_LEAF_ENTRY (l, blksft, chunk);

      /* Verify the chunk entry */
      if (le->le_type != ZAP_CHUNK_ENTRY)
	return grub_error (GRUB_ERR_BAD_FS, "invalid chunk entry");

      if (grub_zfs_to_cpu64 (le->le_hash,endian) != h)
	continue;

      grub_dprintf ("zfs", "fzap: length %d\n", (int) le->le_name_length);

      if (zap_leaf_array_equal (l, endian, blksft, 
				grub_zfs_to_cpu16 (le->le_name_chunk,endian),
				grub_zfs_to_cpu16 (le->le_name_length, endian),
				name, case_insensitive))
	{
	  struct zap_leaf_array *la;

	  if (le->le_int_size != 8 || grub_zfs_to_cpu16 (le->le_value_length,
							 endian) != 1)
	    return grub_error (GRUB_ERR_BAD_FS, "invalid leaf chunk entry");

	  /* get the uint64_t property value */
	  la = &ZAP_LEAF_CHUNK (l, blksft, le->le_value_chunk)->l_array;

	  *value = grub_be_to_cpu64 (la->la_array64);

	  return GRUB_ERR_NONE;
	}
    }

  return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), name);
}


/* Verify if this is a fat zap header block */
static grub_err_t
zap_verify (zap_phys_t *zap, grub_zfs_endian_t endian)
{
  if (grub_zfs_to_cpu64 (zap->zap_magic, endian) != (grub_uint64_t) ZAP_MAGIC)
    return grub_error (GRUB_ERR_BAD_FS, "bad ZAP magic");

  if (zap->zap_salt == 0)
    return grub_error (GRUB_ERR_BAD_FS, "bad ZAP salt");

  return GRUB_ERR_NONE;
}

/*
 * Fat ZAP lookup
 *
 */
/* XXX */
static grub_err_t
fzap_lookup (dnode_end_t * zap_dnode, zap_phys_t * zap,
	     const char *name, grub_uint64_t * value,
	     struct grub_zfs_data *data, int case_insensitive)
{
  void *l;
  grub_uint64_t hash, idx, blkid;
  int blksft = zfs_log2 (grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec, 
					    zap_dnode->endian) << DNODE_SHIFT);
  grub_err_t err;
  grub_zfs_endian_t leafendian;

  err = zap_verify (zap, zap_dnode->endian);
  if (err)
    return err;

  hash = zap_hash (zap->zap_salt, name, case_insensitive);

  /* get block id from index */
  if (zap->zap_ptrtbl.zt_numblks != 0)
    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, 
		       "external pointer tables not supported");
  idx = ZAP_HASH_IDX (hash, zap->zap_ptrtbl.zt_shift);
  blkid = grub_zfs_to_cpu64 (((grub_uint64_t *) zap)[idx + (1 << (blksft - 3 - 1))], zap_dnode->endian);

  /* Get the leaf block */
  if ((1U << blksft) < sizeof (zap_leaf_phys_t))
    return grub_error (GRUB_ERR_BAD_FS, "ZAP leaf is too small");
  err = dmu_read (zap_dnode, blkid, &l, &leafendian, data);
  if (err)
    return err;

  err = zap_leaf_lookup (l, leafendian, blksft, hash, name, value,
			 case_insensitive);
  grub_free (l);
  return err;
}

/* XXX */
static int
fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap,
	      grub_size_t name_elem_length,
	      int (*hook) (const void *name, grub_size_t name_length,
			   const void *val_in,
			   grub_size_t nelem, grub_size_t elemsize,
			   void *data),
	      void *hook_data, struct grub_zfs_data *data)
{
  zap_leaf_phys_t *l;
  void *l_in;
  grub_uint64_t idx, idx2, blkid;
  grub_uint16_t chunk;
  int blksft = zfs_log2 (grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec, 
					    zap_dnode->endian) << DNODE_SHIFT);
  grub_err_t err;
  grub_zfs_endian_t endian;

  if (zap_verify (zap, zap_dnode->endian))
    return 0;

  /* get block id from index */
  if (zap->zap_ptrtbl.zt_numblks != 0)
    {
      grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, 
		  "external pointer tables not supported");
      return 0;
    }
  /* Get the leaf block */
  if ((1U << blksft) < sizeof (zap_leaf_phys_t))
    {
      grub_error (GRUB_ERR_BAD_FS, "ZAP leaf is too small");
      return 0;
    }
  for (idx = 0; idx < (1ULL << zap->zap_ptrtbl.zt_shift); idx++)
    {
      blkid = grub_zfs_to_cpu64 (((grub_uint64_t *) zap)[idx + (1 << (blksft - 3 - 1))],
				 zap_dnode->endian);

      for (idx2 = 0; idx2 < idx; idx2++)
	if (blkid == grub_zfs_to_cpu64 (((grub_uint64_t *) zap)[idx2 + (1 << (blksft - 3 - 1))],
					zap_dnode->endian))
	  break;
      if (idx2 != idx)
	continue;

      err = dmu_read (zap_dnode, blkid, &l_in, &endian, data);
      l = l_in;
      if (err)
	{
	  grub_errno = GRUB_ERR_NONE;
	  continue;
	}

      /* Verify if this is a valid leaf block */
      if (grub_zfs_to_cpu64 (l->l_hdr.lh_block_type, endian) != ZBT_LEAF)
	{
	  grub_free (l);
	  continue;
	}
      if (grub_zfs_to_cpu32 (l->l_hdr.lh_magic, endian) != ZAP_LEAF_MAGIC)
	{
	  grub_free (l);
	  continue;
	}

      for (chunk = 0; chunk < ZAP_LEAF_NUMCHUNKS (blksft); chunk++)
	{
	  char *buf;
	  struct zap_leaf_entry *le;
	  char *val;
	  grub_size_t val_length;
	  le = ZAP_LEAF_ENTRY (l, blksft, chunk);

	  /* Verify the chunk entry */
	  if (le->le_type != ZAP_CHUNK_ENTRY)
	    continue;

	  buf = grub_malloc (grub_zfs_to_cpu16 (le->le_name_length, endian)
			     * name_elem_length + 1);
	  if (zap_leaf_array_get (l, endian, blksft,
				  grub_zfs_to_cpu16 (le->le_name_chunk,
						     endian),
				  grub_zfs_to_cpu16 (le->le_name_length,
						     endian)
				  * name_elem_length, buf))
	    {
	      grub_free (buf);
	      continue;
	    }
	  buf[le->le_name_length * name_elem_length] = 0;

	  val_length = ((int) le->le_value_length
			* (int) le->le_int_size);
	  val = grub_malloc (grub_zfs_to_cpu16 (val_length, endian));
	  if (zap_leaf_array_get (l, endian, blksft,
				  grub_zfs_to_cpu16 (le->le_value_chunk,
						     endian),
				  val_length, val))
	    {
	      grub_free (buf);
	      grub_free (val);
	      continue;
	    }

	  if (hook (buf, le->le_name_length,
		    val, le->le_value_length, le->le_int_size, hook_data))
	    {
	      grub_free (l);
	      return 1;
	    }
	  grub_free (buf);
	  grub_free (val);
	}
      grub_free (l);
    }
  return 0;
}

/*
 * Read in the data of a zap object and find the value for a matching
 * property name.
 *
 */
static grub_err_t
zap_lookup (dnode_end_t * zap_dnode, const char *name, grub_uint64_t *val,
	    struct grub_zfs_data *data, int case_insensitive)
{
  grub_uint64_t block_type;
  grub_uint32_t size;
  void *zapbuf;
  grub_err_t err;
  grub_zfs_endian_t endian;

  grub_dprintf ("zfs", "looking for '%s'\n", name);

  /* Read in the first block of the zap object data. */
  size = (grub_uint32_t) grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec,
			    zap_dnode->endian) << SPA_MINBLOCKSHIFT;
  err = dmu_read (zap_dnode, 0, &zapbuf, &endian, data);
  if (err)
    return err;
  block_type = grub_zfs_to_cpu64 (*((grub_uint64_t *) zapbuf), endian);

  grub_dprintf ("zfs", "zap read\n");

  if (block_type == ZBT_MICRO)
    {
      grub_dprintf ("zfs", "micro zap\n");
      err = mzap_lookup (zapbuf, endian, size, name, val,
			 case_insensitive);
      grub_dprintf ("zfs", "returned %d\n", err);      
      grub_free (zapbuf);
      return err;
    }
  else if (block_type == ZBT_HEADER)
    {
      grub_dprintf ("zfs", "fat zap\n");
      /* this is a fat zap */
      err = fzap_lookup (zap_dnode, zapbuf, name, val, data,
			 case_insensitive);
      grub_dprintf ("zfs", "returned %d\n", err);      
      grub_free (zapbuf);
      return err;
    }

  return grub_error (GRUB_ERR_BAD_FS, "unknown ZAP type");
}

/* Context for zap_iterate_u64.  */
struct zap_iterate_u64_ctx
{
  int (*hook) (const char *, grub_uint64_t, struct grub_zfs_dir_ctx *);
  struct grub_zfs_dir_ctx *dir_ctx;
};

/* Helper for zap_iterate_u64.  */
static int
zap_iterate_u64_transform (const void *name,
			   grub_size_t namelen __attribute__ ((unused)),
			   const void *val_in,
			   grub_size_t nelem,
			   grub_size_t elemsize,
			   void *data)
{
  struct zap_iterate_u64_ctx *ctx = data;

  if (elemsize != sizeof (grub_uint64_t) || nelem != 1)
    return 0;
  return ctx->hook (name, grub_be_to_cpu64 (*(const grub_uint64_t *) val_in),
		    ctx->dir_ctx);
}

static int
zap_iterate_u64 (dnode_end_t * zap_dnode, 
		 int (*hook) (const char *name, grub_uint64_t val,
			      struct grub_zfs_dir_ctx *ctx),
		 struct grub_zfs_data *data, struct grub_zfs_dir_ctx *ctx)
{
  grub_uint64_t block_type;
  int size;
  void *zapbuf;
  grub_err_t err;
  int ret;
  grub_zfs_endian_t endian;

  /* Read in the first block of the zap object data. */
  size = grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec, zap_dnode->endian) << SPA_MINBLOCKSHIFT;
  err = dmu_read (zap_dnode, 0, &zapbuf, &endian, data);
  if (err)
    return 0;
  block_type = grub_zfs_to_cpu64 (*((grub_uint64_t *) zapbuf), endian);

  grub_dprintf ("zfs", "zap iterate\n");

  if (block_type == ZBT_MICRO)
    {
      grub_dprintf ("zfs", "micro zap\n");
      ret = mzap_iterate (zapbuf, endian, size, hook, ctx);
      grub_free (zapbuf);
      return ret;
    }
  else if (block_type == ZBT_HEADER)
    {
      struct zap_iterate_u64_ctx transform_ctx = {
	.hook = hook,
	.dir_ctx = ctx
      };

      grub_dprintf ("zfs", "fat zap\n");
      /* this is a fat zap */
      ret = fzap_iterate (zap_dnode, zapbuf, 1,
			  zap_iterate_u64_transform, &transform_ctx, data);
      grub_free (zapbuf);
      return ret;
    }
  grub_error (GRUB_ERR_BAD_FS, "unknown ZAP type");
  return 0;
}

static int
zap_iterate (dnode_end_t * zap_dnode, 
	     grub_size_t nameelemlen,
	     int (*hook) (const void *name, grub_size_t namelen,
			  const void *val_in,
			  grub_size_t nelem, grub_size_t elemsize,
			  void *data),
	     void *hook_data, struct grub_zfs_data *data)
{
  grub_uint64_t block_type;
  void *zapbuf;
  grub_err_t err;
  int ret;
  grub_zfs_endian_t endian;

  /* Read in the first block of the zap object data. */
  err = dmu_read (zap_dnode, 0, &zapbuf, &endian, data);
  if (err)
    return 0;
  block_type = grub_zfs_to_cpu64 (*((grub_uint64_t *) zapbuf), endian);

  grub_dprintf ("zfs", "zap iterate\n");

  if (block_type == ZBT_MICRO)
    {
      grub_error (GRUB_ERR_BAD_FS, "micro ZAP where FAT ZAP expected");
      return 0;
    }
  if (block_type == ZBT_HEADER)
    {
      grub_dprintf ("zfs", "fat zap\n");
      /* this is a fat zap */
      ret = fzap_iterate (zap_dnode, zapbuf, nameelemlen, hook, hook_data,
			  data);
      grub_free (zapbuf);
      return ret;
    }
  grub_error (GRUB_ERR_BAD_FS, "unknown ZAP type");
  return 0;
}


/*
 * Get the dnode of an object number from the metadnode of an object set.
 *
 * Input
 *	mdn - metadnode to get the object dnode
 *	objnum - object number for the object dnode
 *	buf - data buffer that holds the returning dnode
 */
static grub_err_t
dnode_get (dnode_end_t * mdn, grub_uint64_t objnum, grub_uint8_t type,
	   dnode_end_t * buf, struct grub_zfs_data *data)
{
  grub_uint64_t blkid, blksz;	/* the block id this object dnode is in */
  int epbs;			/* shift of number of dnodes in a block */
  int idx;			/* index within a block */
  void *dnbuf;
  grub_err_t err;
  grub_zfs_endian_t endian;

  blksz = grub_zfs_to_cpu16 (mdn->dn.dn_datablkszsec, 
			     mdn->endian) << SPA_MINBLOCKSHIFT;
  epbs = zfs_log2 (blksz) - DNODE_SHIFT;
  blkid = objnum >> epbs;
  idx = objnum & ((1 << epbs) - 1);

  if (data->dnode_buf != NULL && grub_memcmp (data->dnode_mdn, mdn, 
					      sizeof (*mdn)) == 0 
      && objnum >= data->dnode_start && objnum < data->dnode_end)
    {
      grub_memmove (&(buf->dn), &(data->dnode_buf)[idx], DNODE_SIZE);
      buf->endian = data->dnode_endian;
      if (type && buf->dn.dn_type != type) 
	return grub_error(GRUB_ERR_BAD_FS, "incorrect dnode type"); 
      return GRUB_ERR_NONE;
    }

  grub_dprintf ("zfs", "endian = %d, blkid=%llx\n", mdn->endian, 
		(unsigned long long) blkid);
  err = dmu_read (mdn, blkid, &dnbuf, &endian, data);
  if (err)
    return err;
  grub_dprintf ("zfs", "alive\n");

  grub_free (data->dnode_buf);
  grub_free (data->dnode_mdn);
  data->dnode_mdn = grub_malloc (sizeof (*mdn));
  if (! data->dnode_mdn)
    {
      grub_errno = GRUB_ERR_NONE;
      data->dnode_buf = 0;
    }
  else
    {
      grub_memcpy (data->dnode_mdn, mdn, sizeof (*mdn));
      data->dnode_buf = dnbuf;
      data->dnode_start = blkid << epbs;
      data->dnode_end = (blkid + 1) << epbs;
      data->dnode_endian = endian;
    }

  grub_memmove (&(buf->dn), (dnode_phys_t *) dnbuf + idx, DNODE_SIZE);
  buf->endian = endian;
  if (type && buf->dn.dn_type != type) 
    return grub_error(GRUB_ERR_BAD_FS, "incorrect dnode type"); 

  return GRUB_ERR_NONE;
}

#pragma GCC diagnostic ignored "-Wstrict-aliasing"

/*
 * Get the file dnode for a given file name where mdn is the meta dnode
 * for this ZFS object set. When found, place the file dnode in dn.
 * The 'path' argument will be mangled.
 *
 */
static grub_err_t
dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn,
		struct grub_zfs_data *data)
{
  grub_uint64_t objnum, version;
  char *cname, ch;
  grub_err_t err = GRUB_ERR_NONE;
  char *path, *path_buf;
  struct dnode_chain
  {
    struct dnode_chain *next;
    dnode_end_t dn; 
  };
  struct dnode_chain *dnode_path = 0, *dn_new, *root;

  dn_new = grub_malloc (sizeof (*dn_new));
  if (! dn_new)
    return grub_errno;
  dn_new->next = 0;
  dnode_path = root = dn_new;

  err = dnode_get (&subvol->mdn, MASTER_NODE_OBJ, DMU_OT_MASTER_NODE, 
		   &(dnode_path->dn), data);
  if (err)
    {
      grub_free (dn_new);
      return err;
    }

  err = zap_lookup (&(dnode_path->dn), ZPL_VERSION_STR, &version,
		    data, 0);
  if (err)
    {
      grub_free (dn_new);
      return err;
    }

  if (version > ZPL_VERSION)
    {
      grub_free (dn_new);
      return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "too new ZPL version");
    }

  err = zap_lookup (&(dnode_path->dn), "casesensitivity",
		    &subvol->case_insensitive,
		    data, 0);
  if (err == GRUB_ERR_FILE_NOT_FOUND)
    {
      grub_errno = GRUB_ERR_NONE;
      subvol->case_insensitive = 0;
    }

  err = zap_lookup (&(dnode_path->dn), ZFS_ROOT_OBJ, &objnum, data, 0);
  if (err)
    {
      grub_free (dn_new);
      return err;
    }

  err = dnode_get (&subvol->mdn, objnum, 0, &(dnode_path->dn), data);
  if (err)
    {
      grub_free (dn_new);
      return err;
    }

  path = path_buf = grub_strdup (path_in);
  if (!path_buf)
    {
      grub_free (dn_new);
      return grub_errno;
    }
  
  while (1)
    {
      /* skip leading slashes */
      while (*path == '/')
	path++;
      if (!*path)
	break;
      /* get the next component name */
      cname = path;
      while (*path && *path != '/')
	path++;
      /* Skip dot.  */
      if (cname + 1 == path && cname[0] == '.')
	continue;
      /* Handle double dot.  */
      if (cname + 2 == path && cname[0] == '.' && cname[1] == '.')
	{
	  if (dn_new->next)
	    {
	      dn_new = dnode_path;
	      dnode_path = dn_new->next;
	      grub_free (dn_new);
	    }
	  else
	    {
	      err = grub_error (GRUB_ERR_FILE_NOT_FOUND, 
				"can't resolve ..");
	      break;
	    }
	  continue;
	}

      ch = *path;
      *path = 0;		/* ensure null termination */

      if (dnode_path->dn.dn.dn_type != DMU_OT_DIRECTORY_CONTENTS)
	{
	  grub_free (path_buf);
	  return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
	}
      err = zap_lookup (&(dnode_path->dn), cname, &objnum,
			data, subvol->case_insensitive);
      if (err)
	break;

      dn_new = grub_malloc (sizeof (*dn_new));
      if (! dn_new)
	{
	  err = grub_errno;
	  break;
	}
      dn_new->next = dnode_path;
      dnode_path = dn_new;

      objnum = ZFS_DIRENT_OBJ (objnum);
      err = dnode_get (&subvol->mdn, objnum, 0, &(dnode_path->dn), data);
      if (err)
	break;

      *path = ch;
      if (dnode_path->dn.dn.dn_bonustype == DMU_OT_ZNODE
	  && ((grub_zfs_to_cpu64(((znode_phys_t *) DN_BONUS (&dnode_path->dn.dn))->zp_mode, dnode_path->dn.endian) >> 12) & 0xf) == 0xa)
	{
	  char *sym_value;
	  grub_size_t sym_sz;
	  int free_symval = 0;
	  char *oldpath = path, *oldpathbuf = path_buf;
	  sym_value = ((char *) DN_BONUS (&dnode_path->dn.dn) + sizeof (struct znode_phys));

	  sym_sz = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&dnode_path->dn.dn))->zp_size, dnode_path->dn.endian);

	  if (dnode_path->dn.dn.dn_flags & 1)
	    {
	      grub_size_t block;
	      grub_size_t blksz;
	      blksz = (grub_zfs_to_cpu16 (dnode_path->dn.dn.dn_datablkszsec, 
					  dnode_path->dn.endian)
		       << SPA_MINBLOCKSHIFT);

	      if (blksz == 0)
		return grub_error(GRUB_ERR_BAD_FS, "0-sized block");

	      sym_value = grub_malloc (sym_sz);
	      if (!sym_value)
		return grub_errno;
	      for (block = 0; block < (sym_sz + blksz - 1) / blksz; block++)
		{
		  void *t;
		  grub_size_t movesize;

		  err = dmu_read (&(dnode_path->dn), block, &t, 0, data);
		  if (err)
		    {
		      grub_free (sym_value);
		      return err;
		    }

		  movesize = sym_sz - block * blksz;
		  if (movesize > blksz)
		    movesize = blksz;

		  grub_memcpy (sym_value + block * blksz, t, movesize);
		  grub_free (t);
		}
	      free_symval = 1;
	    }	    
	  path = path_buf = grub_malloc (sym_sz + grub_strlen (oldpath) + 1);
	  if (!path_buf)
	    {
	      grub_free (oldpathbuf);
	      if (free_symval)
		grub_free (sym_value);
	      return grub_errno;
	    }
	  grub_memcpy (path, sym_value, sym_sz);
	  if (free_symval)
	    grub_free (sym_value);
	  path [sym_sz] = 0;
	  grub_memcpy (path + grub_strlen (path), oldpath, 
		       grub_strlen (oldpath) + 1);
	  
	  grub_free (oldpathbuf);
	  if (path[0] != '/')
	    {
	      dn_new = dnode_path;
	      dnode_path = dn_new->next;
	      grub_free (dn_new);
	    }
	  else while (dnode_path != root)
		 {
		   dn_new = dnode_path;
		   dnode_path = dn_new->next;
		   grub_free (dn_new);
		 }
	}
      if (dnode_path->dn.dn.dn_bonustype == DMU_OT_SA)
	{
	  void *sahdrp;
	  int hdrsize;
	  
	  if (dnode_path->dn.dn.dn_bonuslen != 0)
	    {
	      sahdrp = DN_BONUS (&dnode_path->dn.dn);
	    }
	  else if (dnode_path->dn.dn.dn_flags & DNODE_FLAG_SPILL_BLKPTR)
	    {
	      blkptr_t *bp = &dnode_path->dn.dn.dn_spill;
	      
	      err = zio_read (bp, dnode_path->dn.endian, &sahdrp, NULL, data);
	      if (err)
		return err;
	    }
	  else
	    {
	      return grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt");
	    }

	  hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp));

	  if (((grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp
							 + hdrsize
							 + SA_TYPE_OFFSET),
				   dnode_path->dn.endian) >> 12) & 0xf) == 0xa)
	    {
	      char *sym_value = (char *) sahdrp + hdrsize + SA_SYMLINK_OFFSET;
	      grub_size_t sym_sz = 
		grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp
							 + hdrsize
							 + SA_SIZE_OFFSET),
				   dnode_path->dn.endian);
	      char *oldpath = path, *oldpathbuf = path_buf;
	      path = path_buf = grub_malloc (sym_sz + grub_strlen (oldpath) + 1);
	      if (!path_buf)
		{
		  grub_free (oldpathbuf);
		  return grub_errno;
		}
	      grub_memcpy (path, sym_value, sym_sz);
	      path [sym_sz] = 0;
	      grub_memcpy (path + grub_strlen (path), oldpath, 
			   grub_strlen (oldpath) + 1);
	      
	      grub_free (oldpathbuf);
	      if (path[0] != '/')
		{
		  dn_new = dnode_path;
		  dnode_path = dn_new->next;
		  grub_free (dn_new);
		}
	      else while (dnode_path != root)
		     {
		       dn_new = dnode_path;
		       dnode_path = dn_new->next;
		       grub_free (dn_new);
		     }
	    }
	}
    }

  if (!err)
    grub_memcpy (dn, &(dnode_path->dn), sizeof (*dn));

  while (dnode_path)
    {
      dn_new = dnode_path->next;
      grub_free (dnode_path);
      dnode_path = dn_new;
    }
  grub_free (path_buf);
  return err;
}

#if 0
/*
 * Get the default 'bootfs' property value from the rootpool.
 *
 */
static grub_err_t
get_default_bootfsobj (dnode_phys_t * mosmdn, grub_uint64_t * obj,
		       struct grub_zfs_data *data)
{
  grub_uint64_t objnum = 0;
  dnode_phys_t *dn;
  if (!dn)
    return grub_errno;

  if ((grub_errno = dnode_get (mosmdn, DMU_POOL_DIRECTORY_OBJECT,
			       DMU_OT_OBJECT_DIRECTORY, dn, data)))
    {
      grub_free (dn);
      return (grub_errno);
    }

  /*
   * find the object number for 'pool_props', and get the dnode
   * of the 'pool_props'.
   */
  if (zap_lookup (dn, DMU_POOL_PROPS, &objnum, data))
    {
      grub_free (dn);
      return (GRUB_ERR_BAD_FS);
    }
  if ((grub_errno = dnode_get (mosmdn, objnum, DMU_OT_POOL_PROPS, dn, data)))
    {
      grub_free (dn);
      return (grub_errno);
    }
  if (zap_lookup (dn, ZPOOL_PROP_BOOTFS, &objnum, data))
    {
      grub_free (dn);
      return (GRUB_ERR_BAD_FS);
    }

  if (!objnum)
    {
      grub_free (dn);
      return (GRUB_ERR_BAD_FS);
    }

  *obj = objnum;
  return (0);
}
#endif
/*
 * Given a MOS metadnode, get the metadnode of a given filesystem name (fsname),
 * e.g. pool/rootfs, or a given object number (obj), e.g. the object number
 * of pool/rootfs.
 *
 * If no fsname and no obj are given, return the DSL_DIR metadnode.
 * If fsname is given, return its metadnode and its matching object number.
 * If only obj is given, return the metadnode for this object number.
 *
 */
static grub_err_t
get_filesystem_dnode (dnode_end_t * mosmdn, char *fsname,
		      dnode_end_t * mdn, struct grub_zfs_data *data)
{
  grub_uint64_t objnum;
  grub_err_t err;

  grub_dprintf ("zfs", "endian = %d\n", mosmdn->endian);

  err = dnode_get (mosmdn, DMU_POOL_DIRECTORY_OBJECT, 
		   DMU_OT_OBJECT_DIRECTORY, mdn, data);
  if (err)
    return err;

  grub_dprintf ("zfs", "alive\n");

  err = zap_lookup (mdn, DMU_POOL_ROOT_DATASET, &objnum, data, 0);
  if (err)
    return err;

  grub_dprintf ("zfs", "alive\n");

  err = dnode_get (mosmdn, objnum, 0, mdn, data);
  if (err)
    return err;

  grub_dprintf ("zfs", "alive\n");

  while (*fsname)
    {
      grub_uint64_t childobj;
      char *cname, ch;
 
      while (*fsname == '/')
	fsname++;

      if (! *fsname || *fsname == '@')
	break;

      cname = fsname;
      while (*fsname && *fsname != '/')
	fsname++;
      ch = *fsname;
      *fsname = 0;

      childobj = grub_zfs_to_cpu64 ((((dsl_dir_phys_t *) DN_BONUS (&mdn->dn)))->dd_child_dir_zapobj, mdn->endian);
      err = dnode_get (mosmdn, childobj,
		       DMU_OT_DSL_DIR_CHILD_MAP, mdn, data);
      if (err)
	return err;

      err = zap_lookup (mdn, cname, &objnum, data, 0);
      if (err)
	return err;

      err = dnode_get (mosmdn, objnum, 0, mdn, data);
      if (err)
	return err;

      *fsname = ch;
    }
  return GRUB_ERR_NONE;
}

static grub_err_t
make_mdn (dnode_end_t * mdn, struct grub_zfs_data *data)
{
  void *osp;
  blkptr_t *bp;
  grub_size_t ospsize = 0;
  grub_err_t err;

  grub_dprintf ("zfs", "endian = %d\n", mdn->endian);

  bp = &(((dsl_dataset_phys_t *) DN_BONUS (&mdn->dn))->ds_bp);
  err = zio_read (bp, mdn->endian, &osp, &ospsize, data);
  if (err)
    return err;
  if (ospsize < OBJSET_PHYS_SIZE_V14)
    {
      grub_free (osp);
      return grub_error (GRUB_ERR_BAD_FS, "too small osp");
    }

  mdn->endian = (grub_zfs_to_cpu64 (bp->blk_prop, mdn->endian)>>63) & 1;
  grub_memmove ((char *) &(mdn->dn),
		(char *) &((objset_phys_t *) osp)->os_meta_dnode, DNODE_SIZE);
  grub_free (osp);
  return GRUB_ERR_NONE;
}

/* Context for dnode_get_fullpath.  */
struct dnode_get_fullpath_ctx
{
  struct subvolume *subvol;
  grub_uint64_t salt;
  int keyn;
};

/* Helper for dnode_get_fullpath.  */
static int
count_zap_keys (const void *name __attribute__ ((unused)),
		grub_size_t namelen __attribute__ ((unused)),
		const void *val_in __attribute__ ((unused)),
		grub_size_t nelem __attribute__ ((unused)),
		grub_size_t elemsize __attribute__ ((unused)),
		void *data)
{
  struct dnode_get_fullpath_ctx *ctx = data;

  ctx->subvol->nkeys++;
  return 0;
}

/* Helper for dnode_get_fullpath.  */
static int
load_zap_key (const void *name, grub_size_t namelen, const void *val_in,
	      grub_size_t nelem, grub_size_t elemsize, void *data)
{
  struct dnode_get_fullpath_ctx *ctx = data;

  if (namelen != 1)
    {
      grub_dprintf ("zfs", "Unexpected key index size %" PRIuGRUB_SIZE "\n",
		    namelen);
      return 0;
    }

  if (elemsize != 1)
    {
      grub_dprintf ("zfs", "Unexpected key element size %" PRIuGRUB_SIZE "\n",
		    elemsize);
      return 0;
    }

  ctx->subvol->keyring[ctx->keyn].txg =
    grub_be_to_cpu64 (*(grub_uint64_t *) name);
  ctx->subvol->keyring[ctx->keyn].algo =
    grub_le_to_cpu64 (*(grub_uint64_t *) val_in);
  ctx->subvol->keyring[ctx->keyn].cipher =
    grub_zfs_load_key (val_in, nelem, ctx->salt,
		       ctx->subvol->keyring[ctx->keyn].algo);
  ctx->keyn++;
  return 0;
}

static grub_err_t
dnode_get_fullpath (const char *fullpath, struct subvolume *subvol,
		    dnode_end_t * dn, int *isfs,
		    struct grub_zfs_data *data)
{
  char *fsname, *snapname;
  const char *ptr_at, *filename;
  grub_uint64_t headobj;
  grub_uint64_t keychainobj;
  grub_err_t err;

  ptr_at = grub_strchr (fullpath, '@');
  if (! ptr_at)
    {
      *isfs = 1;
      filename = 0;
      snapname = 0;
      fsname = grub_strdup (fullpath);
    }
  else
    {
      const char *ptr_slash = grub_strchr (ptr_at, '/');

      *isfs = 0;
      fsname = grub_malloc (ptr_at - fullpath + 1);
      if (!fsname)
	return grub_errno;
      grub_memcpy (fsname, fullpath, ptr_at - fullpath);
      fsname[ptr_at - fullpath] = 0;
      if (ptr_at[1] && ptr_at[1] != '/')
	{
	  snapname = grub_malloc (ptr_slash - ptr_at);
	  if (!snapname)
	    {
	      grub_free (fsname);
	      return grub_errno;
	    }
	  grub_memcpy (snapname, ptr_at + 1, ptr_slash - ptr_at - 1);
	  snapname[ptr_slash - ptr_at - 1] = 0;
	}
      else
	snapname = 0;
      if (ptr_slash)
	filename = ptr_slash;
      else
	filename = "/";
      grub_dprintf ("zfs", "fsname = '%s' snapname='%s' filename = '%s'\n", 
		    fsname, snapname, filename);
    }
  grub_dprintf ("zfs", "alive\n");
  err = get_filesystem_dnode (&(data->mos), fsname, dn, data);
  if (err)
    {
      grub_free (fsname);
      grub_free (snapname);
      return err;
    }

  grub_dprintf ("zfs", "alive\n");

  headobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&dn->dn))->dd_head_dataset_obj, dn->endian);

  grub_dprintf ("zfs", "endian = %d\n", subvol->mdn.endian);

  err = dnode_get (&(data->mos), headobj, 0, &subvol->mdn, data);
  if (err)
    {
      grub_free (fsname);
      grub_free (snapname);
      return err;
    }
  grub_dprintf ("zfs", "endian = %d\n", subvol->mdn.endian);

  keychainobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&dn->dn))->keychain, dn->endian);
  if (grub_zfs_load_key && keychainobj)
    {
      struct dnode_get_fullpath_ctx ctx = {
	.subvol = subvol,
	.keyn = 0
      };
      dnode_end_t keychain_dn, props_dn;
      grub_uint64_t propsobj;
      propsobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&dn->dn))->dd_props_zapobj, dn->endian);

      err = dnode_get (&(data->mos), propsobj, DMU_OT_DSL_PROPS,
		       &props_dn, data);
      if (err)
	{
	  grub_free (fsname);
	  grub_free (snapname);
	  return err;
	}

      err = zap_lookup (&props_dn, "salt", &ctx.salt, data, 0);
      if (err == GRUB_ERR_FILE_NOT_FOUND)
	{
	  err = 0;
	  grub_errno = 0;
	  ctx.salt = 0;
	}
      if (err)
	{
	  grub_dprintf ("zfs", "failed here\n");
	  return err;
	}

      err = dnode_get (&(data->mos), keychainobj, DMU_OT_DSL_KEYCHAIN,
		       &keychain_dn, data);
      if (err)
	{
	  grub_free (fsname);
	  grub_free (snapname);
	  return err;
	}
      subvol->nkeys = 0;
      zap_iterate (&keychain_dn, 8, count_zap_keys, &ctx, data);
      subvol->keyring = grub_zalloc (subvol->nkeys * sizeof (subvol->keyring[0]));
      if (!subvol->keyring)
	{
	  grub_free (fsname);
	  grub_free (snapname);
	  return err;
	}
      zap_iterate (&keychain_dn, 8, load_zap_key, &ctx, data);
    }

  if (snapname)
    {
      grub_uint64_t snapobj;

      snapobj = grub_zfs_to_cpu64 (((dsl_dataset_phys_t *) DN_BONUS (&subvol->mdn.dn))->ds_snapnames_zapobj, subvol->mdn.endian);

      err = dnode_get (&(data->mos), snapobj, 
		       DMU_OT_DSL_DS_SNAP_MAP, &subvol->mdn, data);
      if (!err)
	err = zap_lookup (&subvol->mdn, snapname, &headobj, data, 0);
      if (!err)
	err = dnode_get (&(data->mos), headobj, DMU_OT_DSL_DATASET,
			 &subvol->mdn, data);
      if (err)
	{
	  grub_free (fsname);
	  grub_free (snapname);
	  return err;
	}
    }

  subvol->obj = headobj;

  make_mdn (&subvol->mdn, data);
  
  grub_dprintf ("zfs", "endian = %d\n", subvol->mdn.endian);

  if (*isfs)
    {
      grub_free (fsname);
      grub_free (snapname);      
      return GRUB_ERR_NONE;
    }
  err = dnode_get_path (subvol, filename, dn, data);
  grub_free (fsname);
  grub_free (snapname);
  return err;
}

static int
nvlist_find_value (const char *nvlist_in, const char *name,
		   int valtype, char **val,
		   grub_size_t *size_out, grub_size_t *nelm_out)
{
  grub_size_t nvp_name_len, name_len = grub_strlen(name);
  int type;
  const char *nvpair=NULL,*nvlist=nvlist_in;
  char *nvp_name;

  /* Verify if the 1st and 2nd byte in the nvlist are valid. */
  /* NOTE: independently of what endianness header announces all 
     subsequent values are big-endian.  */
  if (nvlist[0] != NV_ENCODE_XDR || (nvlist[1] != NV_LITTLE_ENDIAN 
				     && nvlist[1] != NV_BIG_ENDIAN))
    {
      grub_dprintf ("zfs", "incorrect nvlist header\n");
      grub_error (GRUB_ERR_BAD_FS, "incorrect nvlist");
      return 0;
    }

  /*
   * Loop thru the nvpair list
   * The XDR representation of an integer is in big-endian byte order.
   */
  while ((nvpair=nvlist_next_nvpair(nvlist,nvpair)))
    {
      nvpair_name(nvpair,&nvp_name, &nvp_name_len);
      type = nvpair_type(nvpair);
      if (type == valtype
	  && (nvp_name_len == name_len
	      || (nvp_name_len > name_len && nvp_name[name_len] == '\0'))
	  && grub_memcmp (nvp_name, name, name_len) == 0)
	{
	  return nvpair_value(nvpair,val,size_out,nelm_out);
	}
    }
  return 0;
}

int
grub_zfs_nvlist_lookup_uint64 (const char *nvlist, const char *name,
			       grub_uint64_t * out)
{
  char *nvpair;
  grub_size_t size;
  int found;

  found = nvlist_find_value (nvlist, name, DATA_TYPE_UINT64, &nvpair, &size, 0);
  if (!found)
    return 0;
  if (size < sizeof (grub_uint64_t))
    {
      grub_error (GRUB_ERR_BAD_FS, "invalid uint64");
      return 0;
    }

  *out = grub_be_to_cpu64 (grub_get_unaligned64 (nvpair));
  return 1;
}

char *
grub_zfs_nvlist_lookup_string (const char *nvlist, const char *name)
{
  char *nvpair;
  char *ret;
  grub_size_t slen;
  grub_size_t size;
  int found;

  found = nvlist_find_value (nvlist, name, DATA_TYPE_STRING, &nvpair, &size, 0);
  if (!found)
    return 0;
  if (size < 4)
    {
      grub_error (GRUB_ERR_BAD_FS, "invalid string");
      return 0;
    }
  slen = grub_be_to_cpu32 (grub_get_unaligned32 (nvpair));
  if (slen > size - 4)
    slen = size - 4;
  ret = grub_malloc (slen + 1);
  if (!ret)
    return 0;
  grub_memcpy (ret, nvpair + 4, slen);
  ret[slen] = 0;
  return ret;
}

char *
grub_zfs_nvlist_lookup_nvlist (const char *nvlist, const char *name)
{
  char *nvpair;
  char *ret;
  grub_size_t size;
  int found;

  found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST, &nvpair,
			     &size, 0);
  if (!found)
    return 0;
  ret = grub_zalloc (size + 3 * sizeof (grub_uint32_t));
  if (!ret)
    return 0;
  grub_memcpy (ret, nvlist, sizeof (grub_uint32_t));

  grub_memcpy (ret + sizeof (grub_uint32_t), nvpair, size);
  return ret;
}

int
grub_zfs_nvlist_lookup_nvlist_array_get_nelm (const char *nvlist,
					      const char *name)
{
  char *nvpair;
  grub_size_t nelm, size;
  int found;

  found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST_ARRAY, &nvpair,
			     &size, &nelm);
  if (! found)
    return -1;
  return nelm;
}

static int
get_nvlist_size (const char *beg, const char *limit)
{
  const char *ptr;
  grub_uint32_t encode_size;
  
  ptr = beg + 8;

  while (ptr < limit
	 && (encode_size = grub_be_to_cpu32 (grub_get_unaligned32 (ptr))))
    ptr += encode_size;	/* goto the next nvpair */
  ptr += 8;      
  return (ptr > limit) ? -1 : (ptr - beg);
}

char *
grub_zfs_nvlist_lookup_nvlist_array (const char *nvlist, const char *name,
				     grub_size_t index)
{
  char *nvpair, *nvpairptr;
  int found;
  char *ret;
  grub_size_t size;
  unsigned i;
  grub_size_t nelm;
  int elemsize = 0;

  found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST_ARRAY, &nvpair,
			     &size, &nelm);
  if (!found)
    return 0;
  if (index >= nelm)
    {
      grub_error (GRUB_ERR_OUT_OF_RANGE, "trying to lookup past nvlist array");
      return 0;
    }

  nvpairptr = nvpair;

  for (i = 0; i < index; i++)
    {
      int r;
      r = get_nvlist_size (nvpairptr, nvpair + size);

      if (r < 0)
	{
	  grub_error (GRUB_ERR_BAD_FS, "incorrect nvlist array");
	  return NULL;
	}
      nvpairptr += r;
    }

  elemsize = get_nvlist_size (nvpairptr, nvpair + size);

  if (elemsize < 0)
    {
      grub_error (GRUB_ERR_BAD_FS, "incorrect nvlist array");
      return 0;
    }

  ret = grub_zalloc (elemsize + sizeof (grub_uint32_t));
  if (!ret)
    return 0;
  grub_memcpy (ret, nvlist, sizeof (grub_uint32_t));

  grub_memcpy (ret + sizeof (grub_uint32_t), nvpairptr, elemsize);
  return ret;
}

static void
unmount_device (struct grub_zfs_device_desc *desc)
{
  unsigned i;
  switch (desc->type)
    {
    case DEVICE_LEAF:
      if (!desc->original && desc->dev)
	grub_device_close (desc->dev);
      return;
    case DEVICE_RAIDZ:
    case DEVICE_MIRROR:
      for (i = 0; i < desc->n_children; i++)
	unmount_device (&desc->children[i]);
      grub_free (desc->children);
      return;
    }
}

static void
zfs_unmount (struct grub_zfs_data *data)
{
  unsigned i;
  for (i = 0; i < data->n_devices_attached; i++)
    unmount_device (&data->devices_attached[i]);
  grub_free (data->devices_attached);
  grub_free (data->dnode_buf);
  grub_free (data->dnode_mdn);
  grub_free (data->file_buf);
  for (i = 0; i < data->subvol.nkeys; i++)
    grub_crypto_cipher_close (data->subvol.keyring[i].cipher);
  grub_free (data->subvol.keyring);
  grub_free (data);
}

/*
 * zfs_mount() locates a valid uberblock of the root pool and read in its MOS
 * to the memory address MOS.
 *
 */
static struct grub_zfs_data *
zfs_mount (grub_device_t dev)
{
  struct grub_zfs_data *data = 0;
  grub_err_t err;
  void *osp = 0;
  grub_size_t ospsize;
  grub_zfs_endian_t ub_endian = GRUB_ZFS_UNKNOWN_ENDIAN;
  uberblock_t *ub;
  int inserted;

  if (! dev->disk)
    {
      grub_error (GRUB_ERR_BAD_DEVICE, "not a disk");
      return 0;
    }

  data = grub_zalloc (sizeof (*data));
  if (!data)
    return 0;
#if 0
  /* if it's our first time here, zero the best uberblock out */
  if (data->best_drive == 0 && data->best_part == 0 && find_best_root)
    grub_memset (&current_uberblock, 0, sizeof (uberblock_t));
#endif

  data->n_devices_allocated = 16;
  data->devices_attached = grub_malloc (sizeof (data->devices_attached[0])
					* data->n_devices_allocated);
  data->n_devices_attached = 0;
  err = scan_disk (dev, data, 1, &inserted);
  if (err)
    {
      zfs_unmount (data);
      return NULL;
    }

  ub = &(data->current_uberblock);
  ub_endian = (grub_zfs_to_cpu64 (ub->ub_magic, 
				  GRUB_ZFS_LITTLE_ENDIAN) == UBERBLOCK_MAGIC 
	       ? GRUB_ZFS_LITTLE_ENDIAN : GRUB_ZFS_BIG_ENDIAN);

  err = zio_read (&ub->ub_rootbp, ub_endian,
		  &osp, &ospsize, data);
  if (err)
    {
      zfs_unmount (data);
      return NULL;
    }

  if (ospsize < OBJSET_PHYS_SIZE_V14)
    {
      grub_error (GRUB_ERR_BAD_FS, "OSP too small");
      grub_free (osp);
      zfs_unmount (data);
      return NULL;
    }

  if (ub->ub_version >= SPA_VERSION_FEATURES &&
      check_mos_features(&((objset_phys_t *) osp)->os_meta_dnode,ub_endian,
			 data) != 0)
    {
      grub_error (GRUB_ERR_BAD_FS, "Unsupported features in pool");
      grub_free (osp);
      zfs_unmount (data);
      return NULL;
    }

  /* Got the MOS. Save it at the memory addr MOS. */
  grub_memmove (&(data->mos.dn), &((objset_phys_t *) osp)->os_meta_dnode,
		DNODE_SIZE);
  data->mos.endian = (grub_zfs_to_cpu64 (ub->ub_rootbp.blk_prop,
					 ub_endian) >> 63) & 1;
  grub_free (osp);

  return data;
}

grub_err_t
grub_zfs_fetch_nvlist (grub_device_t dev, char **nvlist)
{
  struct grub_zfs_data *zfs;
  grub_err_t err;

  zfs = zfs_mount (dev);
  if (!zfs)
    return grub_errno;
  err = zfs_fetch_nvlist (zfs->device_original, nvlist);
  zfs_unmount (zfs);
  return err;
}

static grub_err_t 
zfs_label (grub_device_t device, char **label)
{
  char *nvlist;
  grub_err_t err;
  struct grub_zfs_data *data;

  data = zfs_mount (device);
  if (! data)
    return grub_errno;

  err = zfs_fetch_nvlist (data->device_original, &nvlist);
  if (err)      
    {
      zfs_unmount (data);
      return err;
    }

  *label = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_POOL_NAME);
  grub_free (nvlist);
  zfs_unmount (data);
  return grub_errno;
}

static grub_err_t 
zfs_uuid (grub_device_t device, char **uuid)
{
  struct grub_zfs_data *data;

  *uuid = 0;

  data = zfs_mount (device);
  if (! data)
    return grub_errno;

  *uuid = grub_xasprintf ("%016llx", (long long unsigned) data->guid);
  zfs_unmount (data);
  if (! *uuid)
    return grub_errno;
  return GRUB_ERR_NONE;
}

static grub_err_t 
zfs_mtime (grub_device_t device, grub_int32_t *mt)
{
  struct grub_zfs_data *data;
  grub_zfs_endian_t ub_endian = GRUB_ZFS_UNKNOWN_ENDIAN;
  uberblock_t *ub;

  *mt = 0;

  data = zfs_mount (device);
  if (! data)
    return grub_errno;

  ub = &(data->current_uberblock);
  ub_endian = (grub_zfs_to_cpu64 (ub->ub_magic, 
				  GRUB_ZFS_LITTLE_ENDIAN) == UBERBLOCK_MAGIC 
	       ? GRUB_ZFS_LITTLE_ENDIAN : GRUB_ZFS_BIG_ENDIAN);

  *mt = grub_zfs_to_cpu64 (ub->ub_timestamp, ub_endian);
  zfs_unmount (data);
  return GRUB_ERR_NONE;
}

/*
 * zfs_open() locates a file in the rootpool by following the
 * MOS and places the dnode of the file in the memory address DNODE.
 */
static grub_err_t
grub_zfs_open (struct grub_file *file, const char *fsfilename)
{
  struct grub_zfs_data *data;
  grub_err_t err;
  int isfs;

  data = zfs_mount (file->device);
  if (! data)
    return grub_errno;

  err = dnode_get_fullpath (fsfilename, &(data->subvol),
			    &(data->dnode), &isfs, data);
  if (err)
    {
      zfs_unmount (data);
      return err;
    }

  if (isfs)
    {
      zfs_unmount (data);
      return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("missing `%c' symbol"), '@');
    }

  /* We found the dnode for this file. Verify if it is a plain file. */
  if (data->dnode.dn.dn_type != DMU_OT_PLAIN_FILE_CONTENTS) 
    {
      zfs_unmount (data);
      return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a regular file"));
    }

  /* get the file size and set the file position to 0 */

  /*
   * For DMU_OT_SA we will need to locate the SIZE attribute
   * attribute, which could be either in the bonus buffer
   * or the "spill" block.
   */
  if (data->dnode.dn.dn_bonustype == DMU_OT_SA)
    {
      void *sahdrp;
      int hdrsize;

      if (data->dnode.dn.dn_bonuslen != 0)
	{
	  sahdrp = (sa_hdr_phys_t *) DN_BONUS (&data->dnode.dn);
	}
      else if (data->dnode.dn.dn_flags & DNODE_FLAG_SPILL_BLKPTR)
	{
	  blkptr_t *bp = &data->dnode.dn.dn_spill;

	  err = zio_read (bp, data->dnode.endian, &sahdrp, NULL, data);
	  if (err)
	    return err;
	}
      else
	{
	  return grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt");
	}

      hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp));
      file->size = grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp + hdrsize + SA_SIZE_OFFSET), data->dnode.endian);
    }
  else if (data->dnode.dn.dn_bonustype == DMU_OT_ZNODE)
    {
      file->size = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&data->dnode.dn))->zp_size, data->dnode.endian);
    }
  else
    return grub_error (GRUB_ERR_BAD_FS, "bad bonus type");

  file->data = data;
  file->offset = 0;

#ifndef GRUB_UTIL
  grub_dl_ref (my_mod);
#endif

  return GRUB_ERR_NONE;
}

static grub_ssize_t
grub_zfs_read (grub_file_t file, char *buf, grub_size_t len)
{
  struct grub_zfs_data *data = (struct grub_zfs_data *) file->data;
  grub_size_t blksz, movesize;
  grub_size_t length;
  grub_size_t read;
  grub_err_t err;

  /*
   * If offset is in memory, move it into the buffer provided and return.
   */
  if (file->offset >= data->file_start
      && file->offset + len <= data->file_end)
    {
      grub_memmove (buf, data->file_buf + file->offset - data->file_start,
		    len);
      return len;
    }

  blksz = grub_zfs_to_cpu16 (data->dnode.dn.dn_datablkszsec, 
			     data->dnode.endian) << SPA_MINBLOCKSHIFT;

  if (blksz == 0)
    {
      grub_error (GRUB_ERR_BAD_FS, "0-sized block");
      return -1;
    }

  /*
   * Entire Dnode is too big to fit into the space available.  We
   * will need to read it in chunks.  This could be optimized to
   * read in as large a chunk as there is space available, but for
   * now, this only reads in one data block at a time.
   */
  length = len;
  read = 0;
  while (length)
    {
      void *t;
      /*
       * Find requested blkid and the offset within that block.
       */
      grub_uint64_t blkid = grub_divmod64 (file->offset + read, blksz, 0);
      grub_free (data->file_buf);
      data->file_buf = 0;

      err = dmu_read (&(data->dnode), blkid, &t,
		      0, data);
      data->file_buf = t;
      if (err)
	{
	  data->file_buf = NULL;
	  data->file_start = data->file_end = 0;
	  return -1;
	}

      data->file_start = blkid * blksz;
      data->file_end = data->file_start + blksz;

      movesize = data->file_end - file->offset - read;
      if (movesize > length)
	movesize = length;

      grub_memmove (buf, data->file_buf + file->offset + read
		    - data->file_start, movesize);
      buf += movesize;
      length -= movesize;
      read += movesize;
    }

  return len;
}

static grub_err_t
grub_zfs_close (grub_file_t file)
{
  zfs_unmount ((struct grub_zfs_data *) file->data);

#ifndef GRUB_UTIL
  grub_dl_unref (my_mod);
#endif

  return GRUB_ERR_NONE;
}

grub_err_t
grub_zfs_getmdnobj (grub_device_t dev, const char *fsfilename,
		    grub_uint64_t *mdnobj)
{
  struct grub_zfs_data *data;
  grub_err_t err;
  int isfs;

  data = zfs_mount (dev);
  if (! data)
    return grub_errno;

  err = dnode_get_fullpath (fsfilename, &(data->subvol),
			    &(data->dnode), &isfs, data);
  *mdnobj = data->subvol.obj;
  zfs_unmount (data);
  return err;
}

static grub_err_t
fill_fs_info (struct grub_dirhook_info *info,
	      dnode_end_t mdn, struct grub_zfs_data *data)
{
  grub_err_t err;
  dnode_end_t dn;
  grub_uint64_t objnum;
  grub_uint64_t headobj;
  
  grub_memset (info, 0, sizeof (*info));
    
  info->dir = 1;
  
  if (mdn.dn.dn_type == DMU_OT_DSL_DIR)
    {
      headobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&mdn.dn))->dd_head_dataset_obj, mdn.endian);

      err = dnode_get (&(data->mos), headobj, 0, &mdn, data);
      if (err)
	{
	  grub_dprintf ("zfs", "failed here\n");
	  return err;
	}
    }
  err = make_mdn (&mdn, data);
  if (err)
    return err;
  err = dnode_get (&mdn, MASTER_NODE_OBJ, DMU_OT_MASTER_NODE, 
		   &dn, data);
  if (err)
    {
      grub_dprintf ("zfs", "failed here\n");
      return err;
    }
  
  err = zap_lookup (&dn, ZFS_ROOT_OBJ, &objnum, data, 0);
  if (err)
    {
      grub_dprintf ("zfs", "failed here\n");
      return err;
    }
  
  err = dnode_get (&mdn, objnum, 0, &dn, data);
  if (err)
    {
      grub_dprintf ("zfs", "failed here\n");
      return err;
    }
  
  if (dn.dn.dn_bonustype == DMU_OT_SA)
    {
      void *sahdrp;
      int hdrsize;

      if (dn.dn.dn_bonuslen != 0)
	{
	  sahdrp = (sa_hdr_phys_t *) DN_BONUS (&dn.dn);
	}
      else if (dn.dn.dn_flags & DNODE_FLAG_SPILL_BLKPTR)
	{
	  blkptr_t *bp = &dn.dn.dn_spill;

	  err = zio_read (bp, dn.endian, &sahdrp, NULL, data);
	  if (err)
	    return err;
	}
      else
	{
	  grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt");
	  return grub_errno;
	}

      hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp));
      info->mtimeset = 1;
      info->mtime = grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp + hdrsize + SA_MTIME_OFFSET), dn.endian);
    }

  if (dn.dn.dn_bonustype == DMU_OT_ZNODE)
    {
      info->mtimeset = 1;
      info->mtime = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&dn.dn))->zp_mtime[0], dn.endian);
    }
  return 0;
}

/* Helper for grub_zfs_dir.  */
static int
iterate_zap (const char *name, grub_uint64_t val, struct grub_zfs_dir_ctx *ctx)
{
  grub_err_t err;
  struct grub_dirhook_info info;

  dnode_end_t dn;
  grub_memset (&info, 0, sizeof (info));

  err = dnode_get (&(ctx->data->subvol.mdn), val, 0, &dn, ctx->data);
  if (err)
    {
      grub_print_error ();
      return 0;
    }

  if (dn.dn.dn_bonustype == DMU_OT_SA)
    {
      void *sahdrp;
      int hdrsize;

      if (dn.dn.dn_bonuslen != 0)
	{
	  sahdrp = (sa_hdr_phys_t *) DN_BONUS (&ctx->data->dnode.dn);
	}
      else if (dn.dn.dn_flags & DNODE_FLAG_SPILL_BLKPTR)
	{
	  blkptr_t *bp = &dn.dn.dn_spill;

	  err = zio_read (bp, dn.endian, &sahdrp, NULL, ctx->data);
	  if (err)
	    {
	      grub_print_error ();
	      return 0;
	    }
	}
      else
	{
	  grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt");
	  grub_print_error ();
	  return 0;
	}

      hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp));
      info.mtimeset = 1;
      info.mtime = grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp + hdrsize + SA_MTIME_OFFSET), dn.endian);
      info.case_insensitive = ctx->data->subvol.case_insensitive;
    }
  
  if (dn.dn.dn_bonustype == DMU_OT_ZNODE)
    {	
      info.mtimeset = 1;
      info.mtime = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&dn.dn))->zp_mtime[0],
				      dn.endian);
    }
  info.dir = (dn.dn.dn_type == DMU_OT_DIRECTORY_CONTENTS);
  grub_dprintf ("zfs", "type=%d, name=%s\n", 
		(int)dn.dn.dn_type, (char *)name);
  return ctx->hook (name, &info, ctx->hook_data);
}

/* Helper for grub_zfs_dir.  */
static int
iterate_zap_fs (const char *name, grub_uint64_t val,
		struct grub_zfs_dir_ctx *ctx)
{
  grub_err_t err;
  struct grub_dirhook_info info;

  dnode_end_t mdn;
  err = dnode_get (&(ctx->data->mos), val, 0, &mdn, ctx->data);
  if (err)
    {
      grub_errno = 0;
      return 0;
    }
  if (mdn.dn.dn_type != DMU_OT_DSL_DIR)
    return 0;

  err = fill_fs_info (&info, mdn, ctx->data);
  if (err)
    {
      grub_errno = 0;
      return 0;
    }
  return ctx->hook (name, &info, ctx->hook_data);
}

/* Helper for grub_zfs_dir.  */
static int
iterate_zap_snap (const char *name, grub_uint64_t val,
		  struct grub_zfs_dir_ctx *ctx)
{
  grub_err_t err;
  struct grub_dirhook_info info;
  char *name2;
  int ret;

  dnode_end_t mdn;

  err = dnode_get (&(ctx->data->mos), val, 0, &mdn, ctx->data);
  if (err)
    {
      grub_errno = 0;
      return 0;
    }

  if (mdn.dn.dn_type != DMU_OT_DSL_DATASET)
    return 0;

  err = fill_fs_info (&info, mdn, ctx->data);
  if (err)
    {
      grub_errno = 0;
      return 0;
    }

  name2 = grub_malloc (grub_strlen (name) + 2);
  name2[0] = '@';
  grub_memcpy (name2 + 1, name, grub_strlen (name) + 1);
  ret = ctx->hook (name2, &info, ctx->hook_data);
  grub_free (name2);
  return ret;
}

static grub_err_t
grub_zfs_dir (grub_device_t device, const char *path,
	      grub_fs_dir_hook_t hook, void *hook_data)
{
  struct grub_zfs_dir_ctx ctx = {
    .hook = hook,
    .hook_data = hook_data
  };
  struct grub_zfs_data *data;
  grub_err_t err;
  int isfs;

  data = zfs_mount (device);
  if (! data)
    return grub_errno;
  err = dnode_get_fullpath (path, &(data->subvol), &(data->dnode), &isfs, data);
  if (err)
    {
      zfs_unmount (data);
      return err;
    }
  ctx.data = data;

  if (isfs)
    {
      grub_uint64_t childobj, headobj; 
      grub_uint64_t snapobj;
      dnode_end_t dn;
      struct grub_dirhook_info info;

      err = fill_fs_info (&info, data->dnode, data);
      if (err)
	{
	  zfs_unmount (data);
	  return err;
	}
      if (hook ("@", &info, hook_data))
	{
	  zfs_unmount (data);
	  return GRUB_ERR_NONE;
	}

      childobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&data->dnode.dn))->dd_child_dir_zapobj, data->dnode.endian);
      headobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&data->dnode.dn))->dd_head_dataset_obj, data->dnode.endian);
      err = dnode_get (&(data->mos), childobj,
		       DMU_OT_DSL_DIR_CHILD_MAP, &dn, data);
      if (err)
	{
	  zfs_unmount (data);
	  return err;
	}

      zap_iterate_u64 (&dn, iterate_zap_fs, data, &ctx);
      
      err = dnode_get (&(data->mos), headobj, DMU_OT_DSL_DATASET, &dn, data);
      if (err)
	{
	  zfs_unmount (data);
	  return err;
	}

      snapobj = grub_zfs_to_cpu64 (((dsl_dataset_phys_t *) DN_BONUS (&dn.dn))->ds_snapnames_zapobj, dn.endian);

      err = dnode_get (&(data->mos), snapobj,
		       DMU_OT_DSL_DS_SNAP_MAP, &dn, data);
      if (err)
	{
	  zfs_unmount (data);
	  return err;
	}

      zap_iterate_u64 (&dn, iterate_zap_snap, data, &ctx);
    }
  else
    {
      if (data->dnode.dn.dn_type != DMU_OT_DIRECTORY_CONTENTS)
	{
	  zfs_unmount (data);
	  return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
	}
      zap_iterate_u64 (&(data->dnode), iterate_zap, data, &ctx);
    }
  zfs_unmount (data);
  return grub_errno;
}

static int
check_feature (const char *name, grub_uint64_t val,
	       struct grub_zfs_dir_ctx *ctx __attribute__((unused)))
{
  int i;
  if (val == 0)
    return 0;
  if (name[0] == 0)
    return 0;
  for (i = 0; spa_feature_names[i] != NULL; i++) 
    if (grub_strcmp (name, spa_feature_names[i]) == 0) 
      return 0;
  return 1;
}

/*
 * Checks whether the MOS features that are active are supported by this
 * (GRUB's) implementation of ZFS.
 *
 * Return:
 *	0: Success.
 *	errnum: Failure.
 */
	    	   
static grub_err_t
check_mos_features(dnode_phys_t *mosmdn_phys,grub_zfs_endian_t endian,struct grub_zfs_data* data )
{
  grub_uint64_t objnum;
  grub_err_t errnum = 0;
  dnode_end_t dn,mosmdn;
  mzap_phys_t* mzp;
  grub_zfs_endian_t endianzap;
  int size;
  grub_memmove(&(mosmdn.dn),mosmdn_phys,sizeof(dnode_phys_t));
  mosmdn.endian=endian;
  errnum = dnode_get(&mosmdn, DMU_POOL_DIRECTORY_OBJECT,
		     DMU_OT_OBJECT_DIRECTORY, &dn,data);
  if (errnum != 0)
    return errnum;

  /*
   * Find the object number for 'features_for_read' and retrieve its
   * corresponding dnode. Note that we don't check features_for_write
   * because GRUB is not opening the pool for write.
   */
  errnum = zap_lookup(&dn, DMU_POOL_FEATURES_FOR_READ, &objnum, data,0);
  if (errnum != 0)
    return errnum;
  
  errnum = dnode_get(&mosmdn, objnum, DMU_OTN_ZAP_METADATA, &dn, data);
  if (errnum != 0)
    return errnum;

  errnum = dmu_read(&dn, 0, (void**)&mzp, &endianzap,data);
  if (errnum != 0)
    return errnum;

  size = grub_zfs_to_cpu16 (dn.dn.dn_datablkszsec, dn.endian) << SPA_MINBLOCKSHIFT;
  return mzap_iterate (mzp,endianzap, size, check_feature,NULL);
}


#ifdef GRUB_UTIL
static grub_err_t
grub_zfs_embed (grub_device_t device __attribute__ ((unused)),
		unsigned int *nsectors,
		unsigned int max_nsectors,
		grub_embed_type_t embed_type,
		grub_disk_addr_t **sectors)
{
  unsigned i;

  if (embed_type != GRUB_EMBED_PCBIOS)
    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
		       "ZFS currently supports only PC-BIOS embedding");

  if ((VDEV_BOOT_SIZE >> GRUB_DISK_SECTOR_BITS) < *nsectors)
    return grub_error (GRUB_ERR_OUT_OF_RANGE,
		       N_("your core.img is unusually large.  "
			  "It won't fit in the embedding area"));

  *nsectors = (VDEV_BOOT_SIZE >> GRUB_DISK_SECTOR_BITS);
  if (*nsectors > max_nsectors)
    *nsectors = max_nsectors;
  *sectors = grub_malloc (*nsectors * sizeof (**sectors));
  if (!*sectors)
    return grub_errno;
  for (i = 0; i < *nsectors; i++)
    (*sectors)[i] = i + (VDEV_BOOT_OFFSET >> GRUB_DISK_SECTOR_BITS);

  return GRUB_ERR_NONE;
}
#endif

static struct grub_fs grub_zfs_fs = {
  .name = "zfs",
  .dir = grub_zfs_dir,
  .open = grub_zfs_open,
  .read = grub_zfs_read,
  .close = grub_zfs_close,
  .label = zfs_label,
  .uuid = zfs_uuid,
  .mtime = zfs_mtime,
#ifdef GRUB_UTIL
  .embed = grub_zfs_embed,
  .reserved_first_sector = 1,
  .blocklist_install = 0,
#endif
  .next = 0
};

GRUB_MOD_INIT (zfs)
{
  COMPILE_TIME_ASSERT (sizeof (zap_leaf_chunk_t) == ZAP_LEAF_CHUNKSIZE);
  grub_fs_register (&grub_zfs_fs);
#ifndef GRUB_UTIL
  my_mod = mod;
#endif
}

GRUB_MOD_FINI (zfs)
{
  grub_fs_unregister (&grub_zfs_fs);
}
