All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0 of 1] [PATCH v2] update ZFS for pygrub from illumos
@ 2013-10-31 19:04 Igor Kozhkuhov
  2013-10-31 19:04 ` [PATCH 1 of 1] Update ZFS sources from illumos.org: Igor Kozhkuhov
  0 siblings, 1 reply; 14+ messages in thread
From: Igor Kozhkuhov @ 2013-10-31 19:04 UTC (permalink / raw)
  To: xen-devel; +Cc: ikozhukhov, Ian Jackson, Ian Campbell

Provide update only for ZFS from illumos upstream for pygrub

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 1 of 1] Update ZFS sources from illumos.org:
  2013-10-31 19:04 [PATCH 0 of 1] [PATCH v2] update ZFS for pygrub from illumos Igor Kozhkuhov
@ 2013-10-31 19:04 ` Igor Kozhkuhov
  2013-11-11 16:23   ` Ian Campbell
  0 siblings, 1 reply; 14+ messages in thread
From: Igor Kozhkuhov @ 2013-10-31 19:04 UTC (permalink / raw)
  To: xen-devel; +Cc: ikozhukhov, Ian Jackson, Ian Campbell

https://github.com/illumos/illumos-gate/tree/master/usr/src/grub/grub-0.97/stage2
Additional CFLAGS rules have been added after 'CFLAGS += -Werror -D_GNU_SOURCE' in Rules.mk

Signed-off-by: Igor Kozhukhov <ikozhukhov@gmail.com>
Asked-by: Ian Campbell <Ian.Campbell@citrix.com>

diff -r 7c12aaa128e3 -r 7afe0b19c898 tools/libfsimage/zfs/Makefile
--- a/tools/libfsimage/zfs/Makefile	Thu Oct 24 22:46:20 2013 +0100
+++ b/tools/libfsimage/zfs/Makefile	Thu Oct 31 22:48:42 2013 +0400
@@ -25,7 +25,7 @@
 XEN_ROOT = $(CURDIR)/../../..
 
 CFLAGS += -DFSYS_ZFS -DFSIMAGE -I$(XEN_ROOT)/tools/libfsimage/zfs
-LIB_SRCS-y = zfs_lzjb.c zfs_sha256.c zfs_fletcher.c fsi_zfs.c fsys_zfs.c
+LIB_SRCS-y = zfs_lzjb.c zfs_sha256.c zfs_fletcher.c fsi_zfs.c fsys_zfs.c zfs_lz4.c
 
 FS = zfs
 
@@ -36,3 +36,8 @@ all: fs-all
 install: fs-install
 
 include $(XEN_ROOT)/tools/libfsimage/Rules.mk
+
+# need for build illumos ZFS
+CFLAGS += -Wno-parentheses
+CFLAGS += -Wno-unused
+# end
diff -r 7c12aaa128e3 -r 7afe0b19c898 tools/libfsimage/zfs/fsi_zfs.h
--- a/tools/libfsimage/zfs/fsi_zfs.h	Thu Oct 24 22:46:20 2013 +0100
+++ b/tools/libfsimage/zfs/fsi_zfs.h	Thu Oct 31 22:48:42 2013 +0400
@@ -36,6 +36,8 @@
 
 /* Boot signature related defines for the findroot command */
 #define	BOOTSIGN_DIR	"/boot/grub/bootsign"
+#define	BOOTSIGN_ARGLEN	(MAXNAMELEN + 10)	/* (<sign>,0,d) */
+#define	BOOTSIGN_LEN	(sizeof (BOOTSIGN_DIR) + 1 + BOOTSIGN_ARGLEN)
 #define	BOOTSIGN_BACKUP	"/etc/bootsign"
 
 /* Maybe redirect memory requests through grub_scratch_mem. */
@@ -60,6 +62,7 @@
 #define grub_strstr strstr
 #define grub_strlen strlen
 #define grub_memmove memmove
+#define grub_isspace isspace
 
 extern char current_bootpath[MAXPATHLEN];
 extern char current_rootpool[MAXNAMELEN];
diff -r 7c12aaa128e3 -r 7afe0b19c898 tools/libfsimage/zfs/fsys_zfs.c
--- a/tools/libfsimage/zfs/fsys_zfs.c	Thu Oct 24 22:46:20 2013 +0100
+++ b/tools/libfsimage/zfs/fsys_zfs.c	Thu Oct 31 22:48:42 2013 +0400
@@ -16,12 +16,18 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
+
 /*
  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
 /*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
+ */
+
+/*
  * The zfs plug-in routines for GRUB are:
  *
  * zfs_mount() - locates a valid uberblock of the root pool and reads
@@ -69,7 +75,18 @@ decomp_entry_t decomp_table[ZIO_COMPRESS
 	{"on", lzjb_decompress}, 	/* ZIO_COMPRESS_ON */
 	{"off", 0},			/* ZIO_COMPRESS_OFF */
 	{"lzjb", lzjb_decompress},	/* ZIO_COMPRESS_LZJB */
-	{"empty", 0}			/* ZIO_COMPRESS_EMPTY */
+	{"empty", 0},			/* ZIO_COMPRESS_EMPTY */
+	{"gzip-1", 0},			/* ZIO_COMPRESS_GZIP_1 */
+	{"gzip-2", 0},			/* ZIO_COMPRESS_GZIP_2 */
+	{"gzip-3", 0},			/* ZIO_COMPRESS_GZIP_3 */
+	{"gzip-4", 0},			/* ZIO_COMPRESS_GZIP_4 */
+	{"gzip-5", 0},			/* ZIO_COMPRESS_GZIP_5 */
+	{"gzip-6", 0},			/* ZIO_COMPRESS_GZIP_6 */
+	{"gzip-7", 0},			/* ZIO_COMPRESS_GZIP_7 */
+	{"gzip-8", 0},			/* ZIO_COMPRESS_GZIP_8 */
+	{"gzip-9", 0},			/* ZIO_COMPRESS_GZIP_9 */
+	{"zle", 0},			/* ZIO_COMPRESS_ZLE */
+	{"lz4", lz4_decompress}		/* ZIO_COMPRESS_LZ4 */
 };
 
 static int zio_read_data(blkptr_t *bp, void *buf, char *stack);
@@ -80,8 +97,8 @@ static int zio_read_data(blkptr_t *bp, v
 static int
 zfs_bcmp(const void *s1, const void *s2, size_t n)
 {
-	const uint8_t *ps1 = s1;
-	const uint8_t *ps2 = s2;
+	const uchar_t *ps1 = s1;
+	const uchar_t *ps2 = s2;
 
 	if (s1 != s2 && n != 0) {
 		do {
@@ -118,16 +135,16 @@ zio_checksum_off(const void *buf, uint64
 
 /* Checksum Table and Values */
 zio_checksum_info_t zio_checksum_table[ZIO_CHECKSUM_FUNCTIONS] = {
-	{ { NULL, NULL }, 0, 0, "inherit" },
-	{ { NULL, NULL }, 0, 0, "on" },
-	{ { zio_checksum_off, zio_checksum_off }, 0, 0, "off" },
-	{ { zio_checksum_SHA256, zio_checksum_SHA256 }, 1, 1, "label" },
-	{ { zio_checksum_SHA256, zio_checksum_SHA256 }, 1, 1, "gang_header" },
-	{ { NULL, NULL }, 0, 0, "zilog" },
-	{ { fletcher_2_native, fletcher_2_byteswap }, 0, 0, "fletcher2" },
-	{ { fletcher_4_native, fletcher_4_byteswap }, 1, 0, "fletcher4" },
-	{ { zio_checksum_SHA256, zio_checksum_SHA256 }, 1, 0, "SHA256" },
-	{ { NULL, NULL }, 0, 0, "zilog2" }
+	{{NULL,			NULL},			0, 0,	"inherit"},
+	{{NULL,			NULL},			0, 0,	"on"},
+	{{zio_checksum_off,	zio_checksum_off},	0, 0,	"off"},
+	{{zio_checksum_SHA256,	zio_checksum_SHA256},	1, 1,	"label"},
+	{{zio_checksum_SHA256,	zio_checksum_SHA256},	1, 1,	"gang_header"},
+	{{NULL,			NULL},			0, 0,	"zilog"},
+	{{fletcher_2_native,	fletcher_2_byteswap},	0, 0,	"fletcher2"},
+	{{fletcher_4_native,	fletcher_4_byteswap},	1, 0,	"fletcher4"},
+	{{zio_checksum_SHA256,	zio_checksum_SHA256},	1, 0,	"SHA256"},
+	{{NULL,			NULL},			0, 0,	"zilog2"},
 };
 
 /*
@@ -217,18 +234,13 @@ vdev_uberblock_compare(uberblock_t *ub1,
  * 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
- * Need to Implement: checksum
- *
  * Return:
  *     0 - Success
  *    -1 - Failure
  */
 static int
-uberblock_verify(uberblock_phys_t *ub, uint64_t offset)
+uberblock_verify(uberblock_t *uber, uint64_t ub_size, uint64_t offset)
 {
-
-	uberblock_t *uber = &ub->ubp_uberblock;
 	blkptr_t bp;
 
 	BP_ZERO(&bp);
@@ -236,11 +248,11 @@ uberblock_verify(uberblock_phys_t *ub, u
 	BP_SET_BYTEORDER(&bp, ZFS_HOST_BYTEORDER);
 	ZIO_SET_CHECKSUM(&bp.blk_cksum, offset, 0, 0, 0);
 
-	if (zio_checksum_verify(&bp, (char *)ub, UBERBLOCK_SIZE) != 0)
+	if (zio_checksum_verify(&bp, (char *)uber, ub_size) != 0)
 		return (-1);
 
 	if (uber->ub_magic == UBERBLOCK_MAGIC &&
-	    uber->ub_version > 0 && uber->ub_version <= SPA_VERSION)
+	    SPA_VERSION_IS_SUPPORTED(uber->ub_version))
 		return (0);
 
 	return (-1);
@@ -252,25 +264,28 @@ uberblock_verify(uberblock_phys_t *ub, u
  *    Success - Pointer to the best uberblock.
  *    Failure - NULL
  */
-static uberblock_phys_t *
-find_bestub(uberblock_phys_t *ub_array, uint64_t sector)
+static uberblock_t *
+find_bestub(char *ub_array, uint64_t ashift, uint64_t sector)
 {
-	uberblock_phys_t *ubbest = NULL;
-	uint64_t offset;
+	uberblock_t *ubbest = NULL;
+	uberblock_t *ubnext;
+	uint64_t offset, ub_size;
 	int i;
 
-	for (i = 0; i < (VDEV_UBERBLOCK_RING >> VDEV_UBERBLOCK_SHIFT); i++) {
+	ub_size = VDEV_UBERBLOCK_SIZE(ashift);
+
+	for (i = 0; i < VDEV_UBERBLOCK_COUNT(ashift); i++) {
+		ubnext = (uberblock_t *)ub_array;
+		ub_array += ub_size;
 		offset = (sector << SPA_MINBLOCKSHIFT) +
-		    VDEV_UBERBLOCK_OFFSET(i);
-		if (uberblock_verify(&ub_array[i], offset) == 0) {
-			if (ubbest == NULL) {
-				ubbest = &ub_array[i];
-			} else if (vdev_uberblock_compare(
-			    &(ub_array[i].ubp_uberblock),
-			    &(ubbest->ubp_uberblock)) > 0) {
-				ubbest = &ub_array[i];
-			}
-		}
+		    VDEV_UBERBLOCK_OFFSET(ashift, i);
+
+		if (uberblock_verify(ubnext, ub_size, offset) != 0)
+			continue;
+
+		if (ubbest == NULL ||
+		    vdev_uberblock_compare(ubnext, ubbest) > 0)
+			ubbest = ubnext;
 	}
 
 	return (ubbest);
@@ -295,7 +310,7 @@ zio_read_gang(blkptr_t *bp, dva_t *dva, 
 	zio_gb = (zio_gbh_phys_t *)stack;
 	stack += SPA_GANGBLOCKSIZE;
 	offset = DVA_GET_OFFSET(dva);
-	sector =  DVA_OFFSET_TO_PHYS_SECTOR(offset);
+	sector = DVA_OFFSET_TO_PHYS_SECTOR(offset);
 
 	/* read in the gang block header */
 	if (devread(sector, 0, SPA_GANGBLOCKSIZE, (char *)zio_gb) == 0) {
@@ -354,8 +369,8 @@ zio_read_data(blkptr_t *bp, void *buf, c
 		} else {
 			/* read in a data block */
 			offset = DVA_GET_OFFSET(&bp->blk_dva[i]);
-			sector =  DVA_OFFSET_TO_PHYS_SECTOR(offset);
-			if (devread(sector, 0, psize, buf))
+			sector = DVA_OFFSET_TO_PHYS_SECTOR(offset);
+			if (devread(sector, 0, psize, buf) != 0)
 				return (0);
 		}
 	}
@@ -399,7 +414,7 @@ zio_read(blkptr_t *bp, void *buf, char *
 		stack += psize;
 	}
 
-	if (zio_read_data(bp, buf, stack)) {
+	if (zio_read_data(bp, buf, stack) != 0) {
 		grub_printf("zio_read_data failed\n");
 		return (ERR_FSYS_CORRUPT);
 	}
@@ -409,8 +424,13 @@ zio_read(blkptr_t *bp, void *buf, char *
 		return (ERR_FSYS_CORRUPT);
 	}
 
-	if (comp != ZIO_COMPRESS_OFF)
-		decomp_table[comp].decomp_func(buf, retbuf, psize, lsize);
+	if (comp != ZIO_COMPRESS_OFF) {
+		if (decomp_table[comp].decomp_func(buf, retbuf, psize,
+		    lsize) != 0) {
+			grub_printf("zio_read decompression failed\n");
+			return (ERR_FSYS_CORRUPT);
+		}
+	}
 
 	return (0);
 }
@@ -446,7 +466,7 @@ dmu_read(dnode_phys_t *dn, uint64_t blki
 			grub_memset(buf, 0,
 			    dn->dn_datablkszsec << SPA_MINBLOCKSHIFT);
 			break;
-		} else if ((errnum = zio_read(bp, tmpbuf, stack))) {
+		} else if (errnum = zio_read(bp, tmpbuf, stack)) {
 			return (errnum);
 		}
 
@@ -465,13 +485,13 @@ dmu_read(dnode_phys_t *dn, uint64_t blki
  *	errnum - failure
  */
 static int
-mzap_lookup(mzap_phys_t *zapobj, int objsize, char *name,
+mzap_lookup(mzap_phys_t *zapobj, int objsize, const char *name,
 	uint64_t *value)
 {
 	int i, chunks;
 	mzap_ent_phys_t *mzap_ent = zapobj->mz_chunk;
 
-	chunks = objsize/MZAP_ENT_LEN - 1;
+	chunks = objsize / MZAP_ENT_LEN - 1;
 	for (i = 0; i < chunks; i++) {
 		if (grub_strcmp(mzap_ent[i].mze_name, name) == 0) {
 			*value = mzap_ent[i].mze_value;
@@ -511,8 +531,8 @@ zap_hash(uint64_t salt, const char *name
 	/*
 	 * 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.
+	 * those are the ones that we first pay attention to when
+	 * choosing the bucket.
 	 */
 	crc &= ~((1ULL << (64 - 28)) - 1);
 
@@ -617,7 +637,7 @@ zap_leaf_lookup(zap_leaf_phys_t *l, int 
  */
 static int
 fzap_lookup(dnode_phys_t *zap_dnode, zap_phys_t *zap,
-    char *name, uint64_t *value, char *stack)
+    const char *name, uint64_t *value, char *stack)
 {
 	zap_leaf_phys_t *l;
 	uint64_t hash, idx, blkid;
@@ -645,7 +665,7 @@ fzap_lookup(dnode_phys_t *zap_dnode, zap
 	stack += 1<<blksft;
 	if ((1<<blksft) < sizeof (zap_leaf_phys_t))
 		return (ERR_FSYS_CORRUPT);
-	if ((errnum = dmu_read(zap_dnode, blkid, l, stack)))
+	if (errnum = dmu_read(zap_dnode, blkid, l, stack))
 		return (errnum);
 
 	return (zap_leaf_lookup(l, blksft, hash, name, value));
@@ -660,7 +680,8 @@ fzap_lookup(dnode_phys_t *zap_dnode, zap
  *	errnum - failure
  */
 static int
-zap_lookup(dnode_phys_t *zap_dnode, char *name, uint64_t *val, char *stack)
+zap_lookup(dnode_phys_t *zap_dnode, const char *name, uint64_t *val,
+    char *stack)
 {
 	uint64_t block_type;
 	int size;
@@ -671,7 +692,7 @@ zap_lookup(dnode_phys_t *zap_dnode, char
 	size = zap_dnode->dn_datablkszsec << SPA_MINBLOCKSHIFT;
 	stack += size;
 
-	if ((errnum = dmu_read(zap_dnode, 0, zapbuf, stack)))
+	if ((errnum = dmu_read(zap_dnode, 0, zapbuf, stack)) != 0)
 		return (errnum);
 
 	block_type = *((uint64_t *)zapbuf);
@@ -687,6 +708,56 @@ zap_lookup(dnode_phys_t *zap_dnode, char
 	return (ERR_FSYS_CORRUPT);
 }
 
+typedef struct zap_attribute {
+	int za_integer_length;
+	uint64_t za_num_integers;
+	uint64_t za_first_integer;
+	char *za_name;
+} zap_attribute_t;
+
+typedef int (zap_cb_t)(zap_attribute_t *za, void *arg, char *stack);
+
+static int
+zap_iterate(dnode_phys_t *zap_dnode, zap_cb_t *cb, void *arg, char *stack)
+{
+	uint32_t size = zap_dnode->dn_datablkszsec << SPA_MINBLOCKSHIFT;
+	zap_attribute_t za;
+	int i;
+	mzap_phys_t *mzp = (mzap_phys_t *)stack;
+	stack += size;
+
+	if ((errnum = dmu_read(zap_dnode, 0, mzp, stack)) != 0)
+		return (errnum);
+
+	/*
+	 * Iteration over fatzap objects has not yet been implemented.
+	 * If we encounter a pool in which there are more features for
+	 * read than can fit inside a microzap (i.e., more than 2048
+	 * features for read), we can add support for fatzap iteration.
+	 * For now, fail.
+	 */
+	if (mzp->mz_block_type != ZBT_MICRO) {
+		grub_printf("feature information stored in fatzap, pool "
+		    "version not supported\n");
+		return (1);
+	}
+
+	za.za_integer_length = 8;
+	za.za_num_integers = 1;
+	for (i = 0; i < size / MZAP_ENT_LEN - 1; i++) {
+		mzap_ent_phys_t *mzep = &mzp->mz_chunk[i];
+		int err;
+
+		za.za_first_integer = mzep->mze_value;
+		za.za_name = mzep->mze_name;
+		err = cb(&za, arg, stack);
+		if (err != 0)
+			return (err);
+	}
+
+	return (0);
+}
+
 /*
  * Get the dnode of an object number from the metadnode of an object set.
  *
@@ -731,7 +802,7 @@ dnode_get(dnode_phys_t *mdn, uint64_t ob
 		stack += blksz;
 	}
 
-	if ((errnum = dmu_read(mdn, blkid, (char *)dnbuf, stack)))
+	if (errnum = dmu_read(mdn, blkid, (char *)dnbuf, stack))
 		return (errnum);
 
 	grub_memmove(buf, &dnbuf[idx], DNODE_SIZE);
@@ -766,6 +837,24 @@ is_top_dataset_file(char *str)
 	return (0);
 }
 
+static int
+check_feature(zap_attribute_t *za, void *arg, char *stack)
+{
+	const char **names = arg;
+	int i;
+
+	if (za->za_first_integer == 0)
+		return (0);
+
+	for (i = 0; names[i] != NULL; i++) {
+		if (grub_strcmp(za->za_name, names[i]) == 0) {
+			return (0);
+		}
+	}
+	grub_printf("missing feature for read '%s'\n", za->za_name);
+	return (ERR_NEWER_VERSION);
+}
+
 /*
  * 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.
@@ -782,40 +871,40 @@ dnode_get_path(dnode_phys_t *mdn, char *
 	uint64_t objnum, version;
 	char *cname, ch;
 
-	if ((errnum = dnode_get(mdn, MASTER_NODE_OBJ, DMU_OT_MASTER_NODE,
-	    dn, stack)))
+	if (errnum = dnode_get(mdn, MASTER_NODE_OBJ, DMU_OT_MASTER_NODE,
+	    dn, stack))
 		return (errnum);
 
-	if ((errnum = zap_lookup(dn, ZPL_VERSION_STR, &version, stack)))
+	if (errnum = zap_lookup(dn, ZPL_VERSION_STR, &version, stack))
 		return (errnum);
 	if (version > ZPL_VERSION)
 		return (-1);
 
-	if ((errnum = zap_lookup(dn, ZFS_ROOT_OBJ, &objnum, stack)))
+	if (errnum = zap_lookup(dn, ZFS_ROOT_OBJ, &objnum, stack))
 		return (errnum);
 
-	if ((errnum = dnode_get(mdn, objnum, DMU_OT_DIRECTORY_CONTENTS,
-	    dn, stack)))
+	if (errnum = dnode_get(mdn, objnum, DMU_OT_DIRECTORY_CONTENTS,
+	    dn, stack))
 		return (errnum);
 
 	/* skip leading slashes */
 	while (*path == '/')
 		path++;
 
-	while (*path && !isspace((uint8_t)*path)) {
+	while (*path && !grub_isspace(*path)) {
 
 		/* get the next component name */
 		cname = path;
-		while (*path && !isspace((uint8_t)*path) && *path != '/')
+		while (*path && !grub_isspace(*path) && *path != '/')
 			path++;
 		ch = *path;
 		*path = 0;   /* ensure null termination */
 
-		if ((errnum = zap_lookup(dn, cname, &objnum, stack)))
+		if (errnum = zap_lookup(dn, cname, &objnum, stack))
 			return (errnum);
 
 		objnum = ZFS_DIRENT_OBJ(objnum);
-		if ((errnum = dnode_get(mdn, objnum, 0, dn, stack)))
+		if (errnum = dnode_get(mdn, objnum, 0, dn, stack))
 			return (errnum);
 
 		*path = ch;
@@ -843,8 +932,8 @@ get_default_bootfsobj(dnode_phys_t *mosm
 	dnode_phys_t *dn = (dnode_phys_t *)stack;
 	stack += DNODE_SIZE;
 
-	if ((errnum = dnode_get(mosmdn, DMU_POOL_DIRECTORY_OBJECT,
-	    DMU_OT_OBJECT_DIRECTORY, dn, stack)))
+	if (errnum = dnode_get(mosmdn, DMU_POOL_DIRECTORY_OBJECT,
+	    DMU_OT_OBJECT_DIRECTORY, dn, stack))
 		return (errnum);
 
 	/*
@@ -854,7 +943,7 @@ get_default_bootfsobj(dnode_phys_t *mosm
 	if (zap_lookup(dn, DMU_POOL_PROPS, &objnum, stack))
 		return (ERR_FILESYSTEM_NOT_FOUND);
 
-	if ((errnum = dnode_get(mosmdn, objnum, DMU_OT_POOL_PROPS, dn, stack)))
+	if (errnum = dnode_get(mosmdn, objnum, DMU_OT_POOL_PROPS, dn, stack))
 		return (errnum);
 
 	if (zap_lookup(dn, ZPOOL_PROP_BOOTFS, &objnum, stack))
@@ -868,6 +957,57 @@ get_default_bootfsobj(dnode_phys_t *mosm
 }
 
 /*
+ * 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.
+ *
+ * When this list is updated the version number in usr/src/grub/capability
+ * must be incremented to ensure the new grub gets installed.
+ */
+static const char *spa_feature_names[] = {
+	"org.illumos:lz4_compress",
+	NULL
+};
+
+/*
+ * Checks whether the MOS features that are active are supported by this
+ * (GRUB's) implementation of ZFS.
+ *
+ * Return:
+ *	0: Success.
+ *	errnum: Failure.
+ */
+static int
+check_mos_features(dnode_phys_t *mosmdn, char *stack)
+{
+	uint64_t objnum;
+	dnode_phys_t *dn;
+	uint8_t error = 0;
+
+	dn = (dnode_phys_t *)stack;
+	stack += DNODE_SIZE;
+
+	if ((errnum = dnode_get(mosmdn, DMU_POOL_DIRECTORY_OBJECT,
+	    DMU_OT_OBJECT_DIRECTORY, dn, stack)) != 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.
+	 */
+	if ((errnum = zap_lookup(dn, DMU_POOL_FEATURES_FOR_READ, &objnum,
+	    stack)) != 0)
+		return (errnum);
+
+	if ((errnum = dnode_get(mosmdn, objnum, DMU_OTN_ZAP_METADATA,
+	    dn, stack)) != 0)
+		return (errnum);
+
+	return (zap_iterate(dn, check_feature, spa_feature_names, stack));
+}
+
+/*
  * 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.
@@ -896,15 +1036,15 @@ get_objset_mdn(dnode_phys_t *mosmdn, cha
 		goto skip;
 	}
 
-	if ((errnum = dnode_get(mosmdn, DMU_POOL_DIRECTORY_OBJECT,
-	    DMU_OT_OBJECT_DIRECTORY, mdn, stack)))
+	if (errnum = dnode_get(mosmdn, DMU_POOL_DIRECTORY_OBJECT,
+	    DMU_OT_OBJECT_DIRECTORY, mdn, stack))
 		return (errnum);
 
-	if ((errnum = zap_lookup(mdn, DMU_POOL_ROOT_DATASET, &objnum,
-	    stack)))
+	if (errnum = zap_lookup(mdn, DMU_POOL_ROOT_DATASET, &objnum,
+	    stack))
 		return (errnum);
 
-	if ((errnum = dnode_get(mosmdn, objnum, DMU_OT_DSL_DIR, mdn, stack)))
+	if (errnum = dnode_get(mosmdn, objnum, DMU_OT_DSL_DIR, mdn, stack))
 		return (errnum);
 
 	if (fsname == NULL) {
@@ -914,23 +1054,24 @@ get_objset_mdn(dnode_phys_t *mosmdn, cha
 	}
 
 	/* take out the pool name */
-	while (*fsname && !isspace((uint8_t)*fsname) && *fsname != '/')
+	while (*fsname && !grub_isspace(*fsname) && *fsname != '/')
 		fsname++;
 
-	while (*fsname && !isspace((uint8_t)*fsname)) {
+	while (*fsname && !grub_isspace(*fsname)) {
 		uint64_t childobj;
 
 		while (*fsname == '/')
 			fsname++;
 
 		cname = fsname;
-		while (*fsname && !isspace((uint8_t)*fsname) && *fsname != '/')
+		while (*fsname && !grub_isspace(*fsname) && *fsname != '/')
 			fsname++;
 		ch = *fsname;
 		*fsname = 0;
 
 		snapname = cname;
-		while (*snapname && !isspace((uint8_t)*snapname) && *snapname != '@')
+		while (*snapname && !grub_isspace(*snapname) && *snapname !=
+		    '@')
 			snapname++;
 		if (*snapname == '@') {
 			issnapshot = 1;
@@ -938,15 +1079,15 @@ get_objset_mdn(dnode_phys_t *mosmdn, cha
 		}
 		childobj =
 		    ((dsl_dir_phys_t *)DN_BONUS(mdn))->dd_child_dir_zapobj;
-		if ((errnum = dnode_get(mosmdn, childobj,
-		    DMU_OT_DSL_DIR_CHILD_MAP, mdn, stack)))
+		if (errnum = dnode_get(mosmdn, childobj,
+		    DMU_OT_DSL_DIR_CHILD_MAP, mdn, stack))
 			return (errnum);
 
 		if (zap_lookup(mdn, cname, &objnum, stack))
 			return (ERR_FILESYSTEM_NOT_FOUND);
 
-		if ((errnum = dnode_get(mosmdn, objnum, DMU_OT_DSL_DIR,
-		    mdn, stack)))
+		if (errnum = dnode_get(mosmdn, objnum, DMU_OT_DSL_DIR,
+		    mdn, stack))
 			return (errnum);
 
 		*fsname = ch;
@@ -958,7 +1099,7 @@ get_objset_mdn(dnode_phys_t *mosmdn, cha
 		*obj = headobj;
 
 skip:
-	if ((errnum = dnode_get(mosmdn, headobj, DMU_OT_DSL_DATASET, mdn, stack)))
+	if (errnum = dnode_get(mosmdn, headobj, DMU_OT_DSL_DATASET, mdn, stack))
 		return (errnum);
 	if (issnapshot) {
 		uint64_t snapobj;
@@ -966,13 +1107,13 @@ skip:
 		snapobj = ((dsl_dataset_phys_t *)DN_BONUS(mdn))->
 		    ds_snapnames_zapobj;
 
-		if ((errnum = dnode_get(mosmdn, snapobj,
-		    DMU_OT_DSL_DS_SNAP_MAP, mdn, stack)))
+		if (errnum = dnode_get(mosmdn, snapobj,
+		    DMU_OT_DSL_DS_SNAP_MAP, mdn, stack))
 			return (errnum);
 		if (zap_lookup(mdn, snapname + 1, &headobj, stack))
 			return (ERR_FILESYSTEM_NOT_FOUND);
-		if ((errnum = dnode_get(mosmdn, headobj,
-		    DMU_OT_DSL_DATASET, mdn, stack)))
+		if (errnum = dnode_get(mosmdn, headobj,
+		    DMU_OT_DSL_DATASET, mdn, stack))
 			return (errnum);
 		if (obj)
 			*obj = headobj;
@@ -981,7 +1122,7 @@ skip:
 	bp = &((dsl_dataset_phys_t *)DN_BONUS(mdn))->ds_bp;
 	osp = (objset_phys_t *)stack;
 	stack += sizeof (objset_phys_t);
-	if ((errnum = zio_read(bp, osp, stack)))
+	if (errnum = zio_read(bp, osp, stack))
 		return (errnum);
 
 	grub_memmove((char *)mdn, (char *)&osp->os_meta_dnode, DNODE_SIZE);
@@ -1019,8 +1160,7 @@ nvlist_unpack(char *nvlist, char **out)
 	if (nvlist[0] != NV_ENCODE_XDR || nvlist[1] != HOST_ENDIAN)
 		return (1);
 
-	nvlist += 4;
-	*out = nvlist;
+	*out = nvlist + 4;
 	return (0);
 }
 
@@ -1033,7 +1173,7 @@ nvlist_array(char *nvlist, int index)
 		/* skip the header, nvl_version, and nvl_nvflag */
 		nvlist = nvlist + 4 * 2;
 
-		while ((encode_size = BSWAP_32(*(uint32_t *)nvlist)))
+		while (encode_size = BSWAP_32(*(uint32_t *)nvlist))
 			nvlist += encode_size; /* goto the next nvpair */
 
 		nvlist = nvlist + 4 * 2; /* skip the ending 2 zeros - 8 bytes */
@@ -1042,69 +1182,159 @@ nvlist_array(char *nvlist, int index)
 	return (nvlist);
 }
 
+/*
+ * 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 char *
+nvlist_next_nvpair(char *nvl, char *nvpair)
+{
+	char *cur, *prev;
+	int encode_size;
+
+	if (nvl == NULL)
+		return (NULL);
+
+	if (nvpair == NULL) {
+		/* skip over nvl_version and nvl_nvflag */
+		nvpair = nvl + 4 * 2;
+	} else {
+		/* skip to the next nvpair */
+		encode_size = BSWAP_32(*(uint32_t *)nvpair);
+		nvpair += encode_size;
+	}
+
+	/* 8 bytes of 0 marks the end of the list */
+	if (*(uint64_t *)nvpair == 0)
+		return (NULL);
+
+	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(char *nvp, char *buf, int buflen)
+{
+	int len;
+
+	/* skip over encode/decode size */
+	nvp += 4 * 2;
+
+	len = BSWAP_32(*(uint32_t *)nvp);
+	if (buflen < len + 1)
+		return (1);
+
+	grub_memmove(buf, nvp + 4, len);
+	buf[len] = '\0';
+
+	return (0);
+}
+
+/*
+ * This function retrieves the value of the nvpair in the form of enumerated
+ * type data_type_t. This is used to determine the appropriate type to pass to
+ * nvpair_value().
+ */
+static int
+nvpair_type(char *nvp)
+{
+	int name_len, type;
+
+	/* skip over encode/decode size */
+	nvp += 4 * 2;
+
+	/* skip over name_len */
+	name_len = BSWAP_32(*(uint32_t *)nvp);
+	nvp += 4;
+
+	/* skip over name */
+	nvp = nvp + ((name_len + 3) & ~3); /* align */
+
+	type = BSWAP_32(*(uint32_t *)nvp);
+
+	return (type);
+}
+
+static int
+nvpair_value(char *nvp, void *val, int valtype, int *nelmp)
+{
+	int name_len, type, slen;
+	char *strval = val;
+	uint64_t *intval = val;
+
+	/* skip over encode/decode size */
+	nvp += 4 * 2;
+
+	/* skip over name_len */
+	name_len = BSWAP_32(*(uint32_t *)nvp);
+	nvp += 4;
+
+	/* skip over name */
+	nvp = nvp + ((name_len + 3) & ~3); /* align */
+
+	/* skip over type */
+	type = BSWAP_32(*(uint32_t *)nvp);
+	nvp += 4;
+
+	if (type == valtype) {
+		int nelm;
+
+		nelm = BSWAP_32(*(uint32_t *)nvp);
+		if (valtype != DATA_TYPE_BOOLEAN && nelm < 1)
+			return (1);
+		nvp += 4;
+
+		switch (valtype) {
+		case DATA_TYPE_BOOLEAN:
+			return (0);
+
+		case DATA_TYPE_STRING:
+			slen = BSWAP_32(*(uint32_t *)nvp);
+			nvp += 4;
+			grub_memmove(strval, nvp, slen);
+			strval[slen] = '\0';
+			return (0);
+
+		case DATA_TYPE_UINT64:
+			*intval = BSWAP_64(*(uint64_t *)nvp);
+			return (0);
+
+		case DATA_TYPE_NVLIST:
+			*(void **)val = (void *)nvp;
+			return (0);
+
+		case DATA_TYPE_NVLIST_ARRAY:
+			*(void **)val = (void *)nvp;
+			if (nelmp)
+				*nelmp = nelm;
+			return (0);
+		}
+	}
+
+	return (1);
+}
+
 static int
 nvlist_lookup_value(char *nvlist, char *name, void *val, int valtype,
     int *nelmp)
 {
-	int name_len, type, slen, encode_size;
-	char *nvpair, *nvp_name, *strval = val;
-	uint64_t *intval = val;
+	char *nvpair;
 
-	/* skip the header, nvl_version, and nvl_nvflag */
-	nvlist = nvlist + 4 * 2;
-
-	/*
-	 * Loop thru the nvpair list
-	 * The XDR representation of an integer is in big-endian byte order.
-	 */
-	while ((encode_size = BSWAP_32(*(uint32_t *)nvlist)))  {
-
-		nvpair = nvlist + 4 * 2; /* skip the encode/decode size */
-
-		name_len = BSWAP_32(*(uint32_t *)nvpair);
-		nvpair += 4;
-
-		nvp_name = nvpair;
-		nvpair = nvpair + ((name_len + 3) & ~3); /* align */
-
-		type = BSWAP_32(*(uint32_t *)nvpair);
-		nvpair += 4;
+	for (nvpair = nvlist_next_nvpair(nvlist, NULL);
+	    nvpair != NULL;
+	    nvpair = nvlist_next_nvpair(nvlist, nvpair)) {
+		int name_len = BSWAP_32(*(uint32_t *)(nvpair + 4 * 2));
+		char *nvp_name = nvpair + 4 * 3;
 
 		if ((grub_strncmp(nvp_name, name, name_len) == 0) &&
-		    type == valtype) {
-			int nelm;
-
-			if ((nelm = BSWAP_32(*(uint32_t *)nvpair)) < 1)
-				return (1);
-			nvpair += 4;
-
-			switch (valtype) {
-			case DATA_TYPE_STRING:
-				slen = BSWAP_32(*(uint32_t *)nvpair);
-				nvpair += 4;
-				grub_memmove(strval, nvpair, slen);
-				strval[slen] = '\0';
-				return (0);
-
-			case DATA_TYPE_UINT64:
-				*intval = BSWAP_64(*(uint64_t *)nvpair);
-				return (0);
-
-			case DATA_TYPE_NVLIST:
-				*(void **)val = (void *)nvpair;
-				return (0);
-
-			case DATA_TYPE_NVLIST_ARRAY:
-				*(void **)val = (void *)nvpair;
-				if (nelmp)
-					*nelmp = nelm;
-				return (0);
-			}
+		    nvpair_type(nvpair) == valtype) {
+			return (nvpair_value(nvpair, val, valtype, nelmp));
 		}
-
-		nvlist += encode_size; /* goto the next nvpair */
 	}
-
 	return (1);
 }
 
@@ -1141,7 +1371,7 @@ vdev_get_bootpath(char *nv, uint64_t ing
 	    NULL))
 		return (ERR_FSYS_CORRUPT);
 
-	if (strcmp(type, VDEV_TYPE_DISK) == 0) {
+	if (grub_strcmp(type, VDEV_TYPE_DISK) == 0) {
 		uint64_t guid;
 
 		if (vdev_validate(nv) != 0)
@@ -1171,15 +1401,15 @@ vdev_get_bootpath(char *nv, uint64_t ing
 		    devid, DATA_TYPE_STRING, NULL) != 0)
 			devid[0] = '\0';
 
-		if (strlen(bootpath) >= MAXPATHLEN ||
-		    strlen(devid) >= MAXPATHLEN)
+		if (grub_strlen(bootpath) >= MAXPATHLEN ||
+		    grub_strlen(devid) >= MAXPATHLEN)
 			return (ERR_WONT_FIT);
 
 		return (0);
 
-	} else if (strcmp(type, VDEV_TYPE_MIRROR) == 0 ||
-	    strcmp(type, VDEV_TYPE_REPLACING) == 0 ||
-	    (is_spare = (strcmp(type, VDEV_TYPE_SPARE) == 0))) {
+	} else if (grub_strcmp(type, VDEV_TYPE_MIRROR) == 0 ||
+	    grub_strcmp(type, VDEV_TYPE_REPLACING) == 0 ||
+	    (is_spare = (grub_strcmp(type, VDEV_TYPE_SPARE) == 0))) {
 		int nelm, i;
 		char *child;
 
@@ -1207,15 +1437,14 @@ vdev_get_bootpath(char *nv, uint64_t ing
  *	0 - success
  *	ERR_* - failure
  */
-int
+static int
 check_pool_label(uint64_t sector, char *stack, char *outdevid,
-    char *outpath, uint64_t *outguid)
+    char *outpath, uint64_t *outguid, uint64_t *outashift, uint64_t *outversion)
 {
 	vdev_phys_t *vdev;
 	uint64_t pool_state, txg = 0;
-	char *nvlist, *nv;
+	char *nvlist, *nv, *features;
 	uint64_t diskguid;
-	uint64_t version;
 
 	sector += (VDEV_SKIP_SIZE >> SPA_MINBLOCKSHIFT);
 
@@ -1248,10 +1477,10 @@ check_pool_label(uint64_t sector, char *
 	if (txg == 0)
 		return (ERR_NO_BOOTPATH);
 
-	if (nvlist_lookup_value(nvlist, ZPOOL_CONFIG_VERSION, &version,
+	if (nvlist_lookup_value(nvlist, ZPOOL_CONFIG_VERSION, outversion,
 	    DATA_TYPE_UINT64, NULL))
 		return (ERR_FSYS_CORRUPT);
-	if (version > SPA_VERSION)
+	if (!SPA_VERSION_IS_SUPPORTED(*outversion))
 		return (ERR_NEWER_VERSION);
 	if (nvlist_lookup_value(nvlist, ZPOOL_CONFIG_VDEV_TREE, &nv,
 	    DATA_TYPE_NVLIST, NULL))
@@ -1259,11 +1488,38 @@ check_pool_label(uint64_t sector, char *
 	if (nvlist_lookup_value(nvlist, ZPOOL_CONFIG_GUID, &diskguid,
 	    DATA_TYPE_UINT64, NULL))
 		return (ERR_FSYS_CORRUPT);
+	if (nvlist_lookup_value(nv, ZPOOL_CONFIG_ASHIFT, outashift,
+	    DATA_TYPE_UINT64, NULL) != 0)
+		return (ERR_FSYS_CORRUPT);
 	if (vdev_get_bootpath(nv, diskguid, outdevid, outpath, 0))
 		return (ERR_NO_BOOTPATH);
 	if (nvlist_lookup_value(nvlist, ZPOOL_CONFIG_POOL_GUID, outguid,
 	    DATA_TYPE_UINT64, NULL))
 		return (ERR_FSYS_CORRUPT);
+
+	if (nvlist_lookup_value(nvlist, ZPOOL_CONFIG_FEATURES_FOR_READ,
+	    &features, DATA_TYPE_NVLIST, NULL) == 0) {
+		char *nvp;
+		char *name = stack;
+		stack += MAXNAMELEN;
+
+		for (nvp = nvlist_next_nvpair(features, NULL);
+		    nvp != NULL;
+		    nvp = nvlist_next_nvpair(features, nvp)) {
+			zap_attribute_t za;
+
+			if (nvpair_name(nvp, name, MAXNAMELEN) != 0)
+				return (ERR_FSYS_CORRUPT);
+
+			za.za_integer_length = 8;
+			za.za_num_integers = 1;
+			za.za_first_integer = 1;
+			za.za_name = name;
+			if (check_feature(&za, spa_feature_names, stack) != 0)
+				return (ERR_NEWER_VERSION);
+		}
+	}
+
 	return (0);
 }
 
@@ -1278,15 +1534,16 @@ check_pool_label(uint64_t sector, char *
 int
 zfs_mount(void)
 {
-	char *stack;
+	char *stack, *ub_array;
 	int label = 0;
-	uberblock_phys_t *ub_array, *ubbest;
+	uberblock_t *ubbest;
 	objset_phys_t *osp;
 	char tmp_bootpath[MAXNAMELEN];
 	char tmp_devid[MAXNAMELEN];
-	uint64_t tmp_guid;
+	uint64_t tmp_guid, ashift, version;
 	uint64_t adjpl = (uint64_t)part_length << SPA_MINBLOCKSHIFT;
 	int err = errnum; /* preserve previous errnum state */
+	uint64_t sector;
 
 	/* if it's our first time here, zero the best uberblock out */
 	if (best_drive == 0 && best_part == 0 && find_best_root) {
@@ -1296,7 +1553,7 @@ zfs_mount(void)
 
 	stackbase = ZFS_SCRATCH;
 	stack = stackbase;
-	ub_array = (uberblock_phys_t *)stack;
+	ub_array = stack;
 	stack += VDEV_UBERBLOCK_RING;
 
 	osp = (objset_phys_t *)stack;
@@ -1305,8 +1562,6 @@ zfs_mount(void)
 
 	for (label = 0; label < VDEV_LABELS; label++) {
 
-		uint64_t sector;
-
 		/*
 		 * some eltorito stacks don't give us a size and
 		 * we end up setting the size to MAXUINT, further
@@ -1324,39 +1579,38 @@ zfs_mount(void)
 
 		/* Read in the uberblock ring (128K). */
 		if (devread(sector  +
-		    ((VDEV_SKIP_SIZE + VDEV_PHYS_SIZE) >>
-		    SPA_MINBLOCKSHIFT), 0, VDEV_UBERBLOCK_RING,
-		    (char *)ub_array) == 0)
+		    ((VDEV_SKIP_SIZE + VDEV_PHYS_SIZE) >> SPA_MINBLOCKSHIFT),
+		    0, VDEV_UBERBLOCK_RING, ub_array) == 0)
 			continue;
 
-		if ((ubbest = find_bestub(ub_array, sector)) != NULL &&
-		    zio_read(&ubbest->ubp_uberblock.ub_rootbp, osp, stack)
-		    == 0) {
+		if (check_pool_label(sector, stack, tmp_devid,
+		    tmp_bootpath, &tmp_guid, &ashift, &version))
+			continue;
 
-			VERIFY_OS_TYPE(osp, DMU_OST_META);
+		if (pool_guid == 0)
+			pool_guid = tmp_guid;
 
-			if (check_pool_label(sector, stack, tmp_devid,
-			    tmp_bootpath, &tmp_guid))
-				continue;
-			if (pool_guid == 0)
-				pool_guid = tmp_guid;
+		if ((ubbest = find_bestub(ub_array, ashift, sector)) == NULL ||
+		    zio_read(&ubbest->ub_rootbp, osp, stack) != 0)
+			continue;
 
-			if (find_best_root && ((pool_guid != tmp_guid) ||
-			    vdev_uberblock_compare(&ubbest->ubp_uberblock,
-			    &(current_uberblock)) <= 0))
-				continue;
+		VERIFY_OS_TYPE(osp, DMU_OST_META);
 
-			/* Got the MOS. Save it at the memory addr MOS. */
-			grub_memmove(MOS, &osp->os_meta_dnode, DNODE_SIZE);
-			grub_memmove(&current_uberblock,
-			    &ubbest->ubp_uberblock, sizeof (uberblock_t));
-			grub_memmove(current_bootpath, tmp_bootpath,
-			    MAXNAMELEN);
-			grub_memmove(current_devid, tmp_devid,
-			    grub_strlen(tmp_devid));
-			is_zfs_mount = 1;
-			return (1);
-		}
+		if (version >= SPA_VERSION_FEATURES &&
+		    check_mos_features(&osp->os_meta_dnode, stack) != 0)
+			continue;
+
+		if (find_best_root && ((pool_guid != tmp_guid) ||
+		    vdev_uberblock_compare(ubbest, &(current_uberblock)) <= 0))
+			continue;
+
+		/* Got the MOS. Save it at the memory addr MOS. */
+		grub_memmove(MOS, &osp->os_meta_dnode, DNODE_SIZE);
+		grub_memmove(&current_uberblock, ubbest, sizeof (uberblock_t));
+		grub_memmove(current_bootpath, tmp_bootpath, MAXNAMELEN);
+		grub_memmove(current_devid, tmp_devid, grub_strlen(tmp_devid));
+		is_zfs_mount = 1;
+		return (1);
 	}
 
 	/*
@@ -1399,23 +1653,23 @@ zfs_open(char *filename)
 	 * do not goto 'current_bootfs'.
 	 */
 	if (is_top_dataset_file(filename)) {
-		if ((errnum = get_objset_mdn(MOS, NULL, NULL, mdn, stack)))
+		if (errnum = get_objset_mdn(MOS, NULL, NULL, mdn, stack))
 			return (0);
 
 		current_bootfs_obj = 0;
 	} else {
 		if (current_bootfs[0] == '\0') {
 			/* Get the default root filesystem object number */
-			if ((errnum = get_default_bootfsobj(MOS,
-			    &current_bootfs_obj, stack)))
+			if (errnum = get_default_bootfsobj(MOS,
+			    &current_bootfs_obj, stack))
 				return (0);
 
-			if ((errnum = get_objset_mdn(MOS, NULL,
-			    &current_bootfs_obj, mdn, stack)))
+			if (errnum = get_objset_mdn(MOS, NULL,
+			    &current_bootfs_obj, mdn, stack))
 				return (0);
 		} else {
-			if ((errnum = get_objset_mdn(MOS, current_bootfs,
-			    &current_bootfs_obj, mdn, stack))) {
+			if (errnum = get_objset_mdn(MOS, current_bootfs,
+			    &current_bootfs_obj, mdn, stack)) {
 				grub_memset(current_bootfs, 0, MAXNAMELEN);
 				return (0);
 			}
@@ -1515,7 +1769,7 @@ zfs_read(char *buf, int len)
 		 */
 		uint64_t blkid = filepos / blksz;
 
-		if ((errnum = dmu_read(DNODE, blkid, file_buf, stack)))
+		if (errnum = dmu_read(DNODE, blkid, file_buf, stack))
 			return (0);
 
 		file_start = blkid * blksz;
diff -r 7c12aaa128e3 -r 7afe0b19c898 tools/libfsimage/zfs/fsys_zfs.h
--- a/tools/libfsimage/zfs/fsys_zfs.h	Thu Oct 24 22:46:20 2013 +0100
+++ b/tools/libfsimage/zfs/fsys_zfs.h	Thu Oct 31 22:48:42 2013 +0400
@@ -16,10 +16,17 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
+
 /*
  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
+
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
+ */
+
 #ifndef _FSYS_ZFS_H
 #define	_FSYS_ZFS_H
 
@@ -95,26 +102,8 @@ typedef	unsigned int size_t;
 #define	BSWAP_64(x)	((BSWAP_32(x) << 32) | BSWAP_32((x) >> 32))
 #define	P2ROUNDUP(x, align)	(-(-(x) & -(align)))
 
-/*
- * XXX Match these macro up with real zfs once we have nvlist support so that we
- * can support large sector disks.
- */
-#define	UBERBLOCK_SIZE		(1ULL << UBERBLOCK_SHIFT)
-#define	VDEV_UBERBLOCK_SHIFT	UBERBLOCK_SHIFT
-#include <stddef.h>
-#define	VDEV_UBERBLOCK_OFFSET(n) \
-offsetof(vdev_label_t, vl_uberblock[(n) << VDEV_UBERBLOCK_SHIFT])
-
 typedef struct uberblock uberblock_t;
 
-/* XXX Uberblock_phys_t is no longer in the kernel zfs */
-typedef struct uberblock_phys {
-	uberblock_t	ubp_uberblock;
-	char		ubp_pad[UBERBLOCK_SIZE - sizeof (uberblock_t) -
-				sizeof (zio_eck_t)];
-	zio_eck_t	ubp_zec;
-} uberblock_phys_t;
-
 /*
  * Macros to get fields in a bp or DVA.
  */
@@ -137,10 +126,36 @@ typedef struct uberblock_phys {
 #define	NV_ENCODE_NATIVE	0
 #define	NV_ENCODE_XDR		1
 #define	HOST_ENDIAN		1	/* for x86 machine */
-#define	DATA_TYPE_UINT64	8
-#define	DATA_TYPE_STRING	9
-#define	DATA_TYPE_NVLIST	19
-#define	DATA_TYPE_NVLIST_ARRAY	20
+typedef enum {
+	DATA_TYPE_UNKNOWN = 0,
+	DATA_TYPE_BOOLEAN,
+	DATA_TYPE_BYTE,
+	DATA_TYPE_INT16,
+	DATA_TYPE_UINT16,
+	DATA_TYPE_INT32,
+	DATA_TYPE_UINT32,
+	DATA_TYPE_INT64,
+	DATA_TYPE_UINT64,
+	DATA_TYPE_STRING,
+	DATA_TYPE_BYTE_ARRAY,
+	DATA_TYPE_INT16_ARRAY,
+	DATA_TYPE_UINT16_ARRAY,
+	DATA_TYPE_INT32_ARRAY,
+	DATA_TYPE_UINT32_ARRAY,
+	DATA_TYPE_INT64_ARRAY,
+	DATA_TYPE_UINT64_ARRAY,
+	DATA_TYPE_STRING_ARRAY,
+	DATA_TYPE_HRTIME,
+	DATA_TYPE_NVLIST,
+	DATA_TYPE_NVLIST_ARRAY,
+	DATA_TYPE_BOOLEAN_VALUE,
+	DATA_TYPE_INT8,
+	DATA_TYPE_UINT8,
+	DATA_TYPE_BOOLEAN_ARRAY,
+	DATA_TYPE_INT8_ARRAY,
+	DATA_TYPE_UINT8_ARRAY,
+	DATA_TYPE_DOUBLE
+} data_type_t;
 
 /*
  * Decompression Entry - lzjb
@@ -199,6 +214,7 @@ extern void fletcher_4_native(const void
 extern void fletcher_4_byteswap(const void *, uint64_t, zio_cksum_t *);
 extern void zio_checksum_SHA256(const void *, uint64_t, zio_cksum_t *);
 extern int lzjb_decompress(void *, void *, size_t, size_t);
+extern int lz4_decompress(void *, void *, size_t, size_t);
 
 #endif	/* FSYS_ZFS */
 
diff -r 7c12aaa128e3 -r 7afe0b19c898 tools/libfsimage/zfs/zfs-include/dmu.h
--- a/tools/libfsimage/zfs/zfs-include/dmu.h	Thu Oct 24 22:46:20 2013 +0100
+++ b/tools/libfsimage/zfs/zfs-include/dmu.h	Thu Oct 31 22:48:42 2013 +0400
@@ -16,11 +16,16 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
+
 /*
  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
 #ifndef	_SYS_DMU_H
 #define	_SYS_DMU_H
 
@@ -31,6 +36,41 @@
  * The DMU also interacts with the SPA.  That interface is described in
  * dmu_spa.h.
  */
+
+#define	B_FALSE	0
+#define	B_TRUE	1
+
+#define	DMU_OT_NEWTYPE 0x80
+#define	DMU_OT_METADATA 0x40
+#define	DMU_OT_BYTESWAP_MASK 0x3f
+
+#define	DMU_OT(byteswap, metadata) \
+	(DMU_OT_NEWTYPE | \
+	((metadata) ? DMU_OT_METADATA : 0) | \
+	((byteswap) & DMU_OT_BYTESWAP_MASK))
+
+#define	DMU_OT_IS_VALID(ot) (((ot) & DMU_OT_NEWTYPE) ? \
+	((ot) & DMU_OT_BYTESWAP_MASK) < DMU_BSWAP_NUMFUNCS : \
+	(ot) < DMU_OT_NUMTYPES)
+
+#define	DMU_OT_IS_METADATA(ot) (((ot) & DMU_OT_NEWTYPE) ? \
+	((ot) & DMU_OT_METADATA) : \
+	dmu_ot[(ot)].ot_metadata)
+
+typedef enum dmu_object_byteswap {
+	DMU_BSWAP_UINT8,
+	DMU_BSWAP_UINT16,
+	DMU_BSWAP_UINT32,
+	DMU_BSWAP_UINT64,
+	DMU_BSWAP_ZAP,
+	DMU_BSWAP_DNODE,
+	DMU_BSWAP_OBJSET,
+	DMU_BSWAP_ZNODE,
+	DMU_BSWAP_OLDACL,
+	DMU_BSWAP_ACL,
+	DMU_BSWAP_NUMFUNCS
+} dmu_object_byteswap_t;
+
 typedef enum dmu_object_type {
 	DMU_OT_NONE,
 	/* general: */
@@ -38,8 +78,8 @@ typedef enum dmu_object_type {
 	DMU_OT_OBJECT_ARRAY,		/* UINT64 */
 	DMU_OT_PACKED_NVLIST,		/* UINT8 (XDR by nvlist_pack/unpack) */
 	DMU_OT_PACKED_NVLIST_SIZE,	/* UINT64 */
-	DMU_OT_BPLIST,			/* UINT64 */
-	DMU_OT_BPLIST_HDR,		/* UINT64 */
+	DMU_OT_BPOBJ,			/* UINT64 */
+	DMU_OT_BPOBJ_HDR,		/* UINT64 */
 	/* spa: */
 	DMU_OT_SPACE_MAP_HEADER,	/* UINT64 */
 	DMU_OT_SPACE_MAP,		/* UINT64 */
@@ -56,7 +96,7 @@ typedef enum dmu_object_type {
 	DMU_OT_DSL_DATASET,		/* UINT64 */
 	/* zpl: */
 	DMU_OT_ZNODE,			/* ZNODE */
-	DMU_OT_OLDACL,			/* OLD ACL */
+	DMU_OT_OLDACL,			/* Old ACL */
 	DMU_OT_PLAIN_FILE_CONTENTS,	/* UINT8 */
 	DMU_OT_DIRECTORY_CONTENTS,	/* ZAP */
 	DMU_OT_MASTER_NODE,		/* ZAP */
@@ -79,7 +119,7 @@ typedef enum dmu_object_type {
 	DMU_OT_FUID,			/* FUID table (Packed NVLIST UINT8) */
 	DMU_OT_FUID_SIZE,		/* FUID table size UINT64 */
 	DMU_OT_NEXT_CLONES,		/* ZAP */
-	DMU_OT_SCRUB_QUEUE,		/* ZAP */
+	DMU_OT_SCAN_QUEUE,		/* ZAP */
 	DMU_OT_USERGROUP_USED,		/* ZAP */
 	DMU_OT_USERGROUP_QUOTA,		/* ZAP */
 	DMU_OT_USERREFS,		/* ZAP */
@@ -89,7 +129,24 @@ typedef enum dmu_object_type {
 	DMU_OT_SA_MASTER_NODE,		/* ZAP */
 	DMU_OT_SA_ATTR_REGISTRATION,	/* ZAP */
 	DMU_OT_SA_ATTR_LAYOUTS,		/* ZAP */
-	DMU_OT_NUMTYPES
+	DMU_OT_SCAN_XLATE,		/* ZAP */
+	DMU_OT_DEDUP,			/* fake dedup BP from ddt_bp_create() */
+	DMU_OT_DEADLIST,		/* ZAP */
+	DMU_OT_DEADLIST_HDR,		/* UINT64 */
+	DMU_OT_DSL_CLONES,		/* ZAP */
+	DMU_OT_BPOBJ_SUBOBJ,		/* UINT64 */
+	DMU_OT_NUMTYPES,
+
+	DMU_OTN_UINT8_DATA = DMU_OT(DMU_BSWAP_UINT8, B_FALSE),
+	DMU_OTN_UINT8_METADATA = DMU_OT(DMU_BSWAP_UINT8, B_TRUE),
+	DMU_OTN_UINT16_DATA = DMU_OT(DMU_BSWAP_UINT16, B_FALSE),
+	DMU_OTN_UINT16_METADATA = DMU_OT(DMU_BSWAP_UINT16, B_TRUE),
+	DMU_OTN_UINT32_DATA = DMU_OT(DMU_BSWAP_UINT32, B_FALSE),
+	DMU_OTN_UINT32_METADATA = DMU_OT(DMU_BSWAP_UINT32, B_TRUE),
+	DMU_OTN_UINT64_DATA = DMU_OT(DMU_BSWAP_UINT64, B_FALSE),
+	DMU_OTN_UINT64_METADATA = DMU_OT(DMU_BSWAP_UINT64, B_TRUE),
+	DMU_OTN_ZAP_DATA = DMU_OT(DMU_BSWAP_ZAP, B_FALSE),
+	DMU_OTN_ZAP_METADATA = DMU_OT(DMU_BSWAP_ZAP, B_TRUE),
 } dmu_object_type_t;
 
 typedef enum dmu_objset_type {
@@ -107,6 +164,9 @@ typedef enum dmu_objset_type {
  */
 #define	DMU_POOL_DIRECTORY_OBJECT	1
 #define	DMU_POOL_CONFIG			"config"
+#define	DMU_POOL_FEATURES_FOR_READ	"features_for_read"
+#define	DMU_POOL_FEATURES_FOR_WRITE	"features_for_write"
+#define	DMU_POOL_FEATURE_DESCRIPTIONS	"feature_descriptions"
 #define	DMU_POOL_ROOT_DATASET		"root_dataset"
 #define	DMU_POOL_SYNC_BPLIST		"sync_bplist"
 #define	DMU_POOL_ERRLOG_SCRUB		"errlog_scrub"
diff -r 7c12aaa128e3 -r 7afe0b19c898 tools/libfsimage/zfs/zfs-include/dsl_dataset.h
--- a/tools/libfsimage/zfs/zfs-include/dsl_dataset.h	Thu Oct 24 22:46:20 2013 +0100
+++ b/tools/libfsimage/zfs/zfs-include/dsl_dataset.h	Thu Oct 31 22:48:42 2013 +0400
@@ -24,8 +24,6 @@
 #ifndef	_SYS_DSL_DATASET_H
 #define	_SYS_DSL_DATASET_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 typedef struct dsl_dataset_phys {
 	uint64_t ds_dir_obj;
 	uint64_t ds_prev_snap_obj;
diff -r 7c12aaa128e3 -r 7afe0b19c898 tools/libfsimage/zfs/zfs-include/dsl_dir.h
--- a/tools/libfsimage/zfs/zfs-include/dsl_dir.h	Thu Oct 24 22:46:20 2013 +0100
+++ b/tools/libfsimage/zfs/zfs-include/dsl_dir.h	Thu Oct 31 22:48:42 2013 +0400
@@ -24,8 +24,6 @@
 #ifndef	_SYS_DSL_DIR_H
 #define	_SYS_DSL_DIR_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 typedef struct dsl_dir_phys {
 	uint64_t dd_creation_time; /* not actually used */
 	uint64_t dd_head_dataset_obj;
diff -r 7c12aaa128e3 -r 7afe0b19c898 tools/libfsimage/zfs/zfs-include/spa.h
--- a/tools/libfsimage/zfs/zfs-include/spa.h	Thu Oct 24 22:46:20 2013 +0100
+++ b/tools/libfsimage/zfs/zfs-include/spa.h	Thu Oct 31 22:48:42 2013 +0400
@@ -16,11 +16,16 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
+
 /*
  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
 #ifndef _SYS_SPA_H
 #define	_SYS_SPA_H
 
@@ -65,7 +70,7 @@
 /*
  * Size of block to hold the configuration data (a packed nvlist)
  */
-#define	SPA_CONFIG_BLOCKSIZE	(1 << 14)
+#define	SPA_CONFIG_BLOCKSIZE	(1ULL << 14)
 
 /*
  * The DVA size encodings for LSIZE and PSIZE support blocks up to 32MB.
diff -r 7c12aaa128e3 -r 7afe0b19c898 tools/libfsimage/zfs/zfs-include/uberblock_impl.h
--- a/tools/libfsimage/zfs/zfs-include/uberblock_impl.h	Thu Oct 24 22:46:20 2013 +0100
+++ b/tools/libfsimage/zfs/zfs-include/uberblock_impl.h	Thu Oct 31 22:48:42 2013 +0400
@@ -24,8 +24,6 @@
 #ifndef _SYS_UBERBLOCK_IMPL_H
 #define	_SYS_UBERBLOCK_IMPL_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /*
  * The uberblock version is incremented whenever an incompatible on-disk
  * format change is made to the SPA, DMU, or ZAP.
diff -r 7c12aaa128e3 -r 7afe0b19c898 tools/libfsimage/zfs/zfs-include/vdev_impl.h
--- a/tools/libfsimage/zfs/zfs-include/vdev_impl.h	Thu Oct 24 22:46:20 2013 +0100
+++ b/tools/libfsimage/zfs/zfs-include/vdev_impl.h	Thu Oct 31 22:48:42 2013 +0400
@@ -24,12 +24,30 @@
 #ifndef _SYS_VDEV_IMPL_H
 #define	_SYS_VDEV_IMPL_H
 
+/* helper macros */
+#undef	offsetof
+#if defined(__GNUC__)
+#define	offsetof(s, m)	__builtin_offsetof(s, m)
+#else
+#define	offsetof(s, m)	((size_t)(&(((s *)0)->m)))
+#endif
+#define	MAX(x, y)		((x) > (y) ? (x) : (y))
+
 #define	VDEV_PAD_SIZE 		(8 << 10)
 /* 2 padding areas (vl_pad1 and vl_pad2) to skip */
 #define	VDEV_SKIP_SIZE		VDEV_PAD_SIZE * 2
 #define	VDEV_PHYS_SIZE		(112 << 10)
 #define	VDEV_UBERBLOCK_RING	(128 << 10)
 
+#define	VDEV_UBERBLOCK_SHIFT(sh)		\
+	MAX((sh), UBERBLOCK_SHIFT)
+#define	VDEV_UBERBLOCK_COUNT(sh)		\
+	(VDEV_UBERBLOCK_RING >> VDEV_UBERBLOCK_SHIFT(sh))
+#define	VDEV_UBERBLOCK_OFFSET(sh, n)	\
+	offsetof(vdev_label_t, vl_uberblock[(n) << VDEV_UBERBLOCK_SHIFT(sh)])
+#define	VDEV_UBERBLOCK_SIZE(sh)			\
+	(1ULL << VDEV_UBERBLOCK_SHIFT(sh))
+
 typedef struct vdev_phys {
 	char		vp_nvlist[VDEV_PHYS_SIZE - sizeof (zio_eck_t)];
 	zio_eck_t	vp_zbt;
diff -r 7c12aaa128e3 -r 7afe0b19c898 tools/libfsimage/zfs/zfs-include/zap_leaf.h
--- a/tools/libfsimage/zfs/zfs-include/zap_leaf.h	Thu Oct 24 22:46:20 2013 +0100
+++ b/tools/libfsimage/zfs/zfs-include/zap_leaf.h	Thu Oct 31 22:48:42 2013 +0400
@@ -24,8 +24,6 @@
 #ifndef	_SYS_ZAP_LEAF_H
 #define	_SYS_ZAP_LEAF_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #define	ZAP_LEAF_MAGIC 0x2AB1EAF
 
 /* chunk size = 24 bytes */
diff -r 7c12aaa128e3 -r 7afe0b19c898 tools/libfsimage/zfs/zfs-include/zfs.h
--- a/tools/libfsimage/zfs/zfs-include/zfs.h	Thu Oct 24 22:46:20 2013 +0100
+++ b/tools/libfsimage/zfs/zfs-include/zfs.h	Thu Oct 31 22:48:42 2013 +0400
@@ -16,9 +16,10 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
+
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
  */
 
 #ifndef	_SYS_FS_ZFS_H
@@ -27,7 +28,14 @@
 /*
  * On-disk version number.
  */
-#define	SPA_VERSION			24ULL
+#define	SPA_VERSION_INITIAL		1ULL
+#define	SPA_VERSION_BEFORE_FEATURES	28ULL
+#define	SPA_VERSION			5000ULL
+#define	SPA_VERSION_FEATURES		5000ULL
+
+#define	SPA_VERSION_IS_SUPPORTED(v) \
+	(((v) >= SPA_VERSION_INITIAL && (v) <= SPA_VERSION_BEFORE_FEATURES) || \
+	((v) >= SPA_VERSION_FEATURES && (v) <= SPA_VERSION))
 
 /*
  * The following are configuration names used in the nvlist describing a pool's
@@ -67,6 +75,7 @@
 #define	ZPOOL_CONFIG_DDT_HISTOGRAM	"ddt_histogram"
 #define	ZPOOL_CONFIG_DDT_OBJ_STATS	"ddt_object_stats"
 #define	ZPOOL_CONFIG_DDT_STATS		"ddt_stats"
+#define	ZPOOL_CONFIG_FEATURES_FOR_READ	"features_for_read"
 /*
  * The persistent vdev state is stored as separate values rather than a single
  * 'vdev_state' entry.  This is because a device can be in multiple states, such
diff -r 7c12aaa128e3 -r 7afe0b19c898 tools/libfsimage/zfs/zfs-include/zfs_acl.h
--- a/tools/libfsimage/zfs/zfs-include/zfs_acl.h	Thu Oct 24 22:46:20 2013 +0100
+++ b/tools/libfsimage/zfs/zfs-include/zfs_acl.h	Thu Oct 31 22:48:42 2013 +0400
@@ -24,8 +24,6 @@
 #ifndef	_SYS_FS_ZFS_ACL_H
 #define	_SYS_FS_ZFS_ACL_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #ifndef _UID_T
 #define	_UID_T
 typedef	unsigned int uid_t;			/* UID type */
diff -r 7c12aaa128e3 -r 7afe0b19c898 tools/libfsimage/zfs/zfs-include/zio.h
--- a/tools/libfsimage/zfs/zfs-include/zio.h	Thu Oct 24 22:46:20 2013 +0100
+++ b/tools/libfsimage/zfs/zfs-include/zio.h	Thu Oct 31 22:48:42 2013 +0400
@@ -20,6 +20,9 @@
  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
+/*
+ * Copyright 2013 by Saso Kiselkov. All rights reserved.
+ */
 
 #ifndef _ZIO_H
 #define	_ZIO_H
@@ -73,6 +76,17 @@ enum zio_compress {
 	ZIO_COMPRESS_OFF,
 	ZIO_COMPRESS_LZJB,
 	ZIO_COMPRESS_EMPTY,
+	ZIO_COMPRESS_GZIP_1,
+	ZIO_COMPRESS_GZIP_2,
+	ZIO_COMPRESS_GZIP_3,
+	ZIO_COMPRESS_GZIP_4,
+	ZIO_COMPRESS_GZIP_5,
+	ZIO_COMPRESS_GZIP_6,
+	ZIO_COMPRESS_GZIP_7,
+	ZIO_COMPRESS_GZIP_8,
+	ZIO_COMPRESS_GZIP_9,
+	ZIO_COMPRESS_ZLE,
+	ZIO_COMPRESS_LZ4,
 	ZIO_COMPRESS_FUNCTIONS
 };
 
diff -r 7c12aaa128e3 -r 7afe0b19c898 tools/libfsimage/zfs/zfs_fletcher.c
--- a/tools/libfsimage/zfs/zfs_fletcher.c	Thu Oct 24 22:46:20 2013 +0100
+++ b/tools/libfsimage/zfs/zfs_fletcher.c	Thu Oct 31 22:48:42 2013 +0400
@@ -21,8 +21,6 @@
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include "fsys_zfs.h"
 
 
diff -r 7c12aaa128e3 -r 7afe0b19c898 tools/libfsimage/zfs/zfs_lz4.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libfsimage/zfs/zfs_lz4.c	Thu Oct 31 22:48:42 2013 +0400
@@ -0,0 +1,313 @@
+/*
+ * LZ4 - Fast LZ compression algorithm
+ * Header File
+ * Copyright (C) 2011-2013, Yann Collet.
+ * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You can contact the author at :
+ * - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html
+ * - LZ4 source repository : http://code.google.com/p/lz4/
+ */
+
+#include "fsys_zfs.h"
+#include <string.h>
+
+static int LZ4_uncompress_unknownOutputSize(const char *source, char *dest,
+					    int isize, int maxOutputSize);
+
+int
+lz4_decompress(void *s_start, void *d_start, size_t s_len, size_t d_len)
+{
+	const uint8_t *src = s_start;
+	uint32_t bufsiz = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) |
+	    src[3];
+
+	/* invalid compressed buffer size encoded at start */
+	if (bufsiz + 4 > s_len)
+		return (1);
+
+	/*
+	 * Returns 0 on success (decompression function returned non-negative)
+	 * and non-zero on failure (decompression function returned negative).
+	 */
+	return (LZ4_uncompress_unknownOutputSize(s_start + 4, d_start, bufsiz,
+	    d_len) < 0);
+}
+
+/*
+ * CPU Feature Detection
+ */
+
+/* 32 or 64 bits ? */
+#if (defined(__x86_64__) || defined(__x86_64) || defined(__amd64__) || \
+	defined(__amd64) || defined(__ppc64__) || defined(_WIN64) || \
+	defined(__LP64__) || defined(_LP64))
+#define	LZ4_ARCH64	1
+#else
+#define	LZ4_ARCH64	0
+#endif
+
+/*
+ * Little Endian or Big Endian?
+ * Note: overwrite the below #define if you know your architecture endianess.
+ */
+#if (defined(__BIG_ENDIAN__) || defined(__BIG_ENDIAN) || \
+	defined(_BIG_ENDIAN) || defined(_ARCH_PPC) || defined(__PPC__) || \
+	defined(__PPC) || defined(PPC) || defined(__powerpc__) || \
+	defined(__powerpc) || defined(powerpc) || \
+	((defined(__BYTE_ORDER__)&&(__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))))
+#define	LZ4_BIG_ENDIAN	1
+#else
+	/*
+	 * Little Endian assumed. PDP Endian and other very rare endian format
+	 * are unsupported.
+	 */
+#endif
+
+/*
+ * Compiler Options
+ */
+#if __STDC_VERSION__ >= 199901L	/* C99 */
+/* "restrict" is a known keyword */
+#else
+/* Disable restrict */
+#define	restrict
+#endif
+
+#define	GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
+
+#define	lz4_bswap16(x) ((unsigned short int) ((((x) >> 8) & 0xffu) \
+	| (((x) & 0xffu) << 8)))
+
+#if (GCC_VERSION >= 302) || (__INTEL_COMPILER >= 800) || defined(__clang__)
+#define	expect(expr, value)    (__builtin_expect((expr), (value)))
+#else
+#define	expect(expr, value)    (expr)
+#endif
+
+#define	likely(expr)	expect((expr) != 0, 1)
+#define	unlikely(expr)	expect((expr) != 0, 0)
+
+/* Basic types */
+#define	BYTE	uint8_t
+#define	U16	uint16_t
+#define	U32	uint32_t
+#define	S32	int32_t
+#define	U64	uint64_t
+
+typedef struct _U16_S {
+	U16 v;
+} U16_S;
+typedef struct _U32_S {
+	U32 v;
+} U32_S;
+typedef struct _U64_S {
+	U64 v;
+} U64_S;
+
+#define	A64(x)	(((U64_S *)(x))->v)
+#define	A32(x)	(((U32_S *)(x))->v)
+#define	A16(x)	(((U16_S *)(x))->v)
+
+/*
+ * Constants
+ */
+#define	MINMATCH 4
+
+#define	COPYLENGTH 8
+#define	LASTLITERALS 5
+
+#define	ML_BITS 4
+#define	ML_MASK ((1U<<ML_BITS)-1)
+#define	RUN_BITS (8-ML_BITS)
+#define	RUN_MASK ((1U<<RUN_BITS)-1)
+
+/*
+ * Architecture-specific macros
+ */
+#if LZ4_ARCH64
+#define	STEPSIZE 8
+#define	UARCH U64
+#define	AARCH A64
+#define	LZ4_COPYSTEP(s, d)	A64(d) = A64(s); d += 8; s += 8;
+#define	LZ4_COPYPACKET(s, d)	LZ4_COPYSTEP(s, d)
+#define	LZ4_SECURECOPY(s, d, e)	if (d < e) LZ4_WILDCOPY(s, d, e)
+#define	HTYPE U32
+#define	INITBASE(base)		const BYTE* const base = ip
+#else
+#define	STEPSIZE 4
+#define	UARCH U32
+#define	AARCH A32
+#define	LZ4_COPYSTEP(s, d)	A32(d) = A32(s); d += 4; s += 4;
+#define	LZ4_COPYPACKET(s, d)	LZ4_COPYSTEP(s, d); LZ4_COPYSTEP(s, d);
+#define	LZ4_SECURECOPY		LZ4_WILDCOPY
+#define	HTYPE const BYTE*
+#define	INITBASE(base)		const int base = 0
+#endif
+
+#if (defined(LZ4_BIG_ENDIAN) && !defined(BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE))
+#define	LZ4_READ_LITTLEENDIAN_16(d, s, p) \
+	{ U16 v = A16(p); v = lz4_bswap16(v); d = (s) - v; }
+#define	LZ4_WRITE_LITTLEENDIAN_16(p, i) \
+	{ U16 v = (U16)(i); v = lz4_bswap16(v); A16(p) = v; p += 2; }
+#else
+#define	LZ4_READ_LITTLEENDIAN_16(d, s, p) { d = (s) - A16(p); }
+#define	LZ4_WRITE_LITTLEENDIAN_16(p, v)  { A16(p) = v; p += 2; }
+#endif
+
+/* Macros */
+#define	LZ4_WILDCOPY(s, d, e) do { LZ4_COPYPACKET(s, d) } while (d < e);
+
+/* Decompression functions */
+
+static int
+LZ4_uncompress_unknownOutputSize(const char *source,
+    char *dest, int isize, int maxOutputSize)
+{
+	/* Local Variables */
+	const BYTE *restrict ip = (const BYTE *) source;
+	const BYTE *const iend = ip + isize;
+	const BYTE *restrict ref;
+
+	BYTE *restrict op = (BYTE *) dest;
+	BYTE *const oend = op + maxOutputSize;
+	BYTE *cpy;
+
+	size_t dec[] = { 0, 3, 2, 3, 0, 0, 0, 0 };
+
+	/* Main Loop */
+	while (ip < iend) {
+		BYTE token;
+		int length;
+
+		/* get runlength */
+		token = *ip++;
+		if ((length = (token >> ML_BITS)) == RUN_MASK) {
+			int s = 255;
+			while ((ip < iend) && (s == 255)) {
+				s = *ip++;
+				length += s;
+			}
+		}
+		/* copy literals */
+		cpy = op + length;
+		if ((cpy > oend - COPYLENGTH) ||
+		    (ip + length > iend - COPYLENGTH)) {
+			if (cpy > oend)
+				/*
+				 * Error: request to write beyond destination
+				 * buffer.
+				 */
+				goto _output_error;
+			if (ip + length > iend)
+				/*
+				 * Error : request to read beyond source
+				 * buffer.
+				 */
+				goto _output_error;
+			memcpy(op, ip, length);
+			op += length;
+			ip += length;
+			if (ip < iend)
+				/* Error : LZ4 format violation */
+				goto _output_error;
+			/* Necessarily EOF, due to parsing restrictions. */
+			break;
+		}
+		LZ4_WILDCOPY(ip, op, cpy);
+		ip -= (op - cpy);
+		op = cpy;
+
+		/* get offset */
+		LZ4_READ_LITTLEENDIAN_16(ref, cpy, ip);
+		ip += 2;
+		if (ref < (BYTE * const) dest)
+			/*
+			 * Error: offset creates reference outside of
+			 * destination buffer.
+			 */
+			goto _output_error;
+
+		/* get matchlength */
+		if ((length = (token & ML_MASK)) == ML_MASK) {
+			while (ip < iend) {
+				int s = *ip++;
+				length += s;
+				if (s == 255)
+					continue;
+				break;
+			}
+		}
+		/* copy repeated sequence */
+		if unlikely(op - ref < STEPSIZE) {
+#if LZ4_ARCH64
+			size_t dec2table[] = { 0, 0, 0, -1, 0, 1, 2, 3 };
+			size_t dec2 = dec2table[op - ref];
+#else
+			const int dec2 = 0;
+#endif
+			*op++ = *ref++;
+			*op++ = *ref++;
+			*op++ = *ref++;
+			*op++ = *ref++;
+			ref -= dec[op - ref];
+			A32(op) = A32(ref);
+			op += STEPSIZE - 4;
+			ref -= dec2;
+		} else {
+			LZ4_COPYSTEP(ref, op);
+		}
+		cpy = op + length - (STEPSIZE - 4);
+		if (cpy > oend - COPYLENGTH) {
+			if (cpy > oend)
+				/*
+				 * Error: request to write outside of
+				 * destination buffer.
+				 */
+				goto _output_error;
+			LZ4_SECURECOPY(ref, op, (oend - COPYLENGTH));
+			while (op < cpy)
+				*op++ = *ref++;
+			op = cpy;
+			if (op == oend)
+				/*
+				 * Check EOF (should never happen, since last
+				 * 5 bytes are supposed to be literals).
+				 */
+				break;
+			continue;
+		}
+		LZ4_SECURECOPY(ref, op, cpy);
+		op = cpy;	/* correction */
+	}
+
+	/* end of decoding */
+	return (int)(((char *)op) - dest);
+
+	/* write overflow error detected */
+	_output_error:
+	return (int)(-(((char *)ip) - source));
+}
diff -r 7c12aaa128e3 -r 7afe0b19c898 tools/libfsimage/zfs/zfs_lzjb.c
--- a/tools/libfsimage/zfs/zfs_lzjb.c	Thu Oct 24 22:46:20 2013 +0100
+++ b/tools/libfsimage/zfs/zfs_lzjb.c	Thu Oct 31 22:48:42 2013 +0400
@@ -21,8 +21,6 @@
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include "fsys_zfs.h"
 
 #define	MATCH_BITS	6
@@ -34,10 +32,10 @@
 int
 lzjb_decompress(void *s_start, void *d_start, size_t s_len, size_t d_len)
 {
-	uint8_t *src = s_start;
-	uint8_t *dst = d_start;
-	uint8_t *d_end = (uint8_t *)d_start + d_len;
-	uint8_t *cpy, copymap = '\0';
+	uchar_t *src = s_start;
+	uchar_t *dst = d_start;
+	uchar_t *d_end = (uchar_t *)d_start + d_len;
+	uchar_t *cpy, copymap = '\0';
 	int copymask = 1 << (NBBY - 1);
 
 	while (dst < d_end) {
@@ -49,7 +47,7 @@ lzjb_decompress(void *s_start, void *d_s
 			int mlen = (src[0] >> (NBBY - MATCH_BITS)) + MATCH_MIN;
 			int offset = ((src[0] << NBBY) | src[1]) & OFFSET_MASK;
 			src += 2;
-			if ((cpy = dst - offset) < (uint8_t *)d_start)
+			if ((cpy = dst - offset) < (uchar_t *)d_start)
 				return (-1);
 			while (--mlen >= 0 && dst < d_end)
 				*dst++ = *cpy++;
diff -r 7c12aaa128e3 -r 7afe0b19c898 tools/libfsimage/zfs/zfs_sha256.c
--- a/tools/libfsimage/zfs/zfs_sha256.c	Thu Oct 24 22:46:20 2013 +0100
+++ b/tools/libfsimage/zfs/zfs_sha256.c	Thu Oct 31 22:48:42 2013 +0400
@@ -21,8 +21,6 @@
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include "fsys_zfs.h"
 
 /*

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1 of 1] Update ZFS sources from illumos.org:
  2013-10-31 19:04 ` [PATCH 1 of 1] Update ZFS sources from illumos.org: Igor Kozhkuhov
