[Midnightbsd-cvs] src [10180] trunk/sys/boot/zfs: sync up zfs code

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Fri Jun 1 19:09:28 EDT 2018


Revision: 10180
          http://svnweb.midnightbsd.org/src/?rev=10180
Author:   laffer1
Date:     2018-06-01 19:09:27 -0400 (Fri, 01 Jun 2018)
Log Message:
-----------
sync up zfs code

Modified Paths:
--------------
    trunk/sys/boot/zfs/Makefile
    trunk/sys/boot/zfs/libzfs.h
    trunk/sys/boot/zfs/zfs.c
    trunk/sys/boot/zfs/zfsimpl.c

Modified: trunk/sys/boot/zfs/Makefile
===================================================================
--- trunk/sys/boot/zfs/Makefile	2018-06-01 23:04:46 UTC (rev 10179)
+++ trunk/sys/boot/zfs/Makefile	2018-06-01 23:09:27 UTC (rev 10180)
@@ -1,4 +1,5 @@
 # $MidnightBSD$
+# $FreeBSD: stable/10/sys/boot/zfs/Makefile 260096 2013-12-30 20:15:46Z dim $
 
 LIB=		zfsboot
 INTERNALLIB=
@@ -16,6 +17,9 @@
 CFLAGS.gcc+=	-mpreferred-stack-boundary=2
 CFLAGS+=	-mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 -msoft-float
 .endif
+.if ${MACHINE_CPUARCH} == "powerpc" || ${MACHINE_CPUARCH} == "arm"
+CFLAGS+=	-msoft-float
+.endif
 .if ${MACHINE_CPUARCH} == "amd64"
 CFLAGS+=	-m32
 .endif

Modified: trunk/sys/boot/zfs/libzfs.h
===================================================================
--- trunk/sys/boot/zfs/libzfs.h	2018-06-01 23:04:46 UTC (rev 10179)
+++ trunk/sys/boot/zfs/libzfs.h	2018-06-01 23:09:27 UTC (rev 10180)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2012 Andriy Gapon <avg at FreeBSD.org>
  * All rights reserved.
@@ -23,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/boot/zfs/libzfs.h 295475 2016-02-10 17:49:22Z allanjude $
  */
 
 #ifndef _BOOT_LIBZFS_H_
@@ -62,6 +63,10 @@
 char	*zfs_fmtdev(void *vdev);
 int	zfs_probe_dev(const char *devname, uint64_t *pool_guid);
 int	zfs_list(const char *name);
+void	init_zfs_bootenv(char *currdev);
+int	zfs_bootenv(const char *name);
+int	zfs_belist_add(const char *name);
+int	zfs_set_env(void);
 
 extern struct devsw zfs_dev;
 extern struct fs_ops zfs_fsops;

Modified: trunk/sys/boot/zfs/zfs.c
===================================================================
--- trunk/sys/boot/zfs/zfs.c	2018-06-01 23:04:46 UTC (rev 10179)
+++ trunk/sys/boot/zfs/zfs.c	2018-06-01 23:09:27 UTC (rev 10180)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2007 Doug Rabson
  * All rights reserved.
@@ -23,11 +24,11 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$MidnightBSD$
+ *	$FreeBSD: stable/10/sys/boot/zfs/zfs.c 295475 2016-02-10 17:49:22Z allanjude $
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/boot/zfs/zfs.c 295475 2016-02-10 17:49:22Z allanjude $");
 
 /*
  *	Stand-alone file reading package.
@@ -48,6 +49,10 @@
 
 #include "zfsimpl.c"
 
+/* Define the range of indexes to be populated with ZFS Boot Environments */
+#define		ZFS_BE_FIRST	4
+#define		ZFS_BE_LAST	8
+
 static int	zfs_open(const char *path, struct open_file *f);
 static int	zfs_write(struct open_file *f, void *buf, size_t size, size_t *resid);
 static int	zfs_close(struct open_file *f);
@@ -80,6 +85,16 @@
 	zap_leaf_phys_t	*f_zap_leaf;	/* zap leaf buffer */
 };
 
+static int	zfs_env_index;
+static int	zfs_env_count;
+
+SLIST_HEAD(zfs_be_list, zfs_be_entry) zfs_be_head = SLIST_HEAD_INITIALIZER(zfs_be_head);
+struct zfs_be_list *zfs_be_headp;
+struct zfs_be_entry {
+	const char *name;
+	SLIST_ENTRY(zfs_be_entry) entries;
+} *zfs_be, *zfs_be_tmp;
+
 /*
  * Open a file.
  */
