/*
 *  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_calloc (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_calloc (*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);
}
