svn commit: r354590 - in stable/12: stand/libsa/zfs sys/cddl/boot/zfs

Toomas Soome tsoome at FreeBSD.org
Sun Nov 10 09:32:18 UTC 2019


Author: tsoome
Date: Sun Nov 10 09:32:17 2019
New Revision: 354590
URL: https://svnweb.freebsd.org/changeset/base/354590

Log:
  MFC r354279:
  loader: calculate physical vdev psize from asize
  
  Since physical device asize is calculated from psize and the asize is stored
  in pool label, we can use asize to set the value of psize, which is used to
  calculate the location of the pool labels.

Modified:
  stable/12/stand/libsa/zfs/zfsimpl.c
  stable/12/sys/cddl/boot/zfs/zfsimpl.h
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/stand/libsa/zfs/zfsimpl.c
==============================================================================
--- stable/12/stand/libsa/zfs/zfsimpl.c	Sun Nov 10 09:28:18 2019	(r354589)
+++ stable/12/stand/libsa/zfs/zfsimpl.c	Sun Nov 10 09:32:17 2019	(r354590)
@@ -1102,7 +1102,7 @@ vdev_init_from_nvlist(const unsigned char *nvlist, vde
     vdev_t **vdevp, int is_newer)
 {
 	int rc;
-	uint64_t guid, id, ashift, nparity;
+	uint64_t guid, id, ashift, asize, nparity;
 	const char *type;
 	const char *path;
 	vdev_t *vdev, *kid;
@@ -1181,6 +1181,11 @@ vdev_init_from_nvlist(const unsigned char *nvlist, vde
 		} else {
 			vdev->v_ashift = 0;
 		}
+		if (nvlist_find(nvlist, ZPOOL_CONFIG_ASIZE,
+		    DATA_TYPE_UINT64, NULL, &asize) == 0) {
+			vdev->v_psize = asize +
+			    VDEV_LABEL_START_SIZE + VDEV_LABEL_END_SIZE;
+		}
 		if (nvlist_find(nvlist, ZPOOL_CONFIG_NPARITY,
 			DATA_TYPE_UINT64, NULL, &nparity) == 0) {
 			vdev->v_nparity = nparity;
@@ -1547,7 +1552,6 @@ vdev_probe(vdev_phys_read_t *_read, void *read_priv, s
 	uint64_t guid;
 	uint64_t best_txg = 0;
 	uint64_t pool_txg, pool_guid;
-	uint64_t psize;
 	const char *pool_name;
 	const unsigned char *vdevs;
 	const unsigned char *features;
@@ -1562,17 +1566,17 @@ vdev_probe(vdev_phys_read_t *_read, void *read_priv, s
 	memset(&vtmp, 0, sizeof(vtmp));
 	vtmp.v_phys_read = _read;
 	vtmp.v_read_priv = read_priv;
-	psize = P2ALIGN(ldi_get_size(read_priv),
+	vtmp.v_psize = P2ALIGN(ldi_get_size(read_priv),
 	    (uint64_t)sizeof (vdev_label_t));
 
 	/* Test for minimum pool size. */
-	if (psize < SPA_MINDEVSIZE)
+	if (vtmp.v_psize < SPA_MINDEVSIZE)
 		return (EIO);
 
 	tmp_label = zfs_alloc(sizeof(vdev_phys_t));
 
 	for (l = 0; l < VDEV_LABELS; l++) {
-		off = vdev_label_offset(psize, l,
+		off = vdev_label_offset(vtmp.v_psize, l,
 		    offsetof(vdev_label_t, vl_vdev_phys));
 
 		BP_ZERO(&bp);
@@ -1595,8 +1599,20 @@ vdev_probe(vdev_phys_read_t *_read, void *read_priv, s
 			continue;
 
 		if (best_txg <= pool_txg) {
+			uint64_t asize;
+
 			best_txg = pool_txg;
 			memcpy(vdev_label, tmp_label, sizeof (vdev_phys_t));
+
+			/*
+			 * Use asize from pool config. We need this
+			 * because we can get bad value from BIOS.
+			 */
+			if (nvlist_find(nvlist, ZPOOL_CONFIG_ASIZE,
+			    DATA_TYPE_UINT64, NULL, &asize) == 0) {
+				vtmp.v_psize = asize +
+				    VDEV_LABEL_START_SIZE + VDEV_LABEL_END_SIZE;
+			}
 		}
 	}
 
@@ -1716,6 +1732,7 @@ vdev_probe(vdev_phys_read_t *_read, void *read_priv, s
 		vdev->v_phys_read = _read;
 		vdev->v_read_priv = read_priv;
 		vdev->v_state = VDEV_STATE_HEALTHY;
+		vdev->v_psize = vtmp.v_psize;
 	} else {
 		printf("ZFS: inconsistent nvlist contents\n");
 		return (EIO);
@@ -1735,7 +1752,7 @@ vdev_probe(vdev_phys_read_t *_read, void *read_priv, s
 	up = (const struct uberblock *)upbuf;
 	for (l = 0; l < VDEV_LABELS; l++) {
 		for (i = 0; i < VDEV_UBERBLOCK_COUNT(vdev); i++) {
-			off = vdev_label_offset(psize, l,
+			off = vdev_label_offset(vdev->v_psize, l,
 			    VDEV_UBERBLOCK_OFFSET(vdev, i));
 			BP_ZERO(&bp);
 			DVA_SET_OFFSET(&bp.blk_dva[0], off);

Modified: stable/12/sys/cddl/boot/zfs/zfsimpl.h
==============================================================================
--- stable/12/sys/cddl/boot/zfs/zfsimpl.h	Sun Nov 10 09:28:18 2019	(r354589)
+++ stable/12/sys/cddl/boot/zfs/zfsimpl.h	Sun Nov 10 09:32:17 2019	(r354590)
@@ -1660,7 +1660,8 @@ typedef struct vdev {
 	vdev_list_t	v_children;	/* children of this vdev */
 	const char	*v_name;	/* vdev name */
 	uint64_t	v_guid;		/* vdev guid */
-	int		v_id;		/* index in parent */
+	uint64_t	v_id;		/* index in parent */
+	uint64_t	v_psize;	/* physical device capacity */
 	int		v_ashift;	/* offset to block shift */
 	int		v_nparity;	/* # parity for raidz */
 	struct vdev	*v_top;		/* parent vdev */


More information about the svn-src-stable-12 mailing list