@@ -140,7 +155,7 @@
 	n = size;
 	if (fp->f_seekp + n > sb.st_size)
 		n = sb.st_size - fp->f_seekp;
-	
+
 	rc = dnode_read(spa, &fp->f_dnode, fp->f_seekp, start, n);
 	if (rc)
 		return (rc);
@@ -433,9 +448,12 @@
 	char devname[32];
 	int ret;
 
-	/* Probe only freebsd-zfs and freebsd partitions */
+	/* Probe only midnightbsd & freebsd-zfs and freebsd partitions */
+	/* TODO: remove freebsd partitions LAH */
 	if (part->type != PART_FREEBSD &&
-	    part->type != PART_FREEBSD_ZFS)
+	    part->type != PART_FREEBSD_ZFS &&
+            part->type != PART_MIDNIGHTBSD &&
+            part->type != PART_MIDNIGHTBSD_ZFS)
 		return;
 
 	ppa = (struct zfs_probe_args *)arg;
@@ -449,7 +467,7 @@
 	if (ret == 0)
 		return;
 	/* Do we have BSD label here? */
-	if (part->type == PART_FREEBSD) {
+	if (part->type == PART_MIDNIGHTBSD || part->type == PART_FREEBSD) {
 		pa.devname = devname;
 		pa.pool_guid = ppa->pool_guid;
 		pa.secsz = ppa->secsz;
@@ -493,7 +511,7 @@
 		}
 	}
 	close(pa.fd);
-	return (0);
+	return (ret);
 }
 
 /*
@@ -691,6 +709,192 @@
 	rv = zfs_lookup_dataset(spa, dsname, &objid);
 	if (rv != 0)
 		return (rv);
-	rv = zfs_list_dataset(spa, objid);
+
+	return (zfs_list_dataset(spa, objid));
+}
+
+void
+init_zfs_bootenv(char *currdev)
+{
+	char *beroot;
+
+	if (strlen(currdev) == 0)
+		return;
+	if(strncmp(currdev, "zfs:", 4) != 0)
+		return;
+	/* Remove the trailing : */
+	currdev[strlen(currdev) - 1] = '\0';
+	setenv("zfs_be_active", currdev, 1);
+	setenv("zfs_be_currpage", "1", 1);
+	/* Forward past zfs: */
+	currdev = strchr(currdev, ':');
+	currdev++;
+	/* Remove the last element (current bootenv) */
+	beroot = strrchr(currdev, '/');
+	if (beroot != NULL)
+		beroot[0] = '\0';
+	beroot = currdev;
+	setenv("zfs_be_root", beroot, 1);
+}
+
+int
+zfs_bootenv(const char *name)
+{
+	static char	poolname[ZFS_MAXNAMELEN], *dsname, *root;
+	char		becount[4];
+	uint64_t	objid;
+	spa_t		*spa;
+	int		len, rv, pages, perpage, currpage;
+
+	if (name == NULL)
+		return (EINVAL);
+	if ((root = getenv("zfs_be_root")) == NULL)
+		return (EINVAL);
+
+	if (strcmp(name, root) != 0) {
+		if (setenv("zfs_be_root", name, 1) != 0)
+			return (ENOMEM);
+	}
+
+	SLIST_INIT(&zfs_be_head);
+	zfs_env_count = 0;
+	len = strlen(name);
+	dsname = strchr(name, '/');
+	if (dsname != NULL) {
+		len = dsname - name;
+		dsname++;
+	} else
+		dsname = "";
+	memcpy(poolname, name, len);
+	poolname[len] = '\0';
+
+	spa = spa_find_by_name(poolname);
+	if (!spa)
+		return (ENXIO);
+	rv = zfs_lookup_dataset(spa, dsname, &objid);
+	if (rv != 0)
+		return (rv);
+	rv = zfs_callback_dataset(spa, objid, zfs_belist_add);
+
+	/* Calculate and store the number of pages of BEs */
+	perpage = (ZFS_BE_LAST - ZFS_BE_FIRST + 1);
+	pages = (zfs_env_count / perpage) + ((zfs_env_count % perpage) > 0 ? 1 : 0);
+	snprintf(becount, 4, "%d", pages);
+	if (setenv("zfs_be_pages", becount, 1) != 0)
+		return (ENOMEM);
+
+	/* Roll over the page counter if it has exceeded the maximum */
+	currpage = strtol(getenv("zfs_be_currpage"), NULL, 10);
+	if (currpage > pages) {
+		if (setenv("zfs_be_currpage", "1", 1) != 0)
+			return (ENOMEM);
+	}
+
+	/* Populate the menu environment variables */
+	zfs_set_env();
+
+	/* Clean up the SLIST of ZFS BEs */
+	while (!SLIST_EMPTY(&zfs_be_head)) {
+		zfs_be = SLIST_FIRST(&zfs_be_head);
+		SLIST_REMOVE_HEAD(&zfs_be_head, entries);
+		free(zfs_be);
+	}
+
 	return (rv);
 }