@ 2013-11-11 16:23   ` Ian Campbell
  2013-11-11 16:38     ` Egger, Christoph
  2013-11-11 16:57     ` Igor Kozhukhov
  0 siblings, 2 replies; 14+ messages in thread
From: Ian Campbell @ 2013-11-11 16:23 UTC (permalink / raw)
  To: Igor Kozhkuhov; +Cc: Ian Jackson, xen-devel

On Thu, 2013-10-31 at 23:04 +0400, Igor Kozhkuhov wrote:
> https://github.com/illumos/illumos-gate/tree/master/usr/src/grub/grub-0.97/stage2

Is this link to a specific unchanging version? It looks to me like it
probably changes everytime something is committed.

> Additional CFLAGS rules have been added after 'CFLAGS += -Werror -D_GNU_SOURCE' in Rules.mk

Actually, they've been added to tools/libfsimage/zfs/Makefile ?

> Signed-off-by: Igor Kozhukhov <ikozhukhov@gmail.com>
> Asked-by: Ian Campbell <Ian.Campbell@citrix.com>

This isn't one of our standard tags, I take it you didn't mean Acked-by,
since I didn't ack it. I think all I did was ask for submitting patches
to be followed etc, no need to credit me for that IMHO.

> 
> diff -r 7c12aaa128e3 -r 7afe0b19c898 tools/libfsimage/zfs/Makefile
> --- a/tools/libfsimage/zfs/Makefile	Thu Oct 24 22:46:20 2013 +0100
> +++ b/tools/libfsimage/zfs/Makefile	Thu Oct 31 22:48:42 2013 +0400
> @@ -25,7 +25,7 @@
>  XEN_ROOT = $(CURDIR)/../../..
>  
>  CFLAGS += -DFSYS_ZFS -DFSIMAGE -I$(XEN_ROOT)/tools/libfsimage/zfs
> -LIB_SRCS-y = zfs_lzjb.c zfs_sha256.c zfs_fletcher.c fsi_zfs.c fsys_zfs.c
> +LIB_SRCS-y = zfs_lzjb.c zfs_sha256.c zfs_fletcher.c fsi_zfs.c fsys_zfs.c zfs_lz4.c
>  
>  FS = zfs
>  
> @@ -36,3 +36,8 @@ all: fs-all
>  install: fs-install
>  
>  include $(XEN_ROOT)/tools/libfsimage/Rules.mk
> +
> +# need for build illumos ZFS
> +CFLAGS += -Wno-parentheses
> +CFLAGS += -Wno-unused

Are these really needed right at the end like this rather than in the
same paragraph as the CFLAGS stuff in the context of the previous hunk?

> +# end
> diff -r 7c12aaa128e3 -r 7afe0b19c898 tools/libfsimage/zfs/fsi_zfs.h
> --- a/tools/libfsimage/zfs/fsi_zfs.h	Thu Oct 24 22:46:20 2013 +0100
> +++ b/tools/libfsimage/zfs/fsi_zfs.h	Thu Oct 31 22:48:42 2013 +0400
> @@ -36,6 +36,8 @@
>  [...]

I'm not in much position to comment on the actual code.

Ian.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1 of 1] Update ZFS sources from illumos.org:
  2013-11-11 16:23   ` Ian Campbell
