changeset 18833:f69311ba75b3

loader: Use the actual struct devdesc at the start of all *_devdesc structs illumos issue #9275
author Toomas Soome <tsoome@me.com>
date Tue, 13 Mar 2018 11:58:56 +0200
parents 365f79a66849
children 55534ee72366
files usr/src/boot/sys/boot/common/disk.c usr/src/boot/sys/boot/common/disk.h usr/src/boot/sys/boot/efi/libefi/efipart.c usr/src/boot/sys/boot/efi/libefi/efizfs.c usr/src/boot/sys/boot/efi/loader/main.c usr/src/boot/sys/boot/i386/gptzfsboot/zfsboot.c usr/src/boot/sys/boot/i386/libi386/bioscd.c usr/src/boot/sys/boot/i386/libi386/biosdisk.c usr/src/boot/sys/boot/i386/libi386/bootinfo32.c usr/src/boot/sys/boot/i386/libi386/devicename.c usr/src/boot/sys/boot/i386/libi386/libi386.h usr/src/boot/sys/boot/i386/libi386/linux.c usr/src/boot/sys/boot/i386/loader/chain.c usr/src/boot/sys/boot/i386/loader/main.c usr/src/boot/sys/boot/ofw/libofw/devicename.c usr/src/boot/sys/boot/ofw/libofw/libofw.h usr/src/boot/sys/boot/sparc64/loader/main.c usr/src/boot/sys/boot/uboot/common/main.c usr/src/boot/sys/boot/uboot/lib/devicename.c usr/src/boot/sys/boot/uboot/lib/disk.c usr/src/boot/sys/boot/uboot/lib/libuboot.h usr/src/boot/sys/boot/userboot/userboot/devicename.c usr/src/boot/sys/boot/userboot/userboot/main.c usr/src/boot/sys/boot/userboot/userboot/userboot_disk.c usr/src/boot/sys/boot/zfs/libzfs.h usr/src/boot/sys/boot/zfs/zfs.c
diffstat 26 files changed, 190 insertions(+), 193 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/boot/sys/boot/common/disk.c	Sat Mar 24 18:13:39 2018 +0200
+++ b/usr/src/boot/sys/boot/common/disk.c	Tue Mar 13 11:58:56 2018 +0200
@@ -84,7 +84,7 @@
 	struct open_disk *od;
 
 	dev = (struct disk_devdesc *)d;
-	od = (struct open_disk *)dev->d_opendata;
+	od = (struct open_disk *)dev->dd.d_opendata;
 
 	/*
 	 * The strategy function assumes the offset is in units of 512 byte
@@ -96,7 +96,7 @@
 	 * As the GPT backup partition is located at the end of the disk,
 	 * to avoid reading past disk end, flag bcache not to use RA.
 	 */