+
+int
+zfs_belist_add(const char *name)
+{
+
+	/* Skip special datasets that start with a $ character */
+	if (strncmp(name, "$", 1) == 0) {
+		return (0);
+	}
+	/* Add the boot environment to the head of the SLIST */
+	zfs_be = malloc(sizeof(struct zfs_be_entry));
+	if (zfs_be == NULL) {
+		return (ENOMEM);
+	}
+	zfs_be->name = name;
+	SLIST_INSERT_HEAD(&zfs_be_head, zfs_be, entries);
+	zfs_env_count++;
+
+	return (0);
+}
+
+int
+zfs_set_env(void)
+{
+	char envname[32], envval[256];
+	char *beroot, *pagenum;
+	int rv, page, ctr;
+
+	beroot = getenv("zfs_be_root");
+	if (beroot == NULL) {
+		return (1);
+	}
+
+	pagenum = getenv("zfs_be_currpage");
+	if (pagenum != NULL) {
+		page = strtol(pagenum, NULL, 10);
+	} else {
+		page = 1;
+	}
+
+	ctr = 1;
+	rv = 0;
+	zfs_env_index = ZFS_BE_FIRST;
+	SLIST_FOREACH_SAFE(zfs_be, &zfs_be_head, entries, zfs_be_tmp) {
+		/* Skip to the requested page number */
+		if (ctr <= ((ZFS_BE_LAST - ZFS_BE_FIRST + 1) * (page - 1))) {
+			ctr++;
+			continue;
+		}
+		
+		snprintf(envname, sizeof(envname), "bootenvmenu_caption[%d]", zfs_env_index);
+		snprintf(envval, sizeof(envval), "%s", zfs_be->name);
+		rv = setenv(envname, envval, 1);
+		if (rv != 0) {
+			break;
+		}
+
+		snprintf(envname, sizeof(envname), "bootenvansi_caption[%d]", zfs_env_index);
+		rv = setenv(envname, envval, 1);
+		if (rv != 0){
+			break;
+		}
+
+		snprintf(envname, sizeof(envname), "bootenvmenu_command[%d]", zfs_env_index);
+		rv = setenv(envname, "set_bootenv", 1);
+		if (rv != 0){
+			break;
+		}
+
+		snprintf(envname, sizeof(envname), "bootenv_root[%d]", zfs_env_index);
+		snprintf(envval, sizeof(envval), "zfs:%s/%s", beroot, zfs_be->name);
+		rv = setenv(envname, envval, 1);
+		if (rv != 0){
+			break;
+		}
+
+		zfs_env_index++;
+		if (zfs_env_index > ZFS_BE_LAST) {
+			break;
+		}
+
+	}
+	
+	for (; zfs_env_index <= ZFS_BE_LAST; zfs_env_index++) {
+		snprintf(envname, sizeof(envname), "bootenvmenu_caption[%d]", zfs_env_index);
+		(void)unsetenv(envname);
+		snprintf(envname, sizeof(envname), "bootenvansi_caption[%d]", zfs_env_index);
+		(void)unsetenv(envname);
+		snprintf(envname, sizeof(envname), "bootenvmenu_command[%d]", zfs_env_index);
+		(void)unsetenv(envname);
+		snprintf(envname, sizeof(envname), "bootenv_root[%d]", zfs_env_index);
+		(void)unsetenv(envname);
+	}
+
+	return (rv);
+}

Modified: trunk/sys/boot/zfs/zfsimpl.c
===================================================================
--- trunk/sys/boot/zfs/zfsimpl.c	2018-06-01 23:04:46 UTC (rev 10179)
+++ trunk/sys/boot/zfs/zfsimpl.c	2018-06-01 23:09:27 UTC (rev 10180)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2007 Doug Rabson
  * All rights reserved.