@ 2013-11-11 16:38     ` Egger, Christoph
  2013-11-11 16:40       ` Ian Campbell
  2013-11-11 16:57     ` Igor Kozhukhov
  1 sibling, 1 reply; 14+ messages in thread
From: Egger, Christoph @ 2013-11-11 16:38 UTC (permalink / raw)
  To: Ian Campbell, Igor Kozhkuhov; +Cc: Ian Jackson, xen-devel

On 11.11.13 17:23, Ian Campbell wrote:
>> Signed-off-by: Igor Kozhukhov <ikozhukhov@gmail.com>
>> Asked-by: Ian Campbell <Ian.Campbell@citrix.com>
> 
> This isn't one of our standard tags, I take it you didn't mean Acked-by,
> since I didn't ack it. I think all I did was ask for submitting patches
> to be followed etc, no need to credit me for that IMHO.

Maybe he should use "Questioned-by" to make clear this is not a typo :-)

Christoph

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1 of 1] Update ZFS sources from illumos.org:
  2013-11-11 16:38     ` Egger, Christoph
@ 2013-11-11 16:40       ` Ian Campbell
  2013-11-11 16:57         ` Igor Kozhukhov
  0 siblings, 1 reply; 14+ messages in thread
From: Ian Campbell @ 2013-11-11 16:40 UTC (permalink / raw)
  To: Egger, Christoph; +Cc: Igor Kozhkuhov, Ian Jackson, xen-devel