-	return (dev->d_dev->dv_strategy(dev, F_READ | F_NORA , offset,
+	return (dev->dd.d_dev->dv_strategy(dev, F_READ | F_NORA , offset,
 	    blocks * od->sectorsize, (char *)buf, NULL));
 }
 
@@ -112,7 +112,7 @@
 	int ret = 0;
 
 	pa = (struct print_args *)arg;
-	od = (struct open_disk *)pa->dev->d_opendata;
+	od = (struct open_disk *)pa->dev->dd.d_opendata;
 	sprintf(line, "  %s%s: %s", pa->prefix, pname,
 	    parttype2str(part->type));
 	if (pa->verbose)
@@ -125,8 +125,8 @@
 		return (ret);
 	if (part->type == PART_FREEBSD || part->type == PART_SOLARIS2) {
 		/* Open slice with BSD or VTOC label */
-		dev.d_dev = pa->dev->d_dev;
-		dev.d_unit = pa->dev->d_unit;
+		dev.dd.d_dev = pa->dev->dd.d_dev;
+		dev.dd.d_unit = pa->dev->dd.d_unit;
 		dev.d_slice = part->index;
 		dev.d_partition = -1;
 		if (disk_open(&dev, part->end - part->start + 1,
@@ -162,7 +162,7 @@
 	struct print_args pa;
 
 	/* Disk should be opened */
-	od = (struct open_disk *)dev->d_opendata;
+	od = (struct open_disk *)dev->dd.d_opendata;
 	pa.dev = dev;
 	pa.prefix = prefix;
 	pa.verbose = verbose;
@@ -175,8 +175,8 @@
 	struct open_disk *od;
 	int ret;
 
-	od = (struct open_disk *)dev->d_opendata;
-	ret = dev->d_dev->dv_strategy(dev, F_READ, dev->d_offset + offset,
+	od = (struct open_disk *)dev->dd.d_opendata;
+	ret = dev->dd.d_dev->dv_strategy(dev, F_READ, dev->d_offset + offset,
 	    blocks * od->sectorsize, buf, NULL);
 
 	return (ret);
@@ -188,8 +188,8 @@
 	struct open_disk *od;
 	int ret;
 
-	od = (struct open_disk *)dev->d_opendata;
-	ret = dev->d_dev->dv_strategy(dev, F_WRITE, dev->d_offset + offset,
+	od = (struct open_disk *)dev->dd.d_opendata;
+	ret = dev->dd.d_dev->dv_strategy(dev, F_WRITE, dev->d_offset + offset,
 	    blocks * od->sectorsize, buf, NULL);
 
 	return (ret);
@@ -198,7 +198,7 @@
 int
 disk_ioctl(struct disk_devdesc *dev, u_long cmd, void *data)
 {
-	struct open_disk *od = dev->d_opendata;
+	struct open_disk *od = dev->dd.d_opendata;
 
 	if (od == NULL)
 		return (ENOTTY);
@@ -242,7 +242,7 @@
 		DEBUG("no memory");
 		return (ENOMEM);
 	}
-	dev->d_opendata = od;
+	dev->dd.d_opendata = od;
 	od->entrysize = 0;
 	od->mediasize = mediasize;
 	od->sectorsize = sectorsize;
@@ -353,7 +353,7 @@
 {
 	struct open_disk *od;
 
-	od = (struct open_disk *)dev->d_opendata;
+	od = (struct open_disk *)dev->dd.d_opendata;
 	DEBUG("%s closed => %p", disk_fmtdev(dev), od);
 	ptable_close(od->table);
 	free(od);
@@ -366,7 +366,7 @@
 	static char buf[128];
 	char *cp;
 
-	cp = buf + sprintf(buf, "%s%d", dev->d_dev->dv_name, dev->d_unit);
+	cp = buf + sprintf(buf, "%s%d", dev->dd.d_dev->dv_name, dev->dd.d_unit);
 	if (dev->d_slice >= 0) {
 #ifdef LOADER_GPT_SUPPORT
 		if (dev->d_partition == 255) {
@@ -428,7 +428,7 @@
 
 	if (*cp != '\0' && *cp != ':')
 		return (EINVAL);
-	dev->d_unit = unit;
+	dev->dd.d_unit = unit;
 	dev->d_slice = slice;
 	dev->d_partition = partition;
 	if (path != NULL)
--- a/usr/src/boot/sys/boot/common/disk.h	Sat Mar 24 18:13:39 2018 +0200
+++ b/usr/src/boot/sys/boot/common/disk.h	Tue Mar 13 11:58:56 2018 +0200
@@ -86,10 +86,7 @@
 
 /* Note: Must match the 'struct devdesc' in stand.h */
 struct disk_devdesc {
-	struct devsw	*d_dev;
-	int		d_type;
-	int		d_unit;
-	void		*d_opendata;
+	struct devdesc	dd;
 	int		d_slice;
 	int		d_partition;
 	uint64_t	d_offset;
--- a/usr/src/boot/sys/boot/efi/libefi/efipart.c	Sat Mar 24 18:13:39 2018 +0200
+++ b/usr/src/boot/sys/boot/efi/libefi/efipart.c	Tue Mar 13 11:58:56 2018 +0200
@@ -743,8 +743,8 @@
 				continue;
 
 			pd->pd_blkio = blkio;
-			pd_dev.d_dev = dev;
-			pd_dev.d_unit = pd->pd_unit;
+			pd_dev.dd.d_dev = dev;
+			pd_dev.dd.d_unit = pd->pd_unit;
 			pd_dev.d_slice = -1;
 			pd_dev.d_partition = -1;
 			ret = disk_open(&pd_dev, blkio->Media->BlockSize *
@@ -819,7 +819,7 @@
 	if (pd->pd_bcache == NULL)
 		pd->pd_bcache = bcache_allocate();
 
-	if (dev->d_dev->dv_type == DEVT_DISK) {
+	if (dev->dd.d_dev->dv_type == DEVT_DISK) {
 		int rc;
 
 		rc = disk_open(dev,
@@ -858,7 +858,7 @@
 		bcache_free(pd->pd_bcache);
 		pd->pd_bcache = NULL;
 	}
-	if (dev->d_dev->dv_type == DEVT_DISK)
+	if (dev->dd.d_dev->dv_type == DEVT_DISK)
 		return (disk_close(dev));
 	return (0);
 }
@@ -878,7 +878,7 @@
 	if (pd == NULL)
 		return (EINVAL);
 
-	if (dev->d_dev->dv_type == DEVT_DISK) {
+	if (dev->dd.d_dev->dv_type == DEVT_DISK) {
 		rc = disk_ioctl(dev, cmd, data);
 		if (rc != ENOTTY)
 			return (rc);
@@ -965,7 +965,7 @@
 	bcd.dv_devdata = devdata;
 	bcd.dv_cache = pd->pd_bcache;
 
-	if (dev->d_dev->dv_type == DEVT_DISK) {
+	if (dev->dd.d_dev->dv_type == DEVT_DISK) {
 		daddr_t offset;
 
 		offset = dev->d_offset * pd->pd_blkio->Media->BlockSize;
@@ -1009,7 +1009,7 @@
 	 * partition.
 	 */
 	disk_blocks = 0;
-	if (dev->d_dev->dv_type == DEVT_DISK) {
+	if (dev->dd.d_dev->dv_type == DEVT_DISK) {
 		if (disk_ioctl(dev, DIOCGMEDIASIZE, &disk_blocks) == 0) {
 			/* DIOCGMEDIASIZE does return bytes. */
 			disk_blocks /= blkio->Media->BlockSize;
--- a/usr/src/boot/sys/boot/efi/libefi/efizfs.c	Sat Mar 24 18:13:39 2018 +0200
+++ b/usr/src/boot/sys/boot/efi/libefi/efizfs.c	Tue Mar 13 11:58:56 2018 +0200
@@ -29,6 +29,7 @@
 
 #include <sys/param.h>
 #include <sys/disk.h>
+#include <stand.h>
 
 #include <libzfs.h>
 
--- a/usr/src/boot/sys/boot/efi/loader/main.c	Sat Mar 24 18:13:39 2018 +0200
+++ b/usr/src/boot/sys/boot/efi/loader/main.c	Tue Mar 13 11:58:56 2018 +0200
@@ -186,9 +186,9 @@
 	if (pool_guid != 0) {
 		struct zfs_devdesc currdev;
 
-		currdev.d_dev = &zfs_dev;
-		currdev.d_unit = 0;
-		currdev.d_type = currdev.d_dev->dv_type;
+		currdev.dd.d_dev = &zfs_dev;
+		currdev.dd.d_unit = 0;
+		currdev.dd.d_type = currdev.dd.d_dev->dv_type;
 		currdev.pool_guid = pool_guid;
 		currdev.root_guid = 0;
 		devname = efi_fmtdev(&currdev);
@@ -205,9 +205,9 @@
 	STAILQ_FOREACH(dp, pdi_list, pd_link) {
 		struct disk_devdesc currdev;
 
-		currdev.d_dev = &efipart_hddev;
-		currdev.d_type = currdev.d_dev->dv_type;
-		currdev.d_unit = dp->pd_unit;
+		currdev.dd.d_dev = &efipart_hddev;
+		currdev.dd.d_type = currdev.dd.d_dev->dv_type;
+		currdev.dd.d_unit = dp->pd_unit;
 		currdev.d_slice = -1;
 		currdev.d_partition = -1;
 
--- a/usr/src/boot/sys/boot/i386/gptzfsboot/zfsboot.c	Sat Mar 24 18:13:39 2018 +0200
+++ b/usr/src/boot/sys/boot/i386/gptzfsboot/zfsboot.c	Tue Mar 13 11:58:56 2018 +0200
@@ -176,13 +176,13 @@
 
     disk_parsedev(&devdesc, boot_devname+4, NULL);
 
-    bootdev = MAKEBOOTDEV(dev_maj[devdesc.d_type], devdesc.d_slice + 1,
-	devdesc.d_unit, devdesc.d_partition >= 0? devdesc.d_partition:0xff);
+    bootdev = MAKEBOOTDEV(dev_maj[DEVT_DISK], devdesc.d_slice + 1,
+	devdesc.dd.d_unit, devdesc.d_partition >= 0? devdesc.d_partition:0xff);
 
     /*
      * zfs_fmtdev() can be called only after dv_init
      */
-    if (bdev != NULL && bdev->d_type == DEVT_ZFS) {
+    if (bdev != NULL && bdev->dd.d_type == DEVT_ZFS) {
 	/* set up proper device name string for ZFS */
 	strncpy(boot_devname, zfs_fmtdev(bdev), sizeof (boot_devname));
     }
@@ -373,7 +373,7 @@
     bootinfo.bi_esymtab = VTOP(p);
     bootinfo.bi_kernelname = VTOP(kname);
 
-    if (bdev->d_type == DEVT_ZFS) {
+    if (bdev->dd.d_type == DEVT_ZFS) {
 	zfsargs.size = sizeof(zfsargs);
 	zfsargs.pool = bdev->d_kind.zfs.pool_guid;
 	zfsargs.root = bdev->d_kind.zfs.root_guid;
@@ -409,15 +409,15 @@
     if (bdev != NULL)
 	free(bdev);
     bdev = ddesc;
-    if (bdev->d_type == DEVT_DISK) {
+    if (bdev->dd.d_type == DEVT_DISK) {
 	if (bdev->d_kind.biosdisk.partition == -1)
 	    part = 0xff;
 	else
 	    part = bdev->d_kind.biosdisk.partition;
-	bootdev = MAKEBOOTDEV(dev_maj[bdev->d_type],
+	bootdev = MAKEBOOTDEV(dev_maj[bdev->dd.d_type],
 	    bdev->d_kind.biosdisk.slice + 1,
-	    bdev->d_unit, part);
-	bootinfo.bi_bios_dev = bd_unit2bios(bdev->d_unit);
+	    bdev->dd.d_unit, part);
+	bootinfo.bi_bios_dev = bd_unit2bios(bdev->dd.d_unit);
     }
     setenv("currdev", root, 1);
     free(root);
@@ -638,8 +638,8 @@
 	if (pool_guid != 0 && bdev == NULL) {
 		bdev = malloc(sizeof (struct i386_devdesc));
 		bzero(bdev, sizeof (struct i386_devdesc));
-		bdev->d_type = DEVT_ZFS;
-		bdev->d_dev = &zfs_dev;
+		bdev->dd.d_type = DEVT_ZFS;
+		bdev->dd.d_dev = &zfs_dev;
 		bdev->d_kind.zfs.pool_guid = pool_guid;
 
 		/*
--- a/usr/src/boot/sys/boot/i386/libi386/bioscd.c	Sat Mar 24 18:13:39 2018 +0200
+++ b/usr/src/boot/sys/boot/i386/libi386/bioscd.c	Tue Mar 13 11:58:56 2018 +0200
@@ -89,7 +89,7 @@
 } bcinfo [MAXBCDEV];
 static int nbcinfo = 0;
 
-#define	BC(dev)	(bcinfo[(dev)->d_unit])
+#define	BC(dev)	(bcinfo[(dev)->dd.d_unit])
 
 static int	bc_read(int unit, daddr_t dblk, int blks, caddr_t dest);
 static int	bc_init(void);
@@ -211,7 +211,7 @@
 	va_start(ap, f);
 	dev = va_arg(ap, struct i386_devdesc *);
 	va_end(ap);
-	if (dev->d_unit >= nbcinfo) {
+	if (dev->dd.d_unit >= nbcinfo) {
 		DEBUG("attempt to open nonexistent disk");
 		return(ENXIO);
 	}
@@ -271,7 +271,7 @@
 	if ((rw & F_MASK) != F_READ)
 		return(EROFS);
 	dev = (struct i386_devdesc *)devdata;
-	unit = dev->d_unit;
+	unit = dev->dd.d_unit;
 	blks = size / BIOSCD_SECSIZE;
 	if (dblk % (BIOSCD_SECSIZE / DEV_BSIZE) != 0)
 		return (EINVAL);
@@ -429,7 +429,7 @@
     int major;
     int rootdev;
 
-    unit = dev->d_unit;
+    unit = dev->dd.d_unit;
     biosdev = bc_unit2bios(unit);
     DEBUG("unit %d BIOS device %d", unit, biosdev);
     if (biosdev == -1)				/* not a BIOS device */
--- a/usr/src/boot/sys/boot/i386/libi386/biosdisk.c	Sat Mar 24 18:13:39 2018 +0200
+++ b/usr/src/boot/sys/boot/i386/libi386/biosdisk.c	Tue Mar 13 11:58:56 2018 +0200
@@ -1,4 +1,4 @@
-/*-
+/*
  * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
  * Copyright (c) 2012 Andrey V. Elsukov <ae@FreeBSD.org>
  * All rights reserved.
@@ -91,7 +91,7 @@
 } bdinfo [MAXBDDEV];
 static int nbdinfo = 0;
 
-#define	BD(dev)		(bdinfo[(dev)->d_unit])
+#define	BD(dev)		(bdinfo[(dev)->dd.d_unit])
 
 static int bd_io(struct disk_devdesc *, daddr_t, int, caddr_t, int);
 static int bd_int13probe(struct bdinfo *bd);
@@ -307,8 +307,8 @@
 		if (ret != 0)
 			return (ret);
 
-		dev.d_dev = &biosdisk;
-		dev.d_unit = i;
+		dev.dd.d_dev = &biosdisk;
+		dev.dd.d_unit = i;
 		dev.d_slice = -1;
 		dev.d_partition = -1;
 		if (disk_open(&dev,
@@ -347,7 +347,7 @@
 	dev = va_arg(ap, struct disk_devdesc *);
 	va_end(ap);
 
-	if (dev->d_unit < 0 || dev->d_unit >= nbdinfo)
+	if (dev->dd.d_unit < 0 || dev->dd.d_unit >= nbdinfo)
 		return (EIO);
 	BD(dev).bd_open++;
 	if (BD(dev).bd_bcache == NULL)
@@ -360,10 +360,9 @@
 	 * During bd_probe() we tested if the mulitplication of bd_sectors
 	 * would overflow so it should be safe to perform here.
 	 */
-	disk.d_dev = dev->d_dev;
-	disk.d_type = dev->d_type;
-	disk.d_unit = dev->d_unit;
-	disk.d_opendata = NULL;
+	disk.dd.d_dev = dev->dd.d_dev;
+	disk.dd.d_type = dev->dd.d_type;
+	disk.dd.d_unit = dev->dd.d_unit;
 	disk.d_slice = -1;
 	disk.d_partition = -1;
 	disk.d_offset = 0;
@@ -693,12 +692,14 @@
 	if (result != 0 && result != 0x20) {
 		if (dowrite != 0) {
 			printf("%s%d: Write %d sector(s) from %p (0x%x) "
-			    "to %lld: 0x%x", dev->d_dev->dv_name, dev->d_unit,
-			    blks, dest, VTOP(dest), dblk, result);
+			    "to %lld: 0x%x", dev->dd.d_dev->dv_name,
+			    dev->dd.d_unit, blks, dest, VTOP(dest), dblk,
+			    result);
 		} else {
 			printf("%s%d: Read %d sector(s) from %lld to %p "
-			    "(0x%x): 0x%x", dev->d_dev->dv_name, dev->d_unit,
-			    blks, dblk, dest, VTOP(dest), result);
+			    "(0x%x): 0x%x", dev->dd.d_dev->dv_name,
+			    dev->dd.d_unit, blks, dblk, dest, VTOP(dest),
+			    result);
 	}
 
 	if (result != 0)
@@ -754,8 +755,8 @@
     int				i, unit;
 
     dev = (struct disk_devdesc *)d;
-    biosdev = bd_unit2bios(dev->d_unit);
-    DEBUG("unit %d BIOS device %d", dev->d_unit, biosdev);
+    biosdev = bd_unit2bios(dev->dd.d_unit);
+    DEBUG("unit %d BIOS device %d", dev->dd.d_unit, biosdev);
     if (biosdev == -1)				/* not a BIOS device */
 	return(-1);
     if (disk_open(dev, BD(dev).bd_sectors * BD(dev).bd_sectorsize,
@@ -766,7 +767,7 @@
 
     if (biosdev < 0x80) {
 	/* floppy (or emulated floppy) or ATAPI device */
-	if (bdinfo[dev->d_unit].bd_type == DT_ATAPI) {
+	if (bdinfo[dev->dd.d_unit].bd_type == DT_ATAPI) {
 	    /* is an ATAPI disk */
 	    major = WFDMAJOR;
 	} else {
--- a/usr/src/boot/sys/boot/i386/libi386/bootinfo32.c	Sat Mar 24 18:13:39 2018 +0200
+++ b/usr/src/boot/sys/boot/i386/libi386/bootinfo32.c	Tue Mar 13 11:58:56 2018 +0200
@@ -1,4 +1,4 @@
-/*-
+/*
  * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
  * All rights reserved.
  *
@@ -25,7 +25,6 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
 
 #include <stand.h>
 #include <sys/param.h>
@@ -169,25 +168,26 @@
     /* XXX - use a default bootdev of 0.  Is this ok??? */
     bootdevnr = 0;
 
-    switch(rootdev->d_type) {
+    switch(rootdev->dd.d_type) {
     case DEVT_CD:
 	    /* Pass in BIOS device number. */
-	    bi.bi_bios_dev = bc_unit2bios(rootdev->d_unit);
+	    bi.bi_bios_dev = bc_unit2bios(rootdev->dd.d_unit);
 	    bootdevnr = bc_getdev(rootdev);
 	    break;
 
     case DEVT_DISK:
 	/* pass in the BIOS device number of the current disk */
-	bi.bi_bios_dev = bd_unit2bios(rootdev->d_unit);
+	bi.bi_bios_dev = bd_unit2bios(rootdev->dd.d_unit);
 	bootdevnr = bd_getdev(rootdev);
 	break;
 
     case DEVT_NET:
     case DEVT_ZFS:
 	    break;
-	    
+
     default:
-	printf("WARNING - don't know how to boot from device type %d\n", rootdev->d_type);
+	printf("WARNING - don't know how to boot from device type %d\n",
+	    rootdev->dd.d_type);
     }
     if (bootdevnr == -1) {
 	printf("root device %s invalid\n", i386_fmtdev(rootdev));
--- a/usr/src/boot/sys/boot/i386/libi386/devicename.c	Sat Mar 24 18:13:39 2018 +0200
+++ b/usr/src/boot/sys/boot/i386/libi386/devicename.c	Tue Mar 13 11:58:56 2018 +0200
@@ -151,14 +151,14 @@
 			goto fail;
 		}
 
-		idev->d_unit = unit;
+		idev->dd.d_unit = unit;
 		if (path != NULL)
 			*path = (*cp == '\0') ? cp : cp + 1;
 		break;
 	}
 
-	idev->d_dev = dv;
-	idev->d_type = dv->dv_type;
+	idev->dd.d_dev = dv;
+	idev->dd.d_type = dv->dv_type;
 
 	if (dev != NULL)
 		*dev = idev;
@@ -178,7 +178,7 @@
 	struct i386_devdesc *dev = (struct i386_devdesc *)vdev;
 	static char buf[SPECNAMELEN + 1];
 
-	switch (dev->d_type) {
+	switch (dev->dd.d_type) {
 	case DEVT_NONE:
 		strlcpy(buf, "(no device)", sizeof (buf));
 		break;
@@ -190,8 +190,8 @@
 		return (zfs_fmtdev(vdev));
 
 	default:
-		snprintf(buf, sizeof (buf), "%s%d:", dev->d_dev->dv_name,
-		    dev->d_unit);
+		snprintf(buf, sizeof (buf), "%s%d:", dev->dd.d_dev->dv_name,
+		    dev->dd.d_unit);
 		break;
 	}
 	return (buf);
--- a/usr/src/boot/sys/boot/i386/libi386/libi386.h	Sat Mar 24 18:13:39 2018 +0200
+++ b/usr/src/boot/sys/boot/i386/libi386/libi386.h	Tue Mar 13 11:58:56 2018 +0200
@@ -34,20 +34,14 @@
  */
 /* Note: Must match the 'struct devdesc' in stand.h */
 struct i386_devdesc {
-    struct devsw	*d_dev;
-    int			d_type;
-    int			d_unit;
-    void		*d_opendata;
-    union 
-    {
-	struct 
-	{
+    struct devdesc	dd;
+    union {
+	struct {
 	    int		slice;
 	    int		partition;
 	    off_t	offset;
 	} biosdisk;
-	struct
-	{
+	struct {
 	    uint64_t	pool_guid;
 	    uint64_t	root_guid;
 	} zfs;
--- a/usr/src/boot/sys/boot/i386/libi386/linux.c	Sat Mar 24 18:13:39 2018 +0200
+++ b/usr/src/boot/sys/boot/i386/libi386/linux.c	Tue Mar 13 11:58:56 2018 +0200
@@ -292,7 +292,7 @@
 
 	i386_getdev((void **)(&rootdev), fp->f_name, NULL);
 	if (rootdev != NULL)
-		relocator_edx = bd_unit2bios(rootdev->d_unit);
+		relocator_edx = bd_unit2bios(rootdev->dd.d_unit);
 
 	/*
 	 * command line
--- a/usr/src/boot/sys/boot/i386/loader/chain.c	Sat Mar 24 18:13:39 2018 +0200
+++ b/usr/src/boot/sys/boot/i386/loader/chain.c	Tue Mar 13 11:58:56 2018 +0200
@@ -100,7 +100,7 @@
 	relocater_data[0].dest = 0x7C00;
 	relocater_data[0].size = size;
 
-	relocator_edx = bd_unit2bios(rootdev->d_unit);
+	relocator_edx = bd_unit2bios(rootdev->dd.d_unit);
 	relocator_esi = relocater_size;
 	relocator_ds = 0;
 	relocator_es = 0;
--- a/usr/src/boot/sys/boot/i386/loader/main.c	Sat Mar 24 18:13:39 2018 +0200
+++ b/usr/src/boot/sys/boot/i386/loader/main.c	Tue Mar 13 11:58:56 2018 +0200
@@ -225,18 +225,18 @@
     int				biosdev = -1;
 
     /* Assume we are booting from a BIOS disk by default */
-    new_currdev.d_dev = &biosdisk;
+    new_currdev.dd.d_dev = &biosdisk;
 
     /* new-style boot loaders such as pxeldr and cdldr */
     if (kargs->bootinfo == 0) {
         if ((kargs->bootflags & KARGS_FLAGS_CD) != 0) {
 	    /* we are booting from a CD with cdboot */
-	    new_currdev.d_dev = &bioscd;
-	    new_currdev.d_unit = bc_bios2unit(initial_bootdev);
+	    new_currdev.dd.d_dev = &bioscd;
+	    new_currdev.dd.d_unit = bc_bios2unit(initial_bootdev);
 	} else if ((kargs->bootflags & KARGS_FLAGS_PXE) != 0) {
 	    /* we are booting from pxeldr */
-	    new_currdev.d_dev = &pxedisk;
-	    new_currdev.d_unit = 0;
+	    new_currdev.dd.d_dev = &pxedisk;
+	    new_currdev.dd.d_unit = 0;
 	} else {
 	    /* we don't know what our boot device is */
 	    new_currdev.d_kind.biosdisk.slice = -1;
@@ -266,7 +266,7 @@
 	    new_currdev.d_kind.zfs.pool_guid = kargs->zfspool;
 	    new_currdev.d_kind.zfs.root_guid = 0;
 	}
-	new_currdev.d_dev = &zfs_dev;
+	new_currdev.dd.d_dev = &zfs_dev;
 #endif
     } else if ((initial_bootdev & B_MAGICMASK) != B_DEVMAGIC) {
 	/* The passed-in boot device is bad */
@@ -287,26 +287,19 @@
 	if ((biosdev == 0) && (B_TYPE(initial_bootdev) != 2))	/* biosdev doesn't match major */
 	    biosdev = 0x80 + B_UNIT(initial_bootdev);		/* assume harddisk */
     }
-    new_currdev.d_type = new_currdev.d_dev->dv_type;
+    new_currdev.dd.d_type = new_currdev.dd.d_dev->dv_type;
 
     /*
      * If we are booting off of a BIOS disk and we didn't succeed in determining
      * which one we booted off of, just use disk0: as a reasonable default.
      */
-    if ((new_currdev.d_type == biosdisk.dv_type) &&
-	((new_currdev.d_unit = bd_bios2unit(biosdev)) == -1)) {
+    if ((new_currdev.dd.d_type == biosdisk.dv_type) &&
+	((new_currdev.dd.d_unit = bd_bios2unit(biosdev)) == -1)) {
 	printf("Can't work out which disk we are booting from.\n"
 	       "Guessed BIOS device 0x%x not found by probes, defaulting to disk0:\n", biosdev);
-	new_currdev.d_unit = 0;
+	new_currdev.dd.d_unit = 0;
     }
 
-#ifdef LOADER_ZFS_SUPPORT
-#ifdef __FreeBSD__
-    if (new_currdev.d_type == DEVT_ZFS)
-	init_zfs_bootenv(zfs_fmtdev(&new_currdev));
-#endif
-#endif
-
     env_setenv("currdev", EV_VOLATILE, i386_fmtdev(&new_currdev),
 	       i386_setcurrdev, env_nounset);
     env_setenv("loaddev", EV_VOLATILE, i386_fmtdev(&new_currdev), env_noset,
--- a/usr/src/boot/sys/boot/ofw/libofw/devicename.c	Sat Mar 24 18:13:39 2018 +0200
+++ b/usr/src/boot/sys/boot/ofw/libofw/devicename.c	Tue Mar 13 11:58:56 2018 +0200
@@ -1,4 +1,4 @@
-/*-
+/*
  * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
  * All rights reserved.
  *
@@ -25,7 +25,6 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
 
 #include <stand.h>
 
@@ -113,9 +112,9 @@
 	return ENOMEM;
     }
     strcpy(idev->d_path, name);
-    idev->d_dev = dv;
-    idev->d_type = dv->dv_type;
-    if (idev->d_type == DEVT_ZFS) {
+    idev->dd.d_dev = dv;
+    idev->dd.d_type = dv->dv_type;
+    if (idev->dd.d_type == DEVT_ZFS) {
 	p = devspec + strlen(dv->dv_name);
 	err = zfs_parsedev((struct zfs_devdesc *)idev, p, path);
 	if (err != 0) {
--- a/usr/src/boot/sys/boot/ofw/libofw/libofw.h	Sat Mar 24 18:13:39 2018 +0200
+++ b/usr/src/boot/sys/boot/ofw/libofw/libofw.h	Tue Mar 13 11:58:56 2018 +0200
@@ -1,4 +1,4 @@
-/*-
+/*
  * Copyright (C) 2000 Benno Rice.
  * All rights reserved.
  *
@@ -29,12 +29,12 @@
 
 /* Note: Must match the 'struct devdesc' in stand.h */
 struct ofw_devdesc {
-	struct devsw	*d_dev;
-	int		d_type;
-	int		d_unit;
-	ihandle_t	d_handle;
+	struct devdesc	dd;
 	union {
-		char			d_path[256];
+		struct {
+			ihandle_t	d_handle;
+			char		d_path[256];
+		};
 		struct {
 			uint64_t	pool_guid;
 			uint64_t	root_guid;
--- a/usr/src/boot/sys/boot/sparc64/loader/main.c	Sat Mar 24 18:13:39 2018 +0200
+++ b/usr/src/boot/sys/boot/sparc64/loader/main.c	Tue Mar 13 11:58:56 2018 +0200
@@ -1,4 +1,4 @@
-/*-
+/*
  * Initial implementation:
  * Copyright (c) 2001 Robert Drehmel
  * All rights reserved.
@@ -6,7 +6,7 @@
  * As long as the above copyright statement and this notice remain
  * unchanged, you can do what ever you want with this file.
  */
-/*-
+/*
  * Copyright (c) 2008 - 2012 Marius Strobl <marius@FreeBSD.org>
  * All rights reserved.
  *
@@ -808,8 +808,8 @@
 	if (guid != 0) {
 		zfs_currdev.pool_guid = guid;
 		zfs_currdev.root_guid = 0;
-		zfs_currdev.d_dev = &zfs_dev;
-		zfs_currdev.d_type = zfs_currdev.d_dev->dv_type;
+		zfs_currdev.dd.d_dev = &zfs_dev;
+		zfs_currdev.dd.d_type = zfs_currdev.dd.d_dev->dv_type;
 	}
 }
 #endif /* LOADER_ZFS_SUPPORT */
--- a/usr/src/boot/sys/boot/uboot/common/main.c	Sat Mar 24 18:13:39 2018 +0200
+++ b/usr/src/boot/sys/boot/uboot/common/main.c	Tue Mar 13 11:58:56 2018 +0200
@@ -1,4 +1,4 @@
-/*-
+/*
  * Copyright (c) 2000 Benno Rice <benno@jeamland.net>
  * Copyright (c) 2000 Stephane Potvin <sepotvin@videotron.ca>
  * Copyright (c) 2007-2008 Semihalf, Rafal Jaworowski <raj@semihalf.com>
@@ -317,12 +317,12 @@
 		strcpy(partition, "<auto>");
 
 	printf("  Checking unit=%d slice=%s partition=%s...",
-	    currdev.d_unit, slice, partition);
+	    currdev.dd.d_unit, slice, partition);
 
 }
 
 static int
-probe_disks(int devidx, int load_type, int load_unit, int load_slice, 
+probe_disks(int devidx, int load_type, int load_unit, int load_slice,
     int load_partition)
 {
 	int open_result, unit;
@@ -337,8 +337,8 @@
 	if (load_type == -1) {
 		printf("  Probing all disk devices...\n");
 		/* Try each disk in succession until one works.  */
-		for (currdev.d_unit = 0; currdev.d_unit < UB_MAX_DEV;
-		     currdev.d_unit++) {
+		for (currdev.dd.d_unit = 0; currdev.dd.d_unit < UB_MAX_DEV;
+		     currdev.dd.d_unit++) {
 			print_disk_probe_info();
 			open_result = devsw[devidx]->dv_open(&f, &currdev);
 			if (open_result == 0) {
@@ -354,8 +354,8 @@
 		printf("  Probing all %s devices...\n", device_typename(load_type));
 		/* Try each disk of given type in succession until one works. */
 		for (unit = 0; unit < UB_MAX_DEV; unit++) {
-			currdev.d_unit = uboot_diskgetunit(load_type, unit);
-			if (currdev.d_unit == -1)
+			currdev.dd.d_unit = uboot_diskgetunit(load_type, unit);
+			if (currdev.dd.d_unit == -1)
 				break;
 			print_disk_probe_info();
 			open_result = devsw[devidx]->dv_open(&f, &currdev);
@@ -368,7 +368,7 @@
 		return (-1);
 	}
 
-	if ((currdev.d_unit = uboot_diskgetunit(load_type, load_unit)) != -1) {
+	if ((currdev.dd.d_unit = uboot_diskgetunit(load_type, load_unit)) != -1) {
 		print_disk_probe_info();
 		open_result = devsw[devidx]->dv_open(&f,&currdev);
 		if (open_result == 0) {
@@ -453,13 +453,13 @@
 
 		printf("Found U-Boot device: %s\n", devsw[i]->dv_name);
 
-		currdev.d_dev = devsw[i];
-		currdev.d_type = currdev.d_dev->dv_type;
-		currdev.d_unit = 0;
+		currdev.dd.d_dev = devsw[i];
+		currdev.dd.d_type = currdev.d_dev->dv_type;
+		currdev.dd.d_unit = 0;
 
 		if ((load_type == -1 || (load_type & DEV_TYP_STOR)) &&
 		    strcmp(devsw[i]->dv_name, "disk") == 0) {
-			if (probe_disks(i, load_type, load_unit, load_slice, 
+			if (probe_disks(i, load_type, load_unit, load_slice,
 			    load_partition) == 0)
 				break;
 		}
--- a/usr/src/boot/sys/boot/uboot/lib/devicename.c	Sat Mar 24 18:13:39 2018 +0200
+++ b/usr/src/boot/sys/boot/uboot/lib/devicename.c	Tue Mar 13 11:58:56 2018 +0200
@@ -1,4 +1,4 @@
-/*-
+/*
  * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
  * All rights reserved.
  *
@@ -25,7 +25,6 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
 
 #include <stand.h>
 #include <string.h>
@@ -136,7 +135,7 @@
 			err = EINVAL;
 			goto fail;
 		}
-		idev->d_unit = unit;
+		idev->dd.d_unit = unit;
 
 		if (path != NULL)
 			*path = (*cp == 0) ? cp : cp + 1;
@@ -146,8 +145,8 @@
 		err = EINVAL;
 		goto fail;
 	}
-	idev->d_dev = dv;
-	idev->d_type = dv->dv_type;
+	idev->dd.d_dev = dv;
+	idev->dd.d_type = dv->dv_type;
 	if (dev == NULL) {
 		free(idev);
 	} else {
@@ -167,7 +166,7 @@
 	struct uboot_devdesc *dev = (struct uboot_devdesc *)vdev;
 	static char buf[128];
 
-	switch(dev->d_type) {
+	switch(dev->dd.d_type) {
 	case DEVT_NONE:
 		strcpy(buf, "(no device)");
 		break;
@@ -178,7 +177,7 @@
 #endif
 
 	case DEVT_NET:
-		sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit);
+		sprintf(buf, "%s%d:", dev->dd.d_dev->dv_name, dev->dd.d_unit);
 		break;
 	}
 	return(buf);
--- a/usr/src/boot/sys/boot/uboot/lib/disk.c	Sat Mar 24 18:13:39 2018 +0200
+++ b/usr/src/boot/sys/boot/uboot/lib/disk.c	Tue Mar 13 11:58:56 2018 +0200
@@ -1,4 +1,4 @@
-/*-
+/*
  * Copyright (c) 2008 Semihalf, Rafal Jaworowski
  * Copyright (c) 2009 Semihalf, Piotr Ziecik
  * Copyright (c) 2012 Andrey V. Elsukov <ae@FreeBSD.org>
@@ -32,7 +32,6 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
 #include <sys/disk.h>
@@ -46,7 +45,7 @@
 #include "libuboot.h"
 
 #define stor_printf(fmt, args...) do {			\
-    printf("%s%d: ", dev->d_dev->dv_name, dev->d_unit);	\
+    printf("%s%d: ", dev->dd.d_dev->dv_name, dev->dd.d_unit);	\
     printf(fmt, ##args);				\
 } while (0)
 
@@ -65,7 +64,7 @@
 	u_int		bsize;	/* block size */
 } stor_info[UB_MAX_DEV];
 
-#define	SI(dev)		(stor_info[(dev)->d_unit])
+#define	SI(dev)		(stor_info[(dev)->dd.d_unit])
 
 static int stor_info_no = 0;
 static int stor_opendev(struct disk_devdesc *);
@@ -191,7 +190,7 @@
 {
 	int err;
 
-	if (dev->d_unit < 0 || dev->d_unit >= stor_info_no)
+	if (dev->dd.d_unit < 0 || dev->dd.d_unit >= stor_info_no)
 		return (EIO);
 
 	if (SI(dev).opened == 0) {
@@ -252,8 +251,8 @@
 		return (ret);
 
 	for (i = 0; i < stor_info_no; i++) {
-		dev.d_dev = &uboot_storage;
-		dev.d_unit = i;
+		dev.dd.d_dev = &uboot_storage;
+		dev.dd.d_unit = i;
 		dev.d_slice = -1;
 		dev.d_partition = -1;
 		sprintf(line, "\tdisk%d (%s)\n", i,
--- a/usr/src/boot/sys/boot/uboot/lib/libuboot.h	Sat Mar 24 18:13:39 2018 +0200
+++ b/usr/src/boot/sys/boot/uboot/lib/libuboot.h	Tue Mar 13 11:58:56 2018 +0200
@@ -1,4 +1,4 @@
-/*-
+/*
  * Copyright (C) 2000 Benno Rice.
  * Copyright (C) 2007 Semihalf, Rafal Jaworowski <raj@semihalf.com>
  * All rights reserved.
@@ -29,10 +29,7 @@
 
 /* Note: Must match the 'struct devdesc' in stand.h */
 struct uboot_devdesc {
-	struct devsw	*d_dev;
-	int		d_type;
-	int		d_unit;
-	void		*d_opendata;
+	struct devdesc	dd;
 	union {
 		struct {
 			int	slice;
--- a/usr/src/boot/sys/boot/userboot/userboot/devicename.c	Sat Mar 24 18:13:39 2018 +0200
+++ b/usr/src/boot/sys/boot/userboot/userboot/devicename.c	Tue Mar 13 11:58:56 2018 +0200
@@ -1,4 +1,4 @@
-/*-
+/*
  * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
  * All rights reserved.
  *
@@ -25,7 +25,6 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
 
 #include <stand.h>
 #include <string.h>
@@ -139,7 +138,7 @@
 	    goto fail;
 	}
 
-	idev->d_unit = unit;
+	idev->dd.d_unit = unit;
 	if (path != NULL)
 	    *path = (*cp == 0) ? cp : cp + 1;
 	break;
@@ -158,8 +157,8 @@
 	err = EINVAL;
 	goto fail;
     }
-    idev->d_dev = dv;
-    idev->d_type = dv->dv_type;
+    idev->dd.d_dev = dv;
+    idev->dd.d_type = dv->dv_type;
     if (dev == NULL) {
 	free(idev);
     } else {
@@ -179,27 +178,27 @@
     struct disk_devdesc	*dev = (struct disk_devdesc *)vdev;
     static char		buf[128];	/* XXX device length constant? */
 
-    switch(dev->d_type) {
+    switch(dev->dd.d_type) {
     case DEVT_NONE:
 	strcpy(buf, "(no device)");
 	break;
 
     case DEVT_CD:
-	sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit);
+	sprintf(buf, "%s%d:", dev->dd.d_dev->dv_name, dev->dd.d_unit);
 	break;
 
     case DEVT_DISK:
 	return (disk_fmtdev(vdev));
 
     case DEVT_NET:
-	sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit);
+	sprintf(buf, "%s%d:", dev->dd.d_dev->dv_name, dev->dd.d_unit);
 	break;
 
     case DEVT_ZFS:
 #if defined(USERBOOT_ZFS_SUPPORT)
 	return (zfs_fmtdev(vdev));
 #else
-	sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit);
+	sprintf(buf, "%s%d:", dev->dd.d_dev->dv_name, dev->dd.d_unit);
 #endif
 	break;
     }
--- a/usr/src/boot/sys/boot/userboot/userboot/main.c	Sat Mar 24 18:13:39 2018 +0200
+++ b/usr/src/boot/sys/boot/userboot/userboot/main.c	Tue Mar 13 11:58:56 2018 +0200
@@ -1,4 +1,4 @@
-/*-
+/*
  * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
  * Copyright (c) 1998,2000 Doug Rabson <dfr@freebsd.org>
  * All rights reserved.
@@ -26,7 +26,6 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
 
 #include <stand.h>
 #include <string.h>
@@ -154,37 +153,38 @@
 	//bzero(&dev, sizeof(dev));
 
 #if defined(USERBOOT_ZFS_SUPPORT)
+	CTASSERT(sizeof(struct disk_devdesc) >= sizeof(struct zfs_devdesc));
 	if (userboot_zfs_found) {
 		struct zfs_devdesc zdev;
-	
+
 		/* Leave the pool/root guid's unassigned */
 		bzero(&zdev, sizeof(zdev));
-		zdev.d_dev = &zfs_dev;
-		zdev.d_type = zdev.d_dev->dv_type;
-		
+		zdev.dd.d_dev = &zfs_dev;
+		zdev.dd.d_type = zdev.dd.d_dev->dv_type;
+
 		dev = *(struct disk_devdesc *)&zdev;
 		init_zfs_bootenv(zfs_fmtdev(&dev));
 	} else
 #endif
 
 	if (userboot_disk_maxunit > 0) {
-		dev.d_dev = &userboot_disk;
-		dev.d_type = dev.d_dev->dv_type;
-		dev.d_unit = 0;
+		dev.dd.d_dev = &userboot_disk;
+		dev.dd.d_type = dev.dd.d_dev->dv_type;
+		dev.dd.d_unit = 0;
 		dev.d_slice = 0;
 		dev.d_partition = 0;
 		/*
 		 * If we cannot auto-detect the partition type then
 		 * access the disk as a raw device.
 		 */
-		if (dev.d_dev->dv_open(NULL, &dev)) {
+		if (dev.dd.d_dev->dv_open(NULL, &dev)) {
 			dev.d_slice = -1;
 			dev.d_partition = -1;
 		}
 	} else {
-		dev.d_dev = &host_dev;
-		dev.d_type = dev.d_dev->dv_type;
-		dev.d_unit = 0;
+		dev.dd.d_dev = &host_dev;
+		dev.dd.d_type = dev.dd.d_dev->dv_type;
+		dev.dd.d_unit = 0;
 	}
 
 	env_setenv("currdev", EV_VOLATILE, userboot_fmtdev(&dev),
--- a/usr/src/boot/sys/boot/userboot/userboot/userboot_disk.c	Sat Mar 24 18:13:39 2018 +0200
+++ b/usr/src/boot/sys/boot/userboot/userboot/userboot_disk.c	Tue Mar 13 11:58:56 2018 +0200
@@ -1,4 +1,4 @@
-/*-
+/*
  * Copyright (c) 2011 Google, Inc.
  * All rights reserved.
  *
@@ -25,7 +25,6 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
 
 /*
  * Userboot disk image handling.
@@ -127,8 +126,8 @@
 	for (i = 0; i < userdisk_maxunit; i++) {
 		sprintf(line, "    disk%d:   Guest drive image\n", i);
 		pager_output(line);
-		dev.d_dev = &userboot_disk;
-		dev.d_unit = i;
+		dev.dd.d_dev = &userboot_disk;
+		dev.dd.d_unit = i;
 		dev.d_slice = -1;
 		dev.d_partition = -1;
 		if (disk_open(&dev, ud_info[i].mediasize,
@@ -153,11 +152,13 @@
 	dev = va_arg(ap, struct disk_devdesc *);
 	va_end(ap);
 
-	if (dev->d_unit < 0 || dev->d_unit >= userdisk_maxunit)
+	if (dev->dd.d_unit < 0 || dev->dd.d_unit >= userdisk_maxunit)
 		return (EIO);
-
-	return (disk_open(dev, ud_info[dev->d_unit].mediasize,
-	    ud_info[dev->d_unit].sectorsize));
+	ud_info[dev->dd.d_unit].ud_open++;
+	if (ud_info[dev->dd.d_unit].ud_bcache == NULL)
+		ud_info[dev->dd.d_unit].ud_bcache = bcache_allocate();
+	return (disk_open(dev, ud_info[dev->dd.d_unit].mediasize,
+	    ud_info[dev->dd.d_unit].sectorsize));
 }
 
 static int
@@ -166,6 +167,11 @@
 	struct disk_devdesc *dev;
 
 	dev = (struct disk_devdesc *)f->f_devdata;
+	ud_info[dev->dd.d_unit].ud_open--;
+	if (ud_info[dev->dd.d_unit].ud_open == 0) {
+		bcache_free(ud_info[dev->dd.d_unit].ud_bcache);
+		ud_info[dev->dd.d_unit].ud_bcache = NULL;
+	}
 	return (disk_close(dev));
 }
 
@@ -173,6 +179,21 @@
 userdisk_strategy(void *devdata, int rw, daddr_t dblk, size_t size,
     char *buf, size_t *rsize)
 {
+	struct bcache_devdata bcd;
+	struct disk_devdesc *dev;
+
+	dev = (struct disk_devdesc *)devdata;
+	bcd.dv_strategy = userdisk_realstrategy;
+	bcd.dv_devdata = devdata;
+	bcd.dv_cache = ud_info[dev->dd.d_unit].ud_bcache;
+	return (bcache_strategy(&bcd, rw, dblk + dev->d_offset,
+	    size, buf, rsize));
+}
+
+static int
+userdisk_realstrategy(void *devdata, int rw, daddr_t dblk, size_t size,
+    char *buf, size_t *rsize)
+{
 	struct disk_devdesc *dev = devdata;
 	uint64_t	off;
 	size_t		resid;
@@ -185,8 +206,8 @@
 		return (EINVAL);
 	if (rsize)
 		*rsize = 0;
-	off = (dblk + dev->d_offset) * ud_info[dev->d_unit].sectorsize;
-	rc = CALLBACK(diskread, dev->d_unit, off, buf, size, &resid);
+	off = dblk * ud_info[dev->dd.d_unit].sectorsize;
+	rc = CALLBACK(diskread, dev->dd.d_unit, off, buf, size, &resid);
 	if (rc)
 		return (rc);
 	if (rsize)
@@ -200,5 +221,5 @@
 	struct disk_devdesc *dev;
 
 	dev = (struct disk_devdesc *)f->f_devdata;
-	return (CALLBACK(diskioctl, dev->d_unit, cmd, data));
+	return (CALLBACK(diskioctl, dev->dd.d_unit, cmd, data));
 }
--- a/usr/src/boot/sys/boot/zfs/libzfs.h	Sat Mar 24 18:13:39 2018 +0200
+++ b/usr/src/boot/sys/boot/zfs/libzfs.h	Tue Mar 13 11:58:56 2018 +0200
@@ -38,10 +38,7 @@
  */
 /* Note: Must match the 'struct devdesc' in stand.h */
 struct zfs_devdesc {
-    struct devsw	*d_dev;
-    int			d_type;
-    int			d_unit;
-    void		*d_opendata;
+    struct devdesc	dd;
     uint64_t		pool_guid;
     uint64_t		root_guid;
 };
--- a/usr/src/boot/sys/boot/zfs/zfs.c	Sat Mar 24 18:13:39 2018 +0200
+++ b/usr/src/boot/sys/boot/zfs/zfs.c	Tue Mar 13 11:58:56 2018 +0200
@@ -691,8 +691,8 @@
 		return (rv);
 	if (path != NULL)
 		*path = (*end == '\0') ? end : end + 1;
-	dev->d_dev = &zfs_dev;
-	dev->d_type = zfs_dev.dv_type;
+	dev->dd.d_dev = &zfs_dev;
+	dev->dd.d_type = zfs_dev.dv_type;
 	return (0);
 }
 
@@ -707,7 +707,7 @@
 	int			n;
 
 	buf[0] = '\0';
-	if (dev->d_type != DEVT_ZFS)
+	if (dev->dd.d_type != DEVT_ZFS)
 		return (buf);
 
 	spa = spa_find_by_guid(dev->pool_guid);
@@ -762,7 +762,7 @@
 	spa_t			*spa;
 
 	buf[0] = '\0';
-	if (dev->d_type != DEVT_ZFS)
+	if (dev->dd.d_type != DEVT_ZFS)
 		return (buf);
 
 	if (dev->pool_guid == 0) {
@@ -784,9 +784,9 @@
 	}
 
 	if (rootname[0] == '\0')
-		sprintf(buf, "%s:%s:", dev->d_dev->dv_name, spa->spa_name);
+		sprintf(buf, "%s:%s:", dev->dd.d_dev->dv_name, spa->spa_name);
 	else
-		sprintf(buf, "%s:%s/%s:", dev->d_dev->dv_name, spa->spa_name,
+		sprintf(buf, "%s:%s/%s:", dev->dd.d_dev->dv_name, spa->spa_name,
 		    rootname);
 	return (buf);
 }