[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: [Pkg-zfsonlinux-devel] zfsutils-linux: /usr/sbin/grub-probe: error: unknown filesystem



On 09/29/2016 02:52 AM, Nicolas Di Gregorio wrote:
> no it seems it's not whole disks.

If it's not whole_disk, then that's not the problem.

Thanks for including the zdb output. I should have asked for that.
That's a much easier way to figure this out. Also, I think that's going
to lead us to the real problem...

Your pool requires the hole_birth and embedded_data features. I suspect
that Debian's GRUB doesn't support those.

I've attached all the ZFS patches from Ubuntu's GRUB.

-- 
Richard
Description: zfs-initramfs currently provides extraneous, undesired symlinks to
  devices directly underneath /dev/ to satisfy zpool's historical output of
  unqualified device names. By including this environment variable to signal
  our intent to zpool, zfs-linux packages can drop the symlink behavior when
  updating to its upstream or backported output behavior.
Author: Chad MILLER <chad.miller@canonical.com>
Bug-Ubuntu: https://bugs.launchpad.net/bugs/1527727
Bug: https://savannah.gnu.org/bugs/?43653

--- a/grub-core/osdep/unix/getroot.c
+++ b/grub-core/osdep/unix/getroot.c
@@ -243,6 +243,7 @@ grub_util_find_root_devices_from_poolnam
   argv[2] = poolname;
   argv[3] = NULL;
 
+  setenv("ZPOOL_VDEV_NAME_PATH", "YES", 1);
   pid = grub_util_exec_pipe (argv, &fd);
   if (!pid)
     return NULL;
>From c5b9a38618e74396aa1af4f769d3ffe94b14b9c9 Mon Sep 17 00:00:00 2001
From: Andrei Borzenkov <arvidjaar@gmail.com>
Date: Thu, 14 May 2015 07:50:33 +0300
Subject: zfs: fix integer truncation in zap_lookup

Size after shift could exceed 16 bits; use grub_unit32_t for result.

Reported and tested by: Kostya Berger <bergerkos@yahoo.co.uk>
Closes: 44448

Origin: upstream, http://git.savannah.gnu.org/cgit/grub.git/commit/?id=5370dcfdae66b60cff3507ad925300a679fe4117
Last-Update: 2016-01-22

Patch-Name: zfs-zap-lookup-truncation.patch
---
 grub-core/fs/zfs/zfs.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c
index a95e7e3..d33424c 100644
--- a/grub-core/fs/zfs/zfs.c
+++ b/grub-core/fs/zfs/zfs.c
@@ -2068,10 +2068,10 @@ dmu_read (dnode_end_t * dn, grub_uint64_t blkid, void **buf,
  */
 static grub_err_t
 mzap_lookup (mzap_phys_t * zapobj, grub_zfs_endian_t endian,
-	     grub_uint16_t objsize, const char *name, grub_uint64_t * value,
+	     grub_uint32_t objsize, const char *name, grub_uint64_t * value,
 	     int case_insensitive)
 {
-  grub_uint16_t i, chunks;
+  grub_uint32_t i, chunks;
   mzap_ent_phys_t *mzap_ent = zapobj->mz_chunk;
 
   if (objsize < MZAP_ENT_LEN)
@@ -2483,7 +2483,7 @@ 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_uint16_t size;
+  grub_uint32_t size;
   void *zapbuf;
   grub_err_t err;
   grub_zfs_endian_t endian;
@@ -2491,7 +2491,7 @@ zap_lookup (dnode_end_t * zap_dnode, const char *name, grub_uint64_t *val,
   grub_dprintf ("zfs", "looking for '%s'\n", name);
 
   /* Read in the first block of the zap object data. */
-  size = grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec, 
+  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)
>From acc35f3fa2a9755a43ec5c4e83d58d88983634c1 Mon Sep 17 00:00:00 2001
From: Vladimir Serbinenko <phcoder@gmail.com>
Date: Sat, 21 Feb 2015 16:22:01 +0100
Subject: zfs/mzap_lookup: Fix argument types

Origin: upstream, http://git.savannah.gnu.org/cgit/grub.git/commit/?id=87a04adb6541c4bf169644bb2f84036a7c8558dd
Last-Update: 2016-01-22

Patch-Name: zfs-mzap-lookup-argument-types.patch
---
 grub-core/fs/zfs/zfs.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c
index e00a980..da8fd56 100644
--- a/grub-core/fs/zfs/zfs.c
+++ b/grub-core/fs/zfs/zfs.c
@@ -2010,12 +2010,14 @@ dmu_read (dnode_end_t * dn, grub_uint64_t blkid, void **buf,
  */
 static grub_err_t
 mzap_lookup (mzap_phys_t * zapobj, grub_zfs_endian_t endian,
-	     int objsize, const char *name, grub_uint64_t * value,
+	     grub_uint16_t objsize, const char *name, grub_uint64_t * value,
 	     int case_insensitive)
 {
-  int i, chunks;
+  grub_uint16_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++)
     {
@@ -2423,7 +2425,7 @@ 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;
-  int size;
+  grub_uint16_t size;
   void *zapbuf;
   grub_err_t err;
   grub_zfs_endian_t endian;
>From f4483fc0bbeaff9dc8b899aea97a914d914c46d6 Mon Sep 17 00:00:00 2001
From: Toomas Soome <tsoome@me.com>
Date: Thu, 16 Apr 2015 08:22:08 +0300
Subject: zfs: com.delphix:hole_birth feature support

In the past birth was always zero for holes. This feature started
to make use of birth for holes as well, so change code to test for
valid DVA address instead.

Origin: upstream, http://git.savannah.gnu.org/cgit/grub.git/commit/?id=a1007c6af296172c788f3346ff3ad30b9020f723
Last-Update: 2016-01-22

Patch-Name: zfs-hole-birth.patch
---
 grub-core/fs/zfs/zfs.c | 6 ++++--
 include/grub/zfs/spa.h | 4 +++-
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c
index da8fd56..b01c34f 100644
--- a/grub-core/fs/zfs/zfs.c
+++ b/grub-core/fs/zfs/zfs.c
@@ -280,7 +280,9 @@ grub_crypto_cipher_handle_t (*grub_zfs_load_key) (const struct grub_zfs_key *key
  */
 #define MAX_SUPPORTED_FEATURE_STRLEN 50
 static const char *spa_feature_names[] = {
-  "org.illumos:lz4_compress",NULL
+  "org.illumos:lz4_compress",
+  "com.delphix:hole_birth",
+  NULL
 };
 
 static int
@@ -1748,7 +1750,7 @@ zio_read_gang (blkptr_t * bp, grub_zfs_endian_t endian, dva_t * dva, void *buf,
 
   for (i = 0; i < SPA_GBH_NBLKPTRS; i++)
     {
-      if (zio_gb->zg_blkptr[i].blk_birth == 0)
+      if (BP_IS_HOLE(&zio_gb->zg_blkptr[i]))
 	continue;
 
       err = zio_read_data (&zio_gb->zg_blkptr[i], endian, buf, data);
diff --git a/include/grub/zfs/spa.h b/include/grub/zfs/spa.h
index 7edb8ab..df43b6b 100644
--- a/include/grub/zfs/spa.h
+++ b/include/grub/zfs/spa.h
@@ -279,7 +279,9 @@ typedef struct blkptr {
 
 #define	BP_IDENTITY(bp)		(&(bp)->blk_dva[0])
 #define	BP_IS_GANG(bp)		DVA_GET_GANG(BP_IDENTITY(bp))
-#define	BP_IS_HOLE(bp)		((bp)->blk_birth == 0)
+#define	DVA_IS_EMPTY(dva)	((dva)->dva_word[0] == 0ULL && \
+				(dva)->dva_word[1] == 0ULL)
+#define	BP_IS_HOLE(bp)		DVA_IS_EMPTY(BP_IDENTITY(bp))
 
 /* BP_IS_RAIDZ(bp) assumes no block compression */
 #define	BP_IS_RAIDZ(bp)		(DVA_GET_ASIZE(&(bp)->blk_dva[0]) > \
>From c9ca44d13eddc6e44de5caa166bda1a89fbddfc0 Mon Sep 17 00:00:00 2001
From: Toomas Soome <tsoome@me.com>
Date: Thu, 16 Apr 2015 08:24:38 +0300
Subject: zfs extensible_dataset and large_blocks feature support
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

large blocks basically use extensible dataset feature, or to be exact,
setting recordsize above 128k will trigger large_block feature to be
enabled and storing such blocks is using feature extensible dataset. so
the extensible dataset is prerequisite.

Changes implement read support extensible datasetâ?¦ instead of fixed DMU
types they dont specify type, making it possible to use fat zap objects
from bonus area.

Origin: upstream, http://git.savannah.gnu.org/cgit/grub.git/commit/?id=cad5cc0f5d3d3630ccfbe242552958b13f2120d6
Last-Update: 2016-01-22

Patch-Name: zfs-extensible-dataset-large-blocks.patch
---
 grub-core/fs/zfs/zfs.c | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c
index d33424c..9ac0759 100644
--- a/grub-core/fs/zfs/zfs.c
+++ b/grub-core/fs/zfs/zfs.c
@@ -283,6 +283,8 @@ 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
 };
 
@@ -3072,7 +3074,7 @@ get_filesystem_dnode (dnode_end_t * mosmdn, char *fsname,
 
   grub_dprintf ("zfs", "alive\n");
 
-  err = dnode_get (mosmdn, objnum, DMU_OT_DSL_DIR, mdn, data);
+  err = dnode_get (mosmdn, objnum, 0, mdn, data);
   if (err)
     return err;
 
@@ -3105,7 +3107,7 @@ get_filesystem_dnode (dnode_end_t * mosmdn, char *fsname,
       if (err)
 	return err;
 
-      err = dnode_get (mosmdn, objnum, DMU_OT_DSL_DIR, mdn, data);
+      err = dnode_get (mosmdn, objnum, 0, mdn, data);
       if (err)
 	return err;
 
@@ -3260,8 +3262,7 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol,
 
   grub_dprintf ("zfs", "endian = %d\n", subvol->mdn.endian);
 
-  err = dnode_get (&(data->mos), headobj, DMU_OT_DSL_DATASET, &subvol->mdn,
-		   data);
+  err = dnode_get (&(data->mos), headobj, 0, &subvol->mdn, data);
   if (err)
     {
       grub_free (fsname);
@@ -3657,8 +3658,11 @@ zfs_mount (grub_device_t dev)
   if (ub->ub_version >= SPA_VERSION_FEATURES &&
       check_mos_features(&((objset_phys_t *) osp)->os_meta_dnode,ub_endian,
 			 data) != 0)
-    return NULL;
-	
+    {
+      grub_error (GRUB_ERR_BAD_FS, "Unsupported features in pool");
+      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);
@@ -3949,7 +3953,7 @@ fill_fs_info (struct grub_dirhook_info *info,
     {
       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, DMU_OT_DSL_DATASET, &mdn, data);
+      err = dnode_get (&(data->mos), headobj, 0, &mdn, data);
       if (err)
 	{
 	  grub_dprintf ("zfs", "failed here\n");
>From e6e24a1e97e1f5d7b1b9d9b8d3132d9f3510b2f6 Mon Sep 17 00:00:00 2001
From: Toomas Soome <tsoome@me.com>
Date: Thu, 16 Apr 2015 08:23:22 +0300
Subject: zfs: com.delphix:embedded_data feature support

Origin: upstream, http://git.savannah.gnu.org/cgit/grub.git/commit/?id=4a7ea4003bd9f39e9bf2ebadbe4ab38f8874be66
Last-Update: 2016-01-22

Patch-Name: zfs-embedded-data.patch
---
 grub-core/fs/zfs/zfs.c | 84 +++++++++++++++++++++++++++++++++++++++++---------
 include/grub/zfs/spa.h | 27 +++++++++++++---
 2 files changed, 93 insertions(+), 18 deletions(-)

diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c
index b01c34f..a95e7e3 100644
--- a/grub-core/fs/zfs/zfs.c
+++ b/grub-core/fs/zfs/zfs.c
@@ -282,6 +282,7 @@ grub_crypto_cipher_handle_t (*grub_zfs_load_key) (const struct grub_zfs_key *key
 static const char *spa_feature_names[] = {
   "org.illumos:lz4_compress",
   "com.delphix:hole_birth",
+  "com.delphix:embedded_data",
   NULL
 };
 
@@ -1800,6 +1801,39 @@ zio_read_data (blkptr_t * bp, grub_zfs_endian_t endian, void *buf,
 }
 
 /*
+ * 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.
  */
@@ -1817,12 +1851,26 @@ zio_read (blkptr_t *bp, grub_zfs_endian_t endian, void **buf,
   *buf = NULL;
 
   checksum = (grub_zfs_to_cpu64((bp)->blk_prop, endian) >> 40) & 0xff;
-  comp = (grub_zfs_to_cpu64((bp)->blk_prop, endian)>>32) & 0xff;
+  comp = (grub_zfs_to_cpu64((bp)->blk_prop, endian)>>32) & 0x7f;
   encrypted = ((grub_zfs_to_cpu64((bp)->blk_prop, endian) >> 60) & 3);
-  lsize = (BP_IS_HOLE(bp) ? 0 :
-	   (((grub_zfs_to_cpu64 ((bp)->blk_prop, endian) & 0xffff) + 1)
-	    << SPA_MINBLOCKSHIFT));
-  psize = get_psize (bp, endian);
+  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;
@@ -1846,23 +1894,31 @@ zio_read (blkptr_t *bp, grub_zfs_endian_t endian, void **buf,
     compbuf = *buf = grub_malloc (lsize);
 
   grub_dprintf ("zfs", "endian = %d\n", endian);
-  err = zio_read_data (bp, endian, compbuf, data);
+  if (BP_IS_EMBEDDED(bp))
+    err = decode_embedded_bp_compressed(bp, compbuf);
+  else
+    {
+      err = zio_read_data (bp, endian, compbuf, data);
+      grub_memset (compbuf, 0, ALIGN_UP (psize, 16) - psize);
+    }
   if (err)
     {
       grub_free (compbuf);
       *buf = NULL;
       return err;
     }
-  grub_memset (compbuf, 0, ALIGN_UP (psize, 16) - psize);
 
-  err = zio_checksum_verify (zc, checksum, endian,
-			     compbuf, psize);
-  if (err)
+  if (!BP_IS_EMBEDDED(bp))
     {
-      grub_dprintf ("zfs", "incorrect checksum\n");
-      grub_free (compbuf);
-      *buf = NULL;
-      return err;
+      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)
diff --git a/include/grub/zfs/spa.h b/include/grub/zfs/spa.h
index df43b6b..8dd1fa8 100644
--- a/include/grub/zfs/spa.h
+++ b/include/grub/zfs/spa.h
@@ -126,7 +126,7 @@ typedef struct zio_cksum {
  *	+-------+-------+-------+-------+-------+-------+-------+-------+
  * 5	|G|			 offset3				|
  *	+-------+-------+-------+-------+-------+-------+-------+-------+
- * 6	|BDX|lvl| type	| cksum | comp	|     PSIZE	|     LSIZE	|
+ * 6	|BDX|lvl| type	| cksum |E| comp|     PSIZE	|     LSIZE	|
  *	+-------+-------+-------+-------+-------+-------+-------+-------+
  * 7	|			padding					|
  *	+-------+-------+-------+-------+-------+-------+-------+-------+
@@ -160,7 +160,8 @@ typedef struct zio_cksum {
  * G		gang block indicator
  * B		byteorder (endianness)
  * D		dedup
- * X		unused
+ * X		encryption
+ * E		blkptr_t contains embedded data
  * lvl		level of indirection
  * type		DMU object type
  * phys birth	txg of block allocation; zero if same as logical birth txg
@@ -203,8 +204,8 @@ typedef struct blkptr {
 #define	BP_SET_LSIZE(bp, x)	\
 	BF64_SET_SB((bp)->blk_prop, 0, 16, SPA_MINBLOCKSHIFT, 1, x)
 
-#define	BP_GET_COMPRESS(bp)		BF64_GET((bp)->blk_prop, 32, 8)
-#define	BP_SET_COMPRESS(bp, x)		BF64_SET((bp)->blk_prop, 32, 8, x)
+#define	BP_GET_COMPRESS(bp)		BF64_GET((bp)->blk_prop, 32, 7)
+#define	BP_SET_COMPRESS(bp, x)		BF64_SET((bp)->blk_prop, 32, 7, x)
 
 #define	BP_GET_CHECKSUM(bp)		BF64_GET((bp)->blk_prop, 40, 8)
 #define	BP_SET_CHECKSUM(bp, x)		BF64_SET((bp)->blk_prop, 40, 8, x)
@@ -215,6 +216,8 @@ typedef struct blkptr {
 #define	BP_GET_LEVEL(bp)		BF64_GET((bp)->blk_prop, 56, 5)
 #define	BP_SET_LEVEL(bp, x)		BF64_SET((bp)->blk_prop, 56, 5, x)
 
+#define	BP_IS_EMBEDDED(bp)		BF64_GET((bp)->blk_prop, 39, 1)
+
 #define	BP_GET_PROP_BIT_61(bp)		BF64_GET((bp)->blk_prop, 61, 1)
 #define	BP_SET_PROP_BIT_61(bp, x)	BF64_SET((bp)->blk_prop, 61, 1, x)
 
@@ -277,6 +280,22 @@ typedef struct blkptr {
 	(zcp)->zc_word[3] = w3;			\
 }
 
+#define	BPE_GET_ETYPE(bp)	BP_GET_CHECKSUM(bp)
+#define	BPE_GET_LSIZE(bp)	\
+	BF64_GET_SB((bp)->blk_prop, 0, 25, 0, 1)
+#define	BPE_GET_PSIZE(bp)	\
+	BF64_GET_SB((bp)->blk_prop, 25, 7, 0, 1)
+
+typedef enum bp_embedded_type {
+  BP_EMBEDDED_TYPE_DATA,
+  NUM_BP_EMBEDDED_TYPES
+} bp_embedded_type_t;
+
+#define	BPE_NUM_WORDS	14
+#define	BPE_PAYLOAD_SIZE	(BPE_NUM_WORDS * sizeof(grub_uint64_t))
+#define	BPE_IS_PAYLOADWORD(bp, wp)	\
+	((wp) != &(bp)->blk_prop && (wp) != &(bp)->blk_birth)
+
 #define	BP_IDENTITY(bp)		(&(bp)->blk_dva[0])
 #define	BP_IS_GANG(bp)		DVA_GET_GANG(BP_IDENTITY(bp))
 #define	DVA_IS_EMPTY(dva)	((dva)->dva_word[0] == 0ULL && \
>From 95593bb11dd80d673164e054edea8cc26260f915 Mon Sep 17 00:00:00 2001
From: Vladimir Serbinenko <phcoder@gmail.com>
Date: Sat, 24 Jan 2015 20:57:26 +0100
Subject: zfs: Fix disk-matching logic.

Reported by: Tim Chase <dweeezil>

Origin: upstream, http://git.savannah.gnu.org/cgit/grub.git/commit/?id=12a9c5516b94888db0a4502946242e3b14709f
Last-Update: 2016-01-22

Patch-Name: zfs-disk-matching.patch
---
 grub-core/fs/zfs/zfs.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c
index cfb25c0..e00a980 100644
--- a/grub-core/fs/zfs/zfs.c
+++ b/grub-core/fs/zfs/zfs.c
@@ -252,7 +252,6 @@ struct grub_zfs_data
 
   uberblock_t current_uberblock;
 
-  int mounted;
   grub_uint64_t guid;
 };
 
@@ -957,7 +956,7 @@ nvpair_value (const char *nvp,char **val,
 static grub_err_t
 check_pool_label (struct grub_zfs_data *data,
 		  struct grub_zfs_device_desc *diskdesc,
-		  int *inserted)
+		  int *inserted, int original)
 {
   grub_uint64_t pool_state, txg = 0;
   char *nvlist,*features;
@@ -1081,11 +1080,12 @@ check_pool_label (struct grub_zfs_data *data,
 
   grub_dprintf ("zfs", "check 11 passed\n");
 
-  if (data->mounted && data->guid != poolguid)
-    return grub_error (GRUB_ERR_BAD_FS, "another zpool");
-  else
+  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);
@@ -1186,7 +1186,7 @@ scan_disk (grub_device_t dev, struct grub_zfs_data *data,
 	}
       grub_dprintf ("zfs", "label ok %d\n", label);
 
-      err = check_pool_label (data, &desc, inserted);
+      err = check_pool_label (data, &desc, inserted, original);
       if (err || !*inserted)
 	{
 	  grub_errno = GRUB_ERR_NONE;
@@ -3606,8 +3606,6 @@ zfs_mount (grub_device_t dev)
 					 ub_endian) >> 63) & 1;
   grub_free (osp);
 
-  data->mounted = 1;
-
   return data;
 }
 

Reply to: