Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 10 Jul 2013 11:02:00 +0200
From:      =?utf-8?Q?Dag-Erling_Sm=C3=B8rgrav?= <des@des.no>
To:        freebsd-fs@freebsd.org, freebsd-hackers@freebsd.org
Cc:        ivoras@freebsd.org
Subject:   Make ZFS use the physical sector size when computing initial ashift
Message-ID:  <86zjtupz3r.fsf@nine.des.no>

next in thread | raw e-mail | index | archive | help
--=-=-=
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

The attached patch causes ZFS to base the minimum transfer size for a
new vdev on the GEOM provider's stripesize (physical sector size) rather
than sectorsize (logical sector size), provided that stripesize is a
power of two larger than sectorsize and smaller than or equal to
VDEV_PAD_SIZE.  This should eliminate the need for ivoras@'s gnop trick
when creating ZFS pools on Advanced Format drives.

DES
--=20
Dag-Erling Sm=C3=B8rgrav - des@des.no


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment; filename=zfs-vdev-stripesize.diff

Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
===================================================================
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c	(revision 253138)
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c	(working copy)
@@ -578,6 +578,7 @@
 {
 	struct g_provider *pp;
 	struct g_consumer *cp;
+	u_int sectorsize;
 	size_t bufsize;
 	int error;
 
@@ -661,8 +662,21 @@
 
 	/*
 	 * Determine the device's minimum transfer size.
+	 *
+	 * This is a bit of a hack.  For performance reasons, we would
+	 * prefer to use the physical sector size (reported by GEOM as
+	 * stripesize) as minimum transfer size.  However, doing so
+	 * unconditionally would break existing vdevs.  Therefore, we
+	 * compute ashift based on stripesize when the vdev isn't already
+	 * part of a pool (vdev_asize == 0), and sectorsize otherwise.
 	 */
-	*ashift = highbit(MAX(pp->sectorsize, SPA_MINBLOCKSIZE)) - 1;
+	if (vd->vdev_asize == 0 && pp->stripesize > pp->sectorsize &&
+	    ISP2(pp->stripesize) && pp->stripesize <= VDEV_PAD_SIZE) {
+		sectorsize = pp->stripesize;
+	} else {
+		sectorsize = pp->sectorsize;
+	}
+	*ashift = highbit(MAX(sectorsize, SPA_MINBLOCKSIZE)) - 1;
 
 	/*
 	 * Clear the nowritecache settings, so that on a vdev_reopen()

--=-=-=--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?86zjtupz3r.fsf>