On Mon, 2013-11-11 at 17:38 +0100, Egger, Christoph wrote:
> On 11.11.13 17:23, Ian Campbell wrote:
> >> Signed-off-by: Igor Kozhukhov <ikozhukhov@gmail.com>
> >> Asked-by: Ian Campbell <Ian.Campbell@citrix.com>
> > 
> > This isn't one of our standard tags, I take it you didn't mean Acked-by,
> > since I didn't ack it. I think all I did was ask for submitting patches
> > to be followed etc, no need to credit me for that IMHO.
> 
> Maybe he should use "Questioned-by" to make clear this is not a typo :-)

Or just skip it?

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1 of 1] Update ZFS sources from illumos.org:
  2013-11-11 16:23   ` Ian Campbell
  2013-11-11 16:38     ` Egger, Christoph
@ 2013-11-11 16:57     ` Igor Kozhukhov
  2013-11-11 17:05       ` Ian Campbell
  1 sibling, 1 reply; 14+ messages in thread
From: Igor Kozhukhov @ 2013-11-11 16:57 UTC (permalink / raw)
  To: Ian Campbell; +Cc: Ian Jackson, xen-devel

Hi Ian,

I'm sorry for misunderstanding about Asked-by tag - i'm new on xen contribution.

please find my comments below inline.