@@ -25,8 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-/* $FreeBSD: stable/9/sys/boot/zfs/zfsimpl.c 284510 2015-06-17 11:48:00Z avg $ */
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/boot/zfs/zfsimpl.c 316323 2017-03-31 04:51:08Z ngie $");
 
 /*
  *	Stand-alone ZFS file reader.
@@ -57,6 +57,8 @@
 	"org.illumos:lz4_compress",
 	"com.delphix:hole_birth",
 	"com.delphix:extensible_dataset",
+	"com.delphix:embedded_data",
+	"org.open-zfs:large_blocks",
 	NULL
 };
 
@@ -65,7 +67,6 @@
  */
 static spa_list_t zfs_pools;
 
-static uint64_t zfs_crc64_table[256];
 static const dnode_phys_t *dnode_cache_obj = 0;
 static uint64_t dnode_cache_bn;
 static char *dnode_cache_buf;
@@ -488,7 +489,7 @@
 }
 
 static vdev_t *
-vdev_create(uint64_t guid, vdev_read_t *read)
+vdev_create(uint64_t guid, vdev_read_t *_read)
 {
 	vdev_t *vdev;
 
@@ -497,7 +498,7 @@
 	STAILQ_INIT(&vdev->v_children);
 	vdev->v_guid = guid;
 	vdev->v_state = VDEV_STATE_OFFLINE;
-	vdev->v_read = read;
+	vdev->v_read = _read;
 	vdev->v_phys_read = 0;
 	vdev->v_read_priv = 0;
 	STAILQ_INSERT_TAIL(&zfs_vdevs, vdev, v_alllink);
@@ -874,7 +875,7 @@
 }
 
 static int
-vdev_probe(vdev_phys_read_t *read, void *read_priv, spa_t **spap)
+vdev_probe(vdev_phys_read_t *_read, void *read_priv, spa_t **spap)
 {
 	vdev_t vtmp;
 	vdev_phys_t *vdev_label = (vdev_phys_t *) zap_scratch;
@@ -899,7 +900,7 @@
 	 * uberblock is most current.
 	 */
 	memset(&vtmp, 0, sizeof(vtmp));
-	vtmp.v_phys_read = read;
+	vtmp.v_phys_read = _read;
 	vtmp.v_read_priv = read_priv;
 	off = offsetof(vdev_label_t, vl_vdev_phys);
 	BP_ZERO(&bp);
@@ -1025,7 +1026,7 @@
 	 */
 	vdev = vdev_find(guid);
 	if (vdev) {
-		vdev->v_phys_read = read;
+		vdev->v_phys_read = _read;
 		vdev->v_read_priv = read_priv;
 		vdev->v_state = VDEV_STATE_HEALTHY;
 	} else {
@@ -1134,6 +1135,34 @@
 	void *pbuf;
 	int i, error;
 
+	/*
+	 * Process data embedded in block pointer
+	 */
+	if (BP_IS_EMBEDDED(bp)) {
+		ASSERT(BPE_GET_ETYPE(bp) == BP_EMBEDDED_TYPE_DATA);
+
+		size = BPE_GET_PSIZE(bp);
+		ASSERT(size <= BPE_PAYLOAD_SIZE);
+
+		if (cpfunc != ZIO_COMPRESS_OFF)
+			pbuf = zfs_alloc(size);
+		else
+			pbuf = buf;
+
+		decode_embedded_bp_compressed(bp, pbuf);
+		error = 0;
+
+		if (cpfunc != ZIO_COMPRESS_OFF) {
+			error = zio_decompress_data(cpfunc, pbuf,
+			    size, buf, BP_GET_LSIZE(bp));
+			zfs_free(pbuf, size);
+		}
+		if (error != 0)
+			printf("ZFS: i/o error - unable to decompress block pointer data, error %d\n",
+			    error);
+		return (error);
+	}
+
 	error = EIO;
 
 	for (i = 0; i < SPA_DVAS_PER_BP; i++) {
@@ -1194,6 +1223,11 @@
 	int nlevels = dnode->dn_nlevels;
 	int i, rc;
 
+	if (bsize > SPA_MAXBLOCKSIZE) {
+		printf("ZFS: I/O error - blocks larger than 128K are not supported\n");
+		return (EIO);
+	}
+
 	/*
 	 * Note: bsize may not be a power of two here so we need to do an
 	 * actual divide rather than a bitshift.
@@ -1439,7 +1473,7 @@
  * the directory contents.
  */
 static int
-mzap_list(const dnode_phys_t *dnode)
+mzap_list(const dnode_phys_t *dnode, int (*callback)(const char *))
 {
 	const mzap_phys_t *mz;
 	const mzap_ent_phys_t *mze;
@@ -1458,7 +1492,7 @@
 		mze = &mz->mz_chunk[i];
 		if (mze->mze_name[0])
 			//printf("%-32s 0x%jx\n", mze->mze_name, (uintmax_t)mze->mze_value);
-			printf("%s\n", mze->mze_name);
+			callback(mze->mze_name);
 	}
 
 	return (0);
@@ -1469,7 +1503,7 @@
  * the directory header.
  */
 static int
-fzap_list(const spa_t *spa, const dnode_phys_t *dnode)
+fzap_list(const spa_t *spa, const dnode_phys_t *dnode, int (*callback)(const char *))
 {
 	int bsize = dnode->dn_datablkszsec << SPA_MINBLOCKSHIFT;
 	zap_phys_t zh = *(zap_phys_t *) zap_scratch;
@@ -1532,7 +1566,7 @@
 			value = fzap_leaf_value(&zl, zc);
 
 			//printf("%s 0x%jx\n", name, (uintmax_t)value);
-			printf("%s\n", name);
+			callback((const char *)name);
 		}
 	}
 
@@ -1539,6 +1573,14 @@
 	return (0);
 }
 
+static int zfs_printf(const char *name)
+{
+
+	printf("%s\n", name);
+
+	return (0);
+}
+
 /*
  * List a zap directory.
  */
@@ -1553,9 +1595,9 @@
 
 	zap_type = *(uint64_t *) zap_scratch;
 	if (zap_type == ZBT_MICRO)
-		return mzap_list(dnode);
+		return mzap_list(dnode, zfs_printf);
 	else
-		return fzap_list(spa, dnode);
+		return fzap_list(spa, dnode, zfs_printf);
 }
 
 static int
