[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