--
Best regards,
Igor Kozhukhov




On Nov 11, 2013, at 8:23 PM, Ian Campbell wrote:

> On Thu, 2013-10-31 at 23:04 +0400, Igor Kozhkuhov wrote:
>> https://github.com/illumos/illumos-gate/tree/master/usr/src/grub/grub-0.97/stage2
> 
> Is this link to a specific unchanging version? It looks to me like it
> probably changes everytime something is committed.

This link specified where i got sources for libfsimage ZFS updates.
> 
>> Additional CFLAGS rules have been added after 'CFLAGS += -Werror -D_GNU_SOURCE' in Rules.mk
> 
> Actually, they've been added to tools/libfsimage/zfs/Makefile ?
> 
Rules.mk contain 'CFLAGS += -Werror -D_GNU_SOURCE'
this file included to zfs/Makefile on bottom. if we have to add additional rules for disable GCC warnings we should to add our rules after -Werror.
I have added additional rules for ZFS compilations after including Rules.mk in zfs/Makefile

>> Signed-off-by: Igor Kozhukhov <ikozhukhov@gmail.com>
>> Asked-by: Ian Campbell <Ian.Campbell@citrix.com>
> 
> This isn't one of our standard tags, I take it you didn't mean Acked-by,
> since I didn't ack it. I think all I did was ask for submitting patches
> to be followed etc, no need to credit me for that IMHO.
> 
Sorry for this - my misunderstanding of process.

>> 
>> diff -r 7c12aaa128e3 -r 7afe0b19c898 tools/libfsimage/zfs/Makefile
>> --- a/tools/libfsimage/zfs/Makefile	Thu Oct 24 22:46:20 2013 +0100
>> +++ b/tools/libfsimage/zfs/Makefile	Thu Oct 31 22:48:42 2013 +0400
>> @@ -25,7 +25,7 @@
>> XEN_ROOT = $(CURDIR)/../../..
>> 
>> CFLAGS += -DFSYS_ZFS -DFSIMAGE -I$(XEN_ROOT)/tools/libfsimage/zfs
>> -LIB_SRCS-y = zfs_lzjb.c zfs_sha256.c zfs_fletcher.c fsi_zfs.c fsys_zfs.c
>> +LIB_SRCS-y = zfs_lzjb.c zfs_sha256.c zfs_fletcher.c fsi_zfs.c fsys_zfs.c zfs_lz4.c
>> 
>> FS = zfs
>> 
>> @@ -36,3 +36,8 @@ all: fs-all
>> install: fs-install
>> 
>> include $(XEN_ROOT)/tools/libfsimage/Rules.mk
>> +
>> +# need for build illumos ZFS
>> +CFLAGS += -Wno-parentheses
>> +CFLAGS += -Wno-unused
> 
> Are these really needed right at the end like this rather than in the
> same paragraph as the CFLAGS stuff in the context of the previous hunk?
> 
>> +# end
>> diff -r 7c12aaa128e3 -r 7afe0b19c898 tools/libfsimage/zfs/fsi_zfs.h
>> --- a/tools/libfsimage/zfs/fsi_zfs.h	Thu Oct 24 22:46:20 2013 +0100
>> +++ b/tools/libfsimage/zfs/fsi_zfs.h	Thu Oct 31 22:48:42 2013 +0400
>> @@ -36,6 +36,8 @@
>> [...]
> 
> I'm not in much position to comment on the actual code.
> 
> Ian.
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1 of 1] Update ZFS sources from illumos.org:
  2013-11-11 16:40       ` Ian Campbell
@ 2013-11-11 16:57         ` Igor Kozhukhov
  2013-11-11 17:16           ` Igor Kozhukhov
  0 siblings, 1 reply; 14+ messages in thread
From: Igor Kozhukhov @ 2013-11-11 16:57 UTC (permalink / raw)
  To: Ian Campbell; +Cc: Egger, Christoph, Ian Jackson, xen-devel

could you please let me know what i need to do next ?

--
Best regards,
Igor Kozhukhov




On Nov 11, 2013, at 8:40 PM, Ian Campbell wrote:

> On Mon, 2013-11-11 at 17:38 +0100, Egger, Christoph wrote:
>> On 11.11.13 17:23, Ian Campbell wrote:
>>>> Signed-off-by: Igor Kozhukhov <ikozhukhov@gmail.com>
>>>> Asked-by: Ian Campbell <Ian.Campbell@citrix.com>
>>> 
>>> This isn't one of our standard tags, I take it you didn't mean Acked-by,
>>> since I didn't ack it. I think all I did was ask for submitting patches
>>> to be followed etc, no need to credit me for that IMHO.
>> 
>> Maybe he should use "Questioned-by" to make clear this is not a typo :-)
> 
> Or just skip it?
> 
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1 of 1] Update ZFS sources from illumos.org:
  2013-11-11 16:57     ` Igor Kozhukhov
@ 2013-11-11 17:05       ` Ian Campbell
  0 siblings, 0 replies; 14+ messages in thread
From: Ian Campbell @ 2013-11-11 17:05 UTC (permalink / raw)
  To: Igor Kozhukhov; +Cc: Ian Jackson, xen-devel

On Mon, 2013-11-11 at 20:57 +0400, Igor Kozhukhov wrote:
> On Nov 11, 2013, at 8:23 PM, Ian Campbell wrote:
> 
> > On Thu, 2013-10-31 at 23:04 +0400, Igor Kozhkuhov wrote:
> >> https://github.com/illumos/illumos-gate/tree/master/usr/src/grub/grub-0.97/stage2
> > 
> > Is this link to a specific unchanging version? It looks to me like it
> > probably changes everytime something is committed.
> 
> This link specified where i got sources for libfsimage ZFS updates.

It's not a static copy of the source though. Someone can't use this link
in a years time to go and compare what has changed since this sync
because it will have changed.

There needs to be a changeset ID corresponding to the exact source you
imported in there somewhere, either in the URL or in a comment.

> > 
> >> Additional CFLAGS rules have been added after 'CFLAGS += -Werror -D_GNU_SOURCE' in Rules.mk
> > 
> > Actually, they've been added to tools/libfsimage/zfs/Makefile ?
> > 
> Rules.mk contain 'CFLAGS += -Werror -D_GNU_SOURCE'
> this file included to zfs/Makefile on bottom. if we have to add additional rules for disable GCC warnings we should to add our rules after -Werror.

Why must they be after -Werror?

> I have added additional rules for ZFS compilations after including Rules.mk in zfs/Makefile
> 
> >> Signed-off-by: Igor Kozhukhov <ikozhukhov@gmail.com>
> >> Asked-by: Ian Campbell <Ian.Campbell@citrix.com>
> > 
> > This isn't one of our standard tags, I take it you didn't mean Acked-by,
> > since I didn't ack it. I think all I did was ask for submitting patches
> > to be followed etc, no need to credit me for that IMHO.
> > 
> Sorry for this - my misunderstanding of process.

No problem.

Ian.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1 of 1] Update ZFS sources from illumos.org:
  2013-11-11 16:57         ` Igor Kozhukhov