@@ -1824,6 +1866,48 @@
 
 	return (zap_list(spa, &child_dir_zap) != 0);
 }
+
+int
+zfs_callback_dataset(const spa_t *spa, uint64_t objnum, int (*callback)(const char *name))
+{
+	uint64_t dir_obj, child_dir_zapobj, zap_type;
+	dnode_phys_t child_dir_zap, dir, dataset;
+	dsl_dataset_phys_t *ds;
+	dsl_dir_phys_t *dd;
+	int err;
+
+	err = objset_get_dnode(spa, &spa->spa_mos, objnum, &dataset);
+	if (err != 0) {
+		printf("ZFS: can't find dataset %ju\n", (uintmax_t)objnum);
+		return (err);
+	}
+	ds = (dsl_dataset_phys_t *) &dataset.dn_bonus;
+	dir_obj = ds->ds_dir_obj;
+
+	err = objset_get_dnode(spa, &spa->spa_mos, dir_obj, &dir);
+	if (err != 0) {
+		printf("ZFS: can't find dirobj %ju\n", (uintmax_t)dir_obj);
+		return (err);
+	}
+	dd = (dsl_dir_phys_t *)&dir.dn_bonus;
+
+	child_dir_zapobj = dd->dd_child_dir_zapobj;
+	err = objset_get_dnode(spa, &spa->spa_mos, child_dir_zapobj, &child_dir_zap);
+	if (err != 0) {
+		printf("ZFS: can't find child zap %ju\n", (uintmax_t)dir_obj);
+		return (err);
+	}
+
+	err = dnode_read(spa, &child_dir_zap, 0, zap_scratch, child_dir_zap.dn_datablkszsec * 512);
+	if (err != 0)
+		return (err);
+
+	zap_type = *(uint64_t *) zap_scratch;
+	if (zap_type == ZBT_MICRO)
+		return mzap_list(&child_dir_zap, callback);
+	else
+		return fzap_list(spa, &child_dir_zap, callback);
+}
 #endif
 
 /*
@@ -2081,7 +2165,13 @@
 				strcpy(&path[sb.st_size], p);
 			else
 				path[sb.st_size] = 0;
-			if (sb.st_size + sizeof(znode_phys_t) <= dn.dn_bonuslen) {
+			/*
+			 * Second test is purely to silence bogus compiler
+			 * warning about accessing past the end of dn_bonus.
+			 */
+			if (sb.st_size + sizeof(znode_phys_t) <=
+			    dn.dn_bonuslen && sizeof(znode_phys_t) <=
+			    sizeof(dn.dn_bonus)) {
 				memcpy(path, &dn.dn_bonus[sizeof(znode_phys_t)],
 					sb.st_size);
 			} else {



More information about the Midnightbsd-cvs mailing list