@ 2013-11-11 17:16           ` Igor Kozhukhov
  2013-11-11 17:23             ` Ian Campbell
  0 siblings, 1 reply; 14+ messages in thread
From: Igor Kozhukhov @ 2013-11-11 17:16 UTC (permalink / raw)
  To: Ian Campbell; +Cc: Egger, Christoph, Ian Jackson, xen-devel

Hi Ian,

we can use:
https://github.com/illumos/illumos-gate/tree/master/usr/src/grub@2acef22db7808606888f8f92715629ff3ba555b9

will it be correct ?
change set after '@'

about -Werror

by GCC specific, if we want to disable some warnings we should add rules after -Werror.
example:
-Werror -Wno-parentheses -Wno-unused

if we add rules "-Wno-parentheses -Wno-unused" before "-Werror" - they will be ignored and we will have build problem.

--
Best regards,
Igor Kozhukhov




On Nov 11, 2013, at 8:57 PM, Igor Kozhukhov wrote:

> could you please let me know what i need to do next ?
> 
> --
> Best regards,
> Igor Kozhukhov
> 
> 
> 
> 
> On Nov 11, 2013, at 8:40 PM, Ian Campbell wrote:
> 
>> On Mon, 2013-11-11 at 17:38 +0100, Egger, Christoph wrote:
>>> On 11.11.13 17:23, Ian Campbell wrote:
>>>>> Signed-off-by: Igor Kozhukhov <ikozhukhov@gmail.com>
>>>>> Asked-by: Ian Campbell <Ian.Campbell@citrix.com>
>>>> 
>>>> This isn't one of our standard tags, I take it you didn't mean Acked-by,
>>>> since I didn't ack it. I think all I did was ask for submitting patches
>>>> to be followed etc, no need to credit me for that IMHO.
>>> 
>>> Maybe he should use "Questioned-by" to make clear this is not a typo :-)
>> 
>> Or just skip it?
>> 
>> 
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1 of 1] Update ZFS sources from illumos.org:
  2013-11-11 17:16           ` Igor Kozhukhov
@ 2013-11-11 17:23             ` Ian Campbell
  2013-11-11 17:31               ` Igor Kozhukhov
  2013-11-11 17:31               ` Igor Kozhukhov
  0 siblings, 2 replies; 14+ messages in thread
From: Ian Campbell @ 2013-11-11 17:23 UTC (permalink / raw)
  To: Igor Kozhukhov; +Cc: Egger, Christoph, Ian Jackson, xen-devel

(please don't top post)

On Mon, 2013-11-11 at 21:16 +0400, Igor Kozhukhov wrote:
> Hi Ian,
> 
> we can use:
> https://github.com/illumos/illumos-gate/tree/master/usr/src/grub@2acef22db7808606888f8f92715629ff3ba555b9
> 
> will it be correct ?
> change set after '@'

That link is 404 for me.

> about -Werror
> 
> by GCC specific, if we want to disable some warnings we should add rules after -Werror.
> example:
> -Werror -Wno-parentheses -Wno-unused
> 
> if we add rules "-Wno-parentheses -Wno-unused" before "-Werror" - they will be ignored and we will have build problem.

Are you sure? We have at least some instances of this in our tree
already and it doesn't seem to be having any adverse impact.

The Werror docs don't say anything about this requirement, just "Make
all warnings into errors.". Since Werror doesn't actually enable or
disable any warnings itself I can't see why the ordering would matter.

Ian.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1 of 1] Update ZFS sources from illumos.org:
  2013-11-11 17:23             ` Ian Campbell
@ 2013-11-11 17:31               ` Igor Kozhukhov
  2013-11-11 17:31               ` Igor Kozhukhov
  1 sibling, 0 replies; 14+ messages in thread
From: Igor Kozhukhov @ 2013-11-11 17:31 UTC (permalink / raw)
  To: Ian Campbell; +Cc: Egger, Christoph, Ian Jackson, xen-devel



On Nov 11, 2013, at 9:23 PM, Ian Campbell wrote:

> 
> On Mon, 2013-11-11 at 21:16 +0400, Igor Kozhukhov wrote:
>> Hi Ian,
>> 
>> we can use:
>> https://github.com/illumos/illumos-gate/tree/master/usr/src/grub@2acef22db7808606888f8f92715629ff3ba555b9
>> 
>> will it be correct ?
>> change set after '@'
> 
> That link is 404 for me.
> 
Could you please let me know how to get URL+changes et on GITHUB or another version control system ?
my URL contain:
main URL: https://github.com/illumos/illumos-gate/tree/master/usr/src/grub
changeset: 2acef22db7808606888f8f92715629ff3ba555b9

for compare with next updates if needed.


>> about -Werror
>> 
>> by GCC specific, if we want to disable some warnings we should add rules after -Werror.
>> example:
>> -Werror -Wno-parentheses -Wno-unused
>> 
>> if we add rules "-Wno-parentheses -Wno-unused" before "-Werror" - they will be ignored and we will have build problem.
> 
> Are you sure? We have at least some instances of this in our tree
> already and it doesn't seem to be having any adverse impact.
> 
> The Werror docs don't say anything about this requirement, just "Make
> all warnings into errors.". Since Werror doesn't actually enable or
> disable any warnings itself I can't see why the ordering would matter.
> 
Yes - i'm sure. I have tested my changes with my rules before "-Werror" - they was ignored and i can see build issues. I have tested by gcc44 and gcc47.

> Ian.
> 

-Igor

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1 of 1] Update ZFS sources from illumos.org:
  2013-11-11 17:23             ` Ian Campbell
  2013-11-11 17:31               ` Igor Kozhukhov
@ 2013-11-11 17:31               ` Igor Kozhukhov
  2013-11-11 17:34                 ` Ian Campbell
  1 sibling, 1 reply; 14+ messages in thread
From: Igor Kozhukhov @ 2013-11-11 17:31 UTC (permalink / raw)
  To: Ian Campbell; +Cc: Egger, Christoph, Ian Jackson, xen-devel



On Nov 11, 2013, at 9:23 PM, Ian Campbell wrote:

> 
> On Mon, 2013-11-11 at 21:16 +0400, Igor Kozhukhov wrote:
>> Hi Ian,
>> 
>> we can use:
>> https://github.com/illumos/illumos-gate/tree/master/usr/src/grub@2acef22db7808606888f8f92715629ff3ba555b9
>> 
>> will it be correct ?
>> change set after '@'
> 
> That link is 404 for me.
> 
Could you please let me know how to get URL+changes et on GITHUB or another version control system ?
my URL contain:
main URL: https://github.com/illumos/illumos-gate/tree/master/usr/src/grub
changeset: 2acef22db7808606888f8f92715629ff3ba555b9

for compare with next updates if needed.


>> about -Werror
>> 
>> by GCC specific, if we want to disable some warnings we should add rules after -Werror.
>> example:
>> -Werror -Wno-parentheses -Wno-unused
>> 
>> if we add rules "-Wno-parentheses -Wno-unused" before "-Werror" - they will be ignored and we will have build problem.
> 
> Are you sure? We have at least some instances of this in our tree
> already and it doesn't seem to be having any adverse impact.
> 
> The Werror docs don't say anything about this requirement, just "Make
> all warnings into errors.". Since Werror doesn't actually enable or
> disable any warnings itself I can't see why the ordering would matter.
> 
Yes - i'm sure. I have tested my changes with my rules before "-Werror" - they was ignored and i can see build issues. I have tested by gcc44 and gcc47.

> Ian.
> 

-Igor

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1 of 1] Update ZFS sources from illumos.org:
  2013-11-11 17:31               ` Igor Kozhukhov
@ 2013-11-11 17:34                 ` Ian Campbell
  2013-11-11 17:47                   ` Igor Kozhukhov
  0 siblings, 1 reply; 14+ messages in thread
From: Ian Campbell @ 2013-11-11 17:34 UTC (permalink / raw)
  To: Igor Kozhukhov; +Cc: Egger, Christoph, Ian Jackson, xen-devel

On Mon, 2013-11-11 at 21:31 +0400, Igor Kozhukhov wrote:
> 
> On Nov 11, 2013, at 9:23 PM, Ian Campbell wrote:
> 
> > 
> > On Mon, 2013-11-11 at 21:16 +0400, Igor Kozhukhov wrote:
> >> Hi Ian,
> >> 
> >> we can use:
> >> https://github.com/illumos/illumos-gate/tree/master/usr/src/grub@2acef22db7808606888f8f92715629ff3ba555b9
> >> 
> >> will it be correct ?
> >> change set after '@'
> > 
> > That link is 404 for me.
> > 
> Could you please let me know how to get URL+changes et on GITHUB or another version control system ?
> my URL contain:
> main URL: https://github.com/illumos/illumos-gate/tree/master/usr/src/grub
> changeset: 2acef22db7808606888f8f92715629ff3ba555b9
> 
> for compare with next updates if needed.

Just saying it in words is fine (changeset 2aceetcetc from
https://github/...etcetc).

> >> about -Werror
> >> 
> >> by GCC specific, if we want to disable some warnings we should add rules after -Werror.
> >> example:
> >> -Werror -Wno-parentheses -Wno-unused
> >> 
> >> if we add rules "-Wno-parentheses -Wno-unused" before "-Werror" - they will be ignored and we will have build problem.
> > 
> > Are you sure? We have at least some instances of this in our tree
> > already and it doesn't seem to be having any adverse impact.
> > 
> > The Werror docs don't say anything about this requirement, just "Make
> > all warnings into errors.". Since Werror doesn't actually enable or
> > disable any warnings itself I can't see why the ordering would matter.
> > 
> Yes - i'm sure. I have tested my changes with my rules before
> "-Werror" - they was ignored and i can see build issues. I have tested
> by gcc44 and gcc47.

How odd. Are you sure it is the position relative to Werror which
matters and not e.g. -Wall ?

Ian.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1 of 1] Update ZFS sources from illumos.org:
  2013-11-11 17:34                 ` Ian Campbell
@ 2013-11-11 17:47                   ` Igor Kozhukhov
  0 siblings, 0 replies; 14+ messages in thread
From: Igor Kozhukhov @ 2013-11-11 17:47 UTC (permalink / raw)
  To: Ian Campbell; +Cc: Egger, Christoph, Ian Jackson, xen-devel


On Nov 11, 2013, at 9:34 PM, Ian Campbell wrote:

> On Mon, 2013-11-11 at 21:31 +0400, Igor Kozhukhov wrote:
>> 
>> On Nov 11, 2013, at 9:23 PM, Ian Campbell wrote:
>> 
>>> 
>>> On Mon, 2013-11-11 at 21:16 +0400, Igor Kozhukhov wrote:
>>>> Hi Ian,
>>>> 
>>>> we can use:
>>>> https://github.com/illumos/illumos-gate/tree/master/usr/src/grub@2acef22db7808606888f8f92715629ff3ba555b9
>>>> 
>>>> will it be correct ?
>>>> change set after '@'
>>> 
>>> That link is 404 for me.
>>> 
>> Could you please let me know how to get URL+changes et on GITHUB or another version control system ?
>> my URL contain:
>> main URL: https://github.com/illumos/illumos-gate/tree/master/usr/src/grub
>> changeset: 2acef22db7808606888f8f92715629ff3ba555b9
>> 
>> for compare with next updates if needed.
> 
> Just saying it in words is fine (changeset 2aceetcetc from
> https://github/...etcetc).
> 
Could you please help me with example ?
can we use what i wrote above ?

>>>> about -Werror
>>>> 
>>>> by GCC specific, if we want to disable some warnings we should add rules after -Werror.
>>>> example:
>>>> -Werror -Wno-parentheses -Wno-unused
>>>> 
>>>> if we add rules "-Wno-parentheses -Wno-unused" before "-Werror" - they will be ignored and we will have build problem.
>>> 
>>> Are you sure? We have at least some instances of this in our tree
>>> already and it doesn't seem to be having any adverse impact.
>>> 
>>> The Werror docs don't say anything about this requirement, just "Make
>>> all warnings into errors.". Since Werror doesn't actually enable or
>>> disable any warnings itself I can't see why the ordering would matter.
>>> 
>> Yes - i'm sure. I have tested my changes with my rules before
>> "-Werror" - they was ignored and i can see build issues. I have tested
>> by gcc44 and gcc47.
> 
> How odd. Are you sure it is the position relative to Werror which
> matters and not e.g. -Wall ?
> 
I have tested in on current build env - if i put my variables before "-Werror" - i have build failed.
if my additional rules for disable warning will be added after "-Werror" - all work well

> Ian.
> 

-Igor

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2013-11-11 17:47 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-10-31 19:04 [PATCH 0 of 1] [PATCH v2] update ZFS for pygrub from illumos Igor Kozhkuhov
2013-10-31 19:04 ` [PATCH 1 of 1] Update ZFS sources from illumos.org: Igor Kozhkuhov
2013-11-11 16:23   ` Ian Campbell
2013-11-11 16:38     ` Egger, Christoph
2013-11-11 16:40       ` Ian Campbell
2013-11-11 16:57         ` Igor Kozhukhov
2013-11-11 17:16           ` Igor Kozhukhov
2013-11-11 17:23             ` Ian Campbell
2013-11-11 17:31               ` Igor Kozhukhov
2013-11-11 17:31               ` Igor Kozhukhov
2013-11-11 17:34                 ` Ian Campbell
2013-11-11 17:47                   ` Igor Kozhukhov
2013-11-11 16:57     ` Igor Kozhukhov
2013-11-11 17:05       ` Ian Campbell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.