Mailing List Archive

[xen-unstable] Port latest grub zfs boot code to pygrub
# HG changeset patch
# User Keir Fraser <keir.fraser@citrix.com>
# Date 1271242614 -3600
# Node ID ae08db793febf3a8da6cd74f38988d69d87d81a5
# Parent 07befd9cf6d3097c3b44d857c8498a6ed14772c7
Port latest grub zfs boot code to pygrub

Signed-off-by: Mark Johnson <mark.r.johnson@oracle.com>

Add -Werror to CFLAGS and fix numerous warnings/errors.

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
---
tools/libfsimage/Rules.mk | 3
tools/libfsimage/common/fsimage_grub.h | 1
tools/libfsimage/zfs/Makefile | 3
tools/libfsimage/zfs/filesys.h | 33
tools/libfsimage/zfs/fsi_zfs.c | 158 ++++
tools/libfsimage/zfs/fsi_zfs.h | 103 ++
tools/libfsimage/zfs/fsys_zfs.c | 792 ++++++++++++----------
tools/libfsimage/zfs/fsys_zfs.h | 102 +-
tools/libfsimage/zfs/shared.h | 33
tools/libfsimage/zfs/zfs-include/dmu.h | 21
tools/libfsimage/zfs/zfs-include/dnode.h | 7
tools/libfsimage/zfs/zfs-include/dsl_dataset.h | 2
tools/libfsimage/zfs/zfs-include/dsl_dir.h | 2
tools/libfsimage/zfs/zfs-include/sa_impl.h | 35
tools/libfsimage/zfs/zfs-include/spa.h | 103 +-
tools/libfsimage/zfs/zfs-include/uberblock_impl.h | 2
tools/libfsimage/zfs/zfs-include/vdev_impl.h | 27
tools/libfsimage/zfs/zfs-include/zap_impl.h | 5
tools/libfsimage/zfs/zfs-include/zap_leaf.h | 2
tools/libfsimage/zfs/zfs-include/zfs.h | 12
tools/libfsimage/zfs/zfs-include/zfs_acl.h | 7
tools/libfsimage/zfs/zfs-include/zfs_znode.h | 5
tools/libfsimage/zfs/zfs-include/zil.h | 10
tools/libfsimage/zfs/zfs-include/zio.h | 22
tools/libfsimage/zfs/zfs-include/zio_checksum.h | 4
tools/libfsimage/zfs/zfs_fletcher.c | 2
tools/libfsimage/zfs/zfs_lzjb.c | 15
tools/libfsimage/zfs/zfs_sha256.c | 2
28 files changed, 1021 insertions(+), 492 deletions(-)

diff -r 07befd9cf6d3 -r ae08db793feb tools/libfsimage/Rules.mk
--- a/tools/libfsimage/Rules.mk Wed Apr 14 11:29:05 2010 +0100
+++ b/tools/libfsimage/Rules.mk Wed Apr 14 11:56:54 2010 +0100
@@ -1,6 +1,7 @@ include $(XEN_ROOT)/tools/Rules.mk
include $(XEN_ROOT)/tools/Rules.mk

-CFLAGS += -I$(XEN_ROOT)/tools/libfsimage/common/ -Werror
+CFLAGS += -Wno-unknown-pragmas -I$(XEN_ROOT)/tools/libfsimage/common/
+CFLAGS += -Werror -D_GNU_SOURCE
LDFLAGS += -L../common/

PIC_OBJS := $(patsubst %.c,%.opic,$(LIB_SRCS-y))
diff -r 07befd9cf6d3 -r ae08db793feb tools/libfsimage/common/fsimage_grub.h
--- a/tools/libfsimage/common/fsimage_grub.h Wed Apr 14 11:29:05 2010 +0100
+++ b/tools/libfsimage/common/fsimage_grub.h Wed Apr 14 11:56:54 2010 +0100
@@ -78,6 +78,7 @@ unsigned long fsig_log2(unsigned long);
#define ERR_DEV_VALUES 1
#define ERR_WONT_FIT 1
#define ERR_READ 1
+#define ERR_NEWER_VERSION 1

fsi_plugin_ops_t *fsig_init(fsi_plugin_t *, fsig_plugin_ops_t *);

diff -r 07befd9cf6d3 -r ae08db793feb tools/libfsimage/zfs/Makefile
--- a/tools/libfsimage/zfs/Makefile Wed Apr 14 11:29:05 2010 +0100
+++ b/tools/libfsimage/zfs/Makefile Wed Apr 14 11:56:54 2010 +0100
@@ -24,7 +24,8 @@

XEN_ROOT = ../../..

-LIB_SRCS-y = fsys_zfs.c zfs_lzjb.c zfs_sha256.c zfs_fletcher.c
+CFLAGS += -DFSYS_ZFS -DFSIMAGE -I$(XEN_ROOT)/tools/libfsimage/zfs
+LIB_SRCS-y = zfs_lzjb.c zfs_sha256.c zfs_fletcher.c fsi_zfs.c fsys_zfs.c

FS = zfs

diff -r 07befd9cf6d3 -r ae08db793feb tools/libfsimage/zfs/filesys.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libfsimage/zfs/filesys.h Wed Apr 14 11:56:54 2010 +0100
@@ -0,0 +1,33 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/*
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+#ifndef _FILESYS_H
+#define _FILESYS_H
+
+#ifdef FSYS_ZFS
+
+/* THIS FILE IS INTENTIONALLY BLANK */
+
+#endif /* FSI_ZFS */
+
+#endif /* !_FILESYS_H */
+
diff -r 07befd9cf6d3 -r ae08db793feb tools/libfsimage/zfs/fsi_zfs.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libfsimage/zfs/fsi_zfs.c Wed Apr 14 11:56:54 2010 +0100
@@ -0,0 +1,158 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/*
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifdef FSYS_ZFS
+
+#include <fsimage_grub.h>
+#include <fsimage_priv.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include "mb_info.h"
+
+
+#undef filemax
+#undef filepos
+#undef errnum
+
+
+#define MAXNAMELEN 256
+#define MAXPATHLEN 1024
+
+/**** START FROM disk_io.c ****/
+char current_rootpool[MAXNAMELEN];
+char current_bootfs[MAXNAMELEN];
+uint64_t current_bootfs_obj;
+char current_bootpath[MAXPATHLEN];
+char current_devid[MAXPATHLEN];
+int is_zfs_mount;
+unsigned long best_drive;
+unsigned long best_part;
+int find_best_root;
+unsigned long part_length;
+/**** END FROM disk_io.c ****/
+
+uint64_t filemax;
+uint64_t filepos;
+
+struct multiboot_info mbi;
+fsi_file_t *zfs_ffi;
+int errnum;
+char *bootstring = NULL;
+
+extern int zfs_mount(void);
+extern int zfs_open(char *filename);
+extern int zfs_read(char *buf, int len);
+
+#define ZFS_SCRATCH_SIZE 0x400000
+#define FSI_MOS_SHIFT 10
+#define FSI_MOS_MASK ((1 << FSI_MOS_SHIFT) - 1)
+unsigned char fsi_mos_buf[ZFS_SCRATCH_SIZE + FSI_MOS_MASK + 1];
+
+#define FSI_MOS_ALIGN(addr) (((uintptr_t)addr + FSI_MOS_MASK) & \
+ ~FSI_MOS_MASK)
+#define FSI_MOS(buf) ((FSI_MOS_ALIGN(buf) + \
+ ZFS_SCRATCH_SIZE - 0x100000) >> FSI_MOS_SHIFT)
+
+static int
+fsi_zfs_mount(fsi_file_t *ffi, const char *options)
+{
+ zfs_ffi = ffi;
+ mbi.mem_upper = FSI_MOS(fsi_mos_buf);
+
+ /* If an boot filesystem is passed in, set it to current_bootfs */
+ if (options != NULL) {
+ if (strlen(options) < MAXNAMELEN) {
+ strcpy(current_bootfs, options);
+ }
+ }
+
+ return (zfs_mount());
+}
+
+static int
+fsi_zfs_open(fsi_file_t *ffi, char *filename)
+{
+ char *fsi_bootstring;
+ uint64_t *fmax;
+ uint64_t *fpos;
+ int rc;
+
+ zfs_ffi = ffi;
+ fmax = fsig_filemax(ffi);
+ fpos = fsig_filepos(ffi);
+
+ rc = zfs_open(filename);
+ if (rc != 1) {
+ return (rc);
+ }
+
+ *fmax = filemax;
+ *fpos = filepos;
+
+ if (bootstring == NULL) {
+ rc = asprintf(&bootstring,
+ "zfs-bootfs=%s/%"PRIu64",bootpath='%s'",
+ current_rootpool, current_bootfs_obj,
+ current_bootpath);
+ if (rc == -1) {
+ return (rc);
+ }
+ fsi_bootstring = fsi_bootstring_alloc(ffi->ff_fsi,
+ strlen(bootstring) + 1);
+ strcpy(fsi_bootstring, bootstring);
+ }
+
+ return (rc);
+}
+
+static int
+fsi_zfs_read(fsi_file_t *ffi, char *buf, int len)
+{
+ uint64_t *fpos;
+ int rc;
+
+ zfs_ffi = ffi;
+ fpos = fsig_filepos(ffi);
+ filepos = *fpos;
+ rc = zfs_read(buf, len);
+ *fpos = filepos;
+
+ return (rc);
+}
+
+
+fsi_plugin_ops_t *
+fsi_init_plugin(int version, fsi_plugin_t *fp, const char **name)
+{
+ static fsig_plugin_ops_t ops = {
+ FSIMAGE_PLUGIN_VERSION,
+ .fpo_mount = fsi_zfs_mount,
+ .fpo_dir = fsi_zfs_open,
+ .fpo_read = fsi_zfs_read,
+ };
+
+ *name = "zfs";
+ return (fsig_init(fp, &ops));
+}
+
+#endif /* FSYS_ZFS */
diff -r 07befd9cf6d3 -r ae08db793feb tools/libfsimage/zfs/fsi_zfs.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libfsimage/zfs/fsi_zfs.h Wed Apr 14 11:56:54 2010 +0100
@@ -0,0 +1,103 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/*
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+#ifndef _FSI_ZFS_H
+#define _FSI_ZFS_H
+
+#ifdef FSYS_ZFS
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+#include <fsimage_grub.h>
+
+
+/*** START FROM shared.h ****/
+#include "mb_info.h"
+
+/* Boot signature related defines for the findroot command */
+#define BOOTSIGN_DIR "/boot/grub/bootsign"
+#define BOOTSIGN_BACKUP "/etc/bootsign"
+
+/* Maybe redirect memory requests through grub_scratch_mem. */
+#define RAW_ADDR(x) (x)
+#define RAW_SEG(x) (x)
+
+/* ZFS will use the top 4 Meg of physical memory (below 4Gig) for sratch */
+#define ZFS_SCRATCH_SIZE 0x400000
+
+#define MAXPATHLEN 1024
+#define MAXNAMELEN 256
+#define MIN(x, y) ((x) < (y) ? (x) : (y))
+
+#define MAXUINT 0xFFFFFFFF
+
+#undef NULL
+#define NULL ((void *) 0)
+
+#define grub_printf printf
+#define grub_strcmp strcmp
+#define grub_strncmp strncmp
+#define grub_strstr strstr
+#define grub_strlen strlen
+#define grub_memmove memmove
+
+extern char current_bootpath[MAXPATHLEN];
+extern char current_rootpool[MAXNAMELEN];
+extern char current_bootfs[MAXNAMELEN];
+extern uint64_t current_bootfs_obj;
+extern char current_devid[MAXPATHLEN];
+extern int is_zfs_mount;
+extern unsigned long best_drive;
+extern unsigned long best_part;
+extern int find_best_root;
+
+extern unsigned long part_length;
+
+#undef filemax
+#undef filepos
+extern uint64_t filemax;
+extern uint64_t filepos;
+
+extern struct multiboot_info mbi;
+
+/*** END FROM shared.h ***/
+
+#ifdef __linux__
+typedef unsigned char uchar_t;
+#endif
+
+typedef struct fsi_file *fsi_file_handle_t;
+extern fsi_file_handle_t zfs_ffi;
+extern int fsig_devread(fsi_file_handle_t, unsigned int, unsigned int,
+ unsigned int, char *);
+
+#undef devread
+#define devread(a, b, c, d) fsig_devread(zfs_ffi, a, b, c, d)
+
+#undef errnum
+extern int errnum;
+
+#endif /* FSI_ZFS */
+
+#endif /* !_FSI_ZFS_H */
+
diff -r 07befd9cf6d3 -r ae08db793feb tools/libfsimage/zfs/fsys_zfs.c
--- a/tools/libfsimage/zfs/fsys_zfs.c Wed Apr 14 11:29:05 2010 +0100
+++ b/tools/libfsimage/zfs/fsys_zfs.c Wed Apr 14 11:56:54 2010 +0100
@@ -17,14 +17,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
- */
-
-/*
- * All files in the zfs directory are derived from the OpenSolaris
- * zfs grub files. All files in the zfs-include directory were
- * included without changes.
*/

/*
@@ -48,59 +42,37 @@
* +--------------------------------------------+
*/

-#include <stdio.h>
-#include <strings.h>
-
-/* From "shared.h" */
-#include "mb_info.h"
-
-/* Boot signature related defines for the findroot command */
-#define BOOTSIGN_DIR "/boot/grub/bootsign"
-#define BOOTSIGN_BACKUP "/etc/bootsign"
-
-/* Maybe redirect memory requests through grub_scratch_mem. */
-#define RAW_ADDR(x) (x)
-#define RAW_SEG(x) (x)
-
-/* ZFS will use the top 4 Meg of physical memory (below 4Gig) for sratch */
-#define ZFS_SCRATCH_SIZE 0x400000
-
-#define MIN(x, y) ((x) < (y) ? (x) : (y))
-/* End from shared.h */
-
+#ifdef FSYS_ZFS
+
+#include "shared.h"
+#include "filesys.h"
#include "fsys_zfs.h"

/* cache for a file block of the currently zfs_open()-ed file */
-#define file_buf zfs_ba->zfs_file_buf
-#define file_start zfs_ba->zfs_file_start
-#define file_end zfs_ba->zfs_file_end
+static void *file_buf = NULL;
+static uint64_t file_start = 0;
+static uint64_t file_end = 0;

/* cache for a dnode block */
-#define dnode_buf zfs_ba->zfs_dnode_buf
-#define dnode_mdn zfs_ba->zfs_dnode_mdn
-#define dnode_start zfs_ba->zfs_dnode_start
-#define dnode_end zfs_ba->zfs_dnode_end
-
-#define stackbase zfs_ba->zfs_stackbase
+static dnode_phys_t *dnode_buf = NULL;
+static dnode_phys_t *dnode_mdn = NULL;
+static uint64_t dnode_start = 0;
+static uint64_t dnode_end = 0;
+
+static uint64_t pool_guid = 0;
+static uberblock_t current_uberblock;
+static char *stackbase;

decomp_entry_t decomp_table[ZIO_COMPRESS_FUNCTIONS] =
{
- {"noop", 0},
+ {"inherit", 0}, /* ZIO_COMPRESS_INHERIT */
{"on", lzjb_decompress}, /* ZIO_COMPRESS_ON */
- {"off", 0},
- {"lzjb", lzjb_decompress} /* ZIO_COMPRESS_LZJB */
+ {"off", 0}, /* ZIO_COMPRESS_OFF */
+ {"lzjb", lzjb_decompress}, /* ZIO_COMPRESS_LZJB */
+ {"empty", 0} /* ZIO_COMPRESS_EMPTY */
};

-/* From disk_io.c */
-/* ZFS root filesystem for booting */
-#define current_bootpath zfs_ba->zfs_current_bootpath
-#define current_rootpool zfs_ba->zfs_current_rootpool
-#define current_bootfs zfs_ba->zfs_current_bootfs
-#define current_bootfs_obj zfs_ba->zfs_current_bootfs_obj
-#define is_zfs_mount (*fsig_int1(ffi))
-/* End from disk_io.c */
-
-#define is_zfs_open zfs_ba->zfs_open
+static int zio_read_data(blkptr_t *bp, void *buf, char *stack);

/*
* Our own version of bcmp().
@@ -108,8 +80,8 @@ static int
static int
zfs_bcmp(const void *s1, const void *s2, size_t n)
{
- const unsigned char *ps1 = s1;
- const unsigned char *ps2 = s2;
+ const uchar_t *ps1 = s1;
+ const uchar_t *ps2 = s2;

if (s1 != s2 && n != 0) {
do {
@@ -146,15 +118,16 @@ zio_checksum_off(const void *buf, uint64

/* Checksum Table and Values */
zio_checksum_info_t zio_checksum_table[ZIO_CHECKSUM_FUNCTIONS] = {
- {{NULL, NULL}, 0, 0, "inherit"},
- {{NULL, NULL}, 0, 0, "on"},
- {{zio_checksum_off, zio_checksum_off}, 0, 0, "off"},
- {{zio_checksum_SHA256, zio_checksum_SHA256}, 1, 1, "label"},
- {{zio_checksum_SHA256, zio_checksum_SHA256}, 1, 1, "gang_header"},
- {{fletcher_2_native, fletcher_2_byteswap}, 0, 1, "zilog"},
- {{fletcher_2_native, fletcher_2_byteswap}, 0, 0, "fletcher2"},
- {{fletcher_4_native, fletcher_4_byteswap}, 1, 0, "fletcher4"},
- {{zio_checksum_SHA256, zio_checksum_SHA256}, 1, 0, "SHA256"}
+ { { NULL, NULL }, 0, 0, "inherit" },
+ { { NULL, NULL }, 0, 0, "on" },
+ { { zio_checksum_off, zio_checksum_off }, 0, 0, "off" },
+ { { zio_checksum_SHA256, zio_checksum_SHA256 }, 1, 1, "label" },
+ { { zio_checksum_SHA256, zio_checksum_SHA256 }, 1, 1, "gang_header" },
+ { { NULL, NULL }, 0, 0, "zilog" },
+ { { fletcher_2_native, fletcher_2_byteswap }, 0, 0, "fletcher2" },
+ { { fletcher_4_native, fletcher_4_byteswap }, 1, 0, "fletcher4" },
+ { { zio_checksum_SHA256, zio_checksum_SHA256 }, 1, 0, "SHA256" },
+ { { NULL, NULL }, 0, 0, "zilog2" }
};

/*
@@ -170,10 +143,9 @@ zio_checksum_verify(blkptr_t *bp, char *
zio_checksum_verify(blkptr_t *bp, char *data, int size)
{
zio_cksum_t zc = bp->blk_cksum;
- uint32_t checksum = BP_IS_GANG(bp) ? ZIO_CHECKSUM_GANG_HEADER :
- BP_GET_CHECKSUM(bp);
+ uint32_t checksum = BP_GET_CHECKSUM(bp);
int byteswap = BP_SHOULD_BYTESWAP(bp);
- zio_block_tail_t *zbt = (zio_block_tail_t *)(data + size) - 1;
+ zio_eck_t *zec = (zio_eck_t *)(data + size) - 1;
zio_checksum_info_t *ci = &zio_checksum_table[checksum];
zio_cksum_t actual_cksum, expected_cksum;

@@ -184,28 +156,14 @@ zio_checksum_verify(blkptr_t *bp, char *
if (checksum >= ZIO_CHECKSUM_FUNCTIONS || ci->ci_func[0] == NULL)
return (-1);

- if (ci->ci_zbt) {
- if (checksum == ZIO_CHECKSUM_GANG_HEADER) {
- /*
- * 'gang blocks' is not supported.
- */
- return (-1);
- }
-
- if (zbt->zbt_magic == BSWAP_64(ZBT_MAGIC)) {
- /* byte swapping is not supported */
- return (-1);
- } else {
- expected_cksum = zbt->zbt_cksum;
- zbt->zbt_cksum = zc;
- ci->ci_func[0](data, size, &actual_cksum);
- zbt->zbt_cksum = expected_cksum;
- }
+ if (ci->ci_eck) {
+ expected_cksum = zec->zec_cksum;
+ zec->zec_cksum = zc;
+ ci->ci_func[0](data, size, &actual_cksum);
+ zec->zec_cksum = expected_cksum;
zc = expected_cksum;

} else {
- if (BP_IS_GANG(bp))
- return (-1);
ci->ci_func[byteswap](data, size, &actual_cksum);
}

@@ -219,30 +177,14 @@ zio_checksum_verify(blkptr_t *bp, char *
}

/*
- * vdev_label_offset takes "offset" (the offset within a vdev_label) and
- * returns its physical disk offset (starting from the beginning of the vdev).
- *
- * Input:
- * psize : Physical size of this vdev
- * l : Label Number (0-3)
- * offset : The offset with a vdev_label in which we want the physical
- * address
- * Return:
- * Success : physical disk offset
- * Failure : errnum = ERR_BAD_ARGUMENT, return value is meaningless
+ * vdev_label_start returns the physical disk offset (in bytes) of
+ * label "l".
*/
static uint64_t
-vdev_label_offset(fsi_file_t *ffi, uint64_t psize, int l, uint64_t offset)
-{
- /* XXX Need to add back label support! */
- if (l >= VDEV_LABELS/2 || offset > sizeof (vdev_label_t)) {
- errnum = ERR_BAD_ARGUMENT;
- return (0);
- }
-
- return (offset + l * sizeof (vdev_label_t) + (l < VDEV_LABELS / 2 ?
+vdev_label_start(uint64_t psize, int l)
+{
+ return (l * sizeof (vdev_label_t) + (l < VDEV_LABELS / 2 ?
0 : psize - VDEV_LABELS * sizeof (vdev_label_t)));
-
}

/*
@@ -283,7 +225,7 @@ vdev_uberblock_compare(uberblock_t *ub1,
* -1 - Failure
*/
static int
-uberblock_verify(uberblock_phys_t *ub, int offset)
+uberblock_verify(uberblock_phys_t *ub, uint64_t offset)
{

uberblock_t *uber = &ub->ubp_uberblock;
@@ -297,7 +239,8 @@ uberblock_verify(uberblock_phys_t *ub, i
if (zio_checksum_verify(&bp, (char *)ub, UBERBLOCK_SIZE) != 0)
return (-1);

- if (uber->ub_magic == UBERBLOCK_MAGIC && uber->ub_version > 0)
+ if (uber->ub_magic == UBERBLOCK_MAGIC &&
+ uber->ub_version > 0 && uber->ub_version <= SPA_VERSION)
return (0);

return (-1);
@@ -310,16 +253,15 @@ uberblock_verify(uberblock_phys_t *ub, i
* Failure - NULL
*/
static uberblock_phys_t *
-find_bestub(fsi_file_t *ffi, uberblock_phys_t *ub_array, int label)
+find_bestub(uberblock_phys_t *ub_array, uint64_t sector)
{
uberblock_phys_t *ubbest = NULL;
- int i, offset;
+ uint64_t offset;
+ int i;

for (i = 0; i < (VDEV_UBERBLOCK_RING >> VDEV_UBERBLOCK_SHIFT); i++) {
- offset = vdev_label_offset(ffi, 0, label,
- VDEV_UBERBLOCK_OFFSET(i));
- if (errnum == ERR_BAD_ARGUMENT)
- return (NULL);
+ offset = (sector << SPA_MINBLOCKSHIFT) +
+ VDEV_UBERBLOCK_OFFSET(i);
if (uberblock_verify(&ub_array[i], offset) == 0) {
if (ubbest == NULL) {
ubbest = &ub_array[i];
@@ -335,58 +277,142 @@ find_bestub(fsi_file_t *ffi, uberblock_p
}

/*
- * Read in a block and put its uncompressed data in buf.
+ * Read a block of data based on the gang block address dva,
+ * and put its data in buf.
*
* Return:
* 0 - success
- * errnum - failure
- */
-static int
-zio_read(fsi_file_t *ffi, blkptr_t *bp, void *buf, char *stack)
-{
+ * 1 - failure
+ */
+static int
+zio_read_gang(blkptr_t *bp, dva_t *dva, void *buf, char *stack)
+{
+ zio_gbh_phys_t *zio_gb;
uint64_t offset, sector;
- int psize, lsize;
- int i, comp, cksum;
+ blkptr_t tmpbp;
+ int i;
+
+ zio_gb = (zio_gbh_phys_t *)stack;
+ stack += SPA_GANGBLOCKSIZE;
+ offset = DVA_GET_OFFSET(dva);
+ sector = DVA_OFFSET_TO_PHYS_SECTOR(offset);
+
+ /* read in the gang block header */
+ if (devread(sector, 0, SPA_GANGBLOCKSIZE, (char *)zio_gb) == 0) {
+ grub_printf("failed to read in a gang block header\n");
+ return (1);
+ }
+
+ /* self checksuming the gang block header */
+ BP_ZERO(&tmpbp);
+ BP_SET_CHECKSUM(&tmpbp, ZIO_CHECKSUM_GANG_HEADER);
+ BP_SET_BYTEORDER(&tmpbp, ZFS_HOST_BYTEORDER);
+ ZIO_SET_CHECKSUM(&tmpbp.blk_cksum, DVA_GET_VDEV(dva),
+ DVA_GET_OFFSET(dva), bp->blk_birth, 0);
+ if (zio_checksum_verify(&tmpbp, (char *)zio_gb, SPA_GANGBLOCKSIZE)) {
+ grub_printf("failed to checksum a gang block header\n");
+ return (1);
+ }
+
+ for (i = 0; i < SPA_GBH_NBLKPTRS; i++) {
+ if (zio_gb->zg_blkptr[i].blk_birth == 0)
+ continue;
+
+ if (zio_read_data(&zio_gb->zg_blkptr[i], buf, stack))
+ return (1);
+ buf += BP_GET_PSIZE(&zio_gb->zg_blkptr[i]);
+ }
+
+ return (0);
+}
+
+/*
+ * Read in a block of raw data to buf.
+ *
+ * Return:
+ * 0 - success
+ * 1 - failure
+ */
+static int
+zio_read_data(blkptr_t *bp, void *buf, char *stack)
+{
+ int i, psize;

psize = BP_GET_PSIZE(bp);
- lsize = BP_GET_LSIZE(bp);
- comp = BP_GET_COMPRESS(bp);
- cksum = BP_GET_CHECKSUM(bp);
-
- if ((unsigned int)comp >= ZIO_COMPRESS_FUNCTIONS ||
- (comp != ZIO_COMPRESS_OFF &&
- decomp_table[comp].decomp_func == NULL))
- return (ERR_FSYS_CORRUPT);

/* pick a good dva from the block pointer */
for (i = 0; i < SPA_DVAS_PER_BP; i++) {
+ uint64_t offset, sector;

if (bp->blk_dva[i].dva_word[0] == 0 &&
bp->blk_dva[i].dva_word[1] == 0)
continue;

- /* read in a block */
- offset = DVA_GET_OFFSET(&bp->blk_dva[i]);
- sector = DVA_OFFSET_TO_PHYS_SECTOR(offset);
-
- if (comp != ZIO_COMPRESS_OFF) {
-
- if (devread(ffi, sector, 0, psize, stack) == 0)
- continue;
- if (zio_checksum_verify(bp, stack, psize) != 0)
- continue;
- decomp_table[comp].decomp_func(stack, buf, psize,
- lsize);
+ if (DVA_GET_GANG(&bp->blk_dva[i])) {
+ if (zio_read_gang(bp, &bp->blk_dva[i], buf, stack) == 0)
+ return (0);
} else {
- if (devread(ffi, sector, 0, psize, buf) == 0)
- continue;
- if (zio_checksum_verify(bp, buf, psize) != 0)
- continue;
+ /* read in a data block */
+ offset = DVA_GET_OFFSET(&bp->blk_dva[i]);
+ sector = DVA_OFFSET_TO_PHYS_SECTOR(offset);
+ if (devread(sector, 0, psize, buf))
+ return (0);
}
- return (0);
- }
-
- return (ERR_FSYS_CORRUPT);
+ }
+
+ return (1);
+}
+
+/*
+ * Read in a block of data, verify its checksum, decompress if needed,
+ * and put the uncompressed data in buf.
+ *
+ * Return:
+ * 0 - success
+ * errnum - failure
+ */
+static int
+zio_read(blkptr_t *bp, void *buf, char *stack)
+{
+ int lsize, psize, comp;
+ char *retbuf;
+
+ comp = BP_GET_COMPRESS(bp);
+ lsize = BP_GET_LSIZE(bp);
+ psize = BP_GET_PSIZE(bp);
+
+ if ((unsigned int)comp >= ZIO_COMPRESS_FUNCTIONS ||
+ (comp != ZIO_COMPRESS_OFF &&
+ decomp_table[comp].decomp_func == NULL)) {
+ grub_printf("compression algorithm not supported\n");
+ return (ERR_FSYS_CORRUPT);
+ }
+
+ if ((char *)buf < stack && ((char *)buf) + lsize > stack) {
+ grub_printf("not enough memory allocated\n");
+ return (ERR_WONT_FIT);
+ }
+
+ retbuf = buf;
+ if (comp != ZIO_COMPRESS_OFF) {
+ buf = stack;
+ stack += psize;
+ }
+
+ if (zio_read_data(bp, buf, stack)) {
+ grub_printf("zio_read_data failed\n");
+ return (ERR_FSYS_CORRUPT);
+ }
+
+ if (zio_checksum_verify(bp, buf, psize) != 0) {
+ grub_printf("checksum verification failed\n");
+ return (ERR_FSYS_CORRUPT);
+ }
+
+ if (comp != ZIO_COMPRESS_OFF)
+ decomp_table[comp].decomp_func(buf, retbuf, psize, lsize);
+
+ return (0);
}

/*
@@ -398,8 +424,7 @@ zio_read(fsi_file_t *ffi, blkptr_t *bp,
* errnum - failure
*/
static int
-dmu_read(fsi_file_t *ffi, dnode_phys_t *dn, uint64_t blkid, void *buf,
- char *stack)
+dmu_read(dnode_phys_t *dn, uint64_t blkid, void *buf, char *stack)
{
int idx, level;
blkptr_t *bp_array = dn->dn_blkptr;
@@ -421,9 +446,10 @@ dmu_read(fsi_file_t *ffi, dnode_phys_t *
grub_memset(buf, 0,
dn->dn_datablkszsec << SPA_MINBLOCKSHIFT);
break;
- } else if ((errnum = zio_read(ffi, bp, tmpbuf, stack))) {
+ } else if ((errnum = zio_read(bp, tmpbuf, stack))) {
return (errnum);
}
+
bp_array = tmpbuf;
}

@@ -447,7 +473,7 @@ mzap_lookup(mzap_phys_t *zapobj, int obj

chunks = objsize/MZAP_ENT_LEN - 1;
for (i = 0; i < chunks; i++) {
- if (strcmp(mzap_ent[i].mze_name, name) == 0) {
+ if (grub_strcmp(mzap_ent[i].mze_name, name) == 0) {
*value = mzap_ent[i].mze_value;
return (0);
}
@@ -457,7 +483,7 @@ mzap_lookup(mzap_phys_t *zapobj, int obj
}

static uint64_t
-zap_hash(fsi_file_t *ffi, uint64_t salt, const char *name)
+zap_hash(uint64_t salt, const char *name)
{
static uint64_t table[256];
const uint8_t *cp;
@@ -488,7 +514,7 @@ zap_hash(fsi_file_t *ffi, uint64_t salt,
* those are the onces that we first pay attention to when
* chosing the bucket.
*/
- crc &= ~((1ULL << (64 - ZAP_HASHBITS)) - 1);
+ crc &= ~((1ULL << (64 - 28)) - 1);

return (crc);
}
@@ -590,7 +616,7 @@ zap_leaf_lookup(zap_leaf_phys_t *l, int
* errnum - failure
*/
static int
-fzap_lookup(fsi_file_t *ffi, dnode_phys_t *zap_dnode, zap_phys_t *zap,
+fzap_lookup(dnode_phys_t *zap_dnode, zap_phys_t *zap,
char *name, uint64_t *value, char *stack)
{
zap_leaf_phys_t *l;
@@ -598,10 +624,11 @@ fzap_lookup(fsi_file_t *ffi, dnode_phys_
int blksft = zfs_log2(zap_dnode->dn_datablkszsec << DNODE_SHIFT);

/* Verify if this is a fat zap header block */
- if (zap->zap_magic != (uint64_t)ZAP_MAGIC)
- return (ERR_FSYS_CORRUPT);
-
- hash = zap_hash(ffi, zap->zap_salt, name);
+ if (zap->zap_magic != (uint64_t)ZAP_MAGIC ||
+ zap->zap_flags != 0)
+ return (ERR_FSYS_CORRUPT);
+
+ hash = zap_hash(zap->zap_salt, name);
if (errnum)
return (errnum);

@@ -616,7 +643,9 @@ fzap_lookup(fsi_file_t *ffi, dnode_phys_
/* Get the leaf block */
l = (zap_leaf_phys_t *)stack;
stack += 1<<blksft;
- if ((errnum = dmu_read(ffi, zap_dnode, blkid, l, stack)))
+ if ((1<<blksft) < sizeof (zap_leaf_phys_t))
+ return (ERR_FSYS_CORRUPT);
+ if ((errnum = dmu_read(zap_dnode, blkid, l, stack)))
return (errnum);

return (zap_leaf_lookup(l, blksft, hash, name, value));
@@ -631,8 +660,7 @@ fzap_lookup(fsi_file_t *ffi, dnode_phys_
* errnum - failure
*/
static int
-zap_lookup(fsi_file_t *ffi, dnode_phys_t *zap_dnode, char *name,
- uint64_t *val, char *stack)
+zap_lookup(dnode_phys_t *zap_dnode, char *name, uint64_t *val, char *stack)
{
uint64_t block_type;
int size;
@@ -642,7 +670,8 @@ zap_lookup(fsi_file_t *ffi, dnode_phys_t
zapbuf = stack;
size = zap_dnode->dn_datablkszsec << SPA_MINBLOCKSHIFT;
stack += size;
- if ((errnum = dmu_read(ffi, zap_dnode, 0, zapbuf, stack)))
+
+ if ((errnum = dmu_read(zap_dnode, 0, zapbuf, stack)))
return (errnum);

block_type = *((uint64_t *)zapbuf);
@@ -651,7 +680,7 @@ zap_lookup(fsi_file_t *ffi, dnode_phys_t
return (mzap_lookup(zapbuf, size, name, val));
} else if (block_type == ZBT_HEADER) {
/* this is a fat zap */
- return (fzap_lookup(ffi, zap_dnode, zapbuf, name,
+ return (fzap_lookup(zap_dnode, zapbuf, name,
val, stack));
}

@@ -672,14 +701,13 @@ zap_lookup(fsi_file_t *ffi, dnode_phys_t
* errnum - failure
*/
static int
-dnode_get(fsi_file_t *ffi, dnode_phys_t *mdn, uint64_t objnum,
- uint8_t type, dnode_phys_t *buf, char *stack)
+dnode_get(dnode_phys_t *mdn, uint64_t objnum, uint8_t type, dnode_phys_t *buf,
+ char *stack)
{
uint64_t blkid, blksz; /* the block id this object dnode is in */
int epbs; /* shift of number of dnodes in a block */
int idx; /* index within a block */
dnode_phys_t *dnbuf;
- zfs_bootarea_t *zfs_ba = (zfs_bootarea_t *)ffi->ff_fsi->f_data;

blksz = mdn->dn_datablkszsec << SPA_MINBLOCKSHIFT;
epbs = zfs_log2(blksz) - DNODE_SHIFT;
@@ -703,7 +731,7 @@ dnode_get(fsi_file_t *ffi, dnode_phys_t
stack += blksz;
}

- if ((errnum = dmu_read(ffi, mdn, blkid, (char *)dnbuf, stack)))
+ if ((errnum = dmu_read(mdn, blkid, (char *)dnbuf, stack)))
return (errnum);

grub_memmove(buf, &dnbuf[idx], DNODE_SIZE);
@@ -723,16 +751,16 @@ is_top_dataset_file(char *str)
{
char *tptr;

- if (((tptr = strstr(str, "menu.lst"))) &&
+ if ((tptr = grub_strstr(str, "menu.lst")) &&
(tptr[8] == '\0' || tptr[8] == ' ') &&
*(tptr-1) == '/')
return (1);

- if (strncmp(str, BOOTSIGN_DIR"/",
- strlen(BOOTSIGN_DIR) + 1) == 0)
+ if (grub_strncmp(str, BOOTSIGN_DIR"/",
+ grub_strlen(BOOTSIGN_DIR) + 1) == 0)
return (1);

- if (strcmp(str, BOOTSIGN_BACKUP) == 0)
+ if (grub_strcmp(str, BOOTSIGN_BACKUP) == 0)
return (1);

return (0);
@@ -748,23 +776,25 @@ is_top_dataset_file(char *str)
* errnum - failure
*/
static int
-dnode_get_path(fsi_file_t *ffi, dnode_phys_t *mdn, char *path,
- dnode_phys_t *dn, char *stack)
+dnode_get_path(dnode_phys_t *mdn, char *path, dnode_phys_t *dn,
+ char *stack)
{
uint64_t objnum, version;
char *cname, ch;

- if ((errnum = dnode_get(ffi, mdn, MASTER_NODE_OBJ, DMU_OT_MASTER_NODE,
+ if ((errnum = dnode_get(mdn, MASTER_NODE_OBJ, DMU_OT_MASTER_NODE,
dn, stack)))
return (errnum);

- if ((errnum = zap_lookup(ffi, dn, ZPL_VERSION_STR, &version, stack)))
+ if ((errnum = zap_lookup(dn, ZPL_VERSION_STR, &version, stack)))
return (errnum);
-
- if ((errnum = zap_lookup(ffi, dn, ZFS_ROOT_OBJ, &objnum, stack)))
+ if (version > ZPL_VERSION)
+ return (-1);
+
+ if ((errnum = zap_lookup(dn, ZFS_ROOT_OBJ, &objnum, stack)))
return (errnum);

- if ((errnum = dnode_get(ffi, mdn, objnum, DMU_OT_DIRECTORY_CONTENTS,
+ if ((errnum = dnode_get(mdn, objnum, DMU_OT_DIRECTORY_CONTENTS,
dn, stack)))
return (errnum);

@@ -772,20 +802,20 @@ dnode_get_path(fsi_file_t *ffi, dnode_ph
while (*path == '/')
path++;

- while (*path && !isspace((uint8_t)*path)) {
+ while (*path && !isspace(*path)) {

/* get the next component name */
cname = path;
- while (*path && !isspace((uint8_t)*path) && *path != '/')
+ while (*path && !isspace(*path) && *path != '/')
path++;
ch = *path;
*path = 0; /* ensure null termination */

- if ((errnum = zap_lookup(ffi, dn, cname, &objnum, stack)))
+ if ((errnum = zap_lookup(dn, cname, &objnum, stack)))
return (errnum);

objnum = ZFS_DIRENT_OBJ(objnum);
- if ((errnum = dnode_get(ffi, mdn, objnum, 0, dn, stack)))
+ if ((errnum = dnode_get(mdn, objnum, 0, dn, stack)))
return (errnum);

*path = ch;
@@ -807,14 +837,13 @@ dnode_get_path(fsi_file_t *ffi, dnode_ph
* errnum -failure
*/
static int
-get_default_bootfsobj(fsi_file_t *ffi, dnode_phys_t *mosmdn,
- uint64_t *obj, char *stack)
+get_default_bootfsobj(dnode_phys_t *mosmdn, uint64_t *obj, char *stack)
{
uint64_t objnum = 0;
dnode_phys_t *dn = (dnode_phys_t *)stack;
stack += DNODE_SIZE;

- if ((errnum = dnode_get(ffi, mosmdn, DMU_POOL_DIRECTORY_OBJECT,
+ if ((errnum = dnode_get(mosmdn, DMU_POOL_DIRECTORY_OBJECT,
DMU_OT_OBJECT_DIRECTORY, dn, stack)))
return (errnum);

@@ -822,19 +851,17 @@ get_default_bootfsobj(fsi_file_t *ffi, d
* find the object number for 'pool_props', and get the dnode
* of the 'pool_props'.
*/
- if (zap_lookup(ffi, dn, DMU_POOL_PROPS, &objnum, stack))
+ if (zap_lookup(dn, DMU_POOL_PROPS, &objnum, stack))
return (ERR_FILESYSTEM_NOT_FOUND);

- if ((errnum = dnode_get(ffi, mosmdn, objnum, DMU_OT_POOL_PROPS, dn,
- stack)))
+ if ((errnum = dnode_get(mosmdn, objnum, DMU_OT_POOL_PROPS, dn, stack)))
return (errnum);

- if (zap_lookup(ffi, dn, ZPOOL_PROP_BOOTFS, &objnum, stack))
+ if (zap_lookup(dn, ZPOOL_PROP_BOOTFS, &objnum, stack))
return (ERR_FILESYSTEM_NOT_FOUND);

if (!objnum)
return (ERR_FILESYSTEM_NOT_FOUND);
-

*obj = objnum;
return (0);
@@ -854,29 +881,30 @@ get_default_bootfsobj(fsi_file_t *ffi, d
* errnum - failure
*/
static int
-get_objset_mdn(fsi_file_t *ffi, dnode_phys_t *mosmdn, char *fsname,
- uint64_t *obj, dnode_phys_t *mdn, char *stack)
+get_objset_mdn(dnode_phys_t *mosmdn, char *fsname, uint64_t *obj,
+ dnode_phys_t *mdn, char *stack)
{
uint64_t objnum, headobj;
char *cname, ch;
blkptr_t *bp;
objset_phys_t *osp;
+ int issnapshot = 0;
+ char *snapname = NULL;

if (fsname == NULL && obj) {
headobj = *obj;
goto skip;
}

- if ((errnum = dnode_get(ffi, mosmdn, DMU_POOL_DIRECTORY_OBJECT,
+ if ((errnum = dnode_get(mosmdn, DMU_POOL_DIRECTORY_OBJECT,
DMU_OT_OBJECT_DIRECTORY, mdn, stack)))
return (errnum);

- if ((errnum = zap_lookup(ffi, mdn, DMU_POOL_ROOT_DATASET, &objnum,
+ if ((errnum = zap_lookup(mdn, DMU_POOL_ROOT_DATASET, &objnum,
stack)))
return (errnum);

- if ((errnum = dnode_get(ffi, mosmdn, objnum, DMU_OT_DSL_DIR, mdn,
- stack)))
+ if ((errnum = dnode_get(mosmdn, objnum, DMU_OT_DSL_DIR, mdn, stack)))
return (errnum);

if (fsname == NULL) {
@@ -886,51 +914,74 @@ get_objset_mdn(fsi_file_t *ffi, dnode_ph
}

/* take out the pool name */
- while (*fsname && !isspace((uint8_t)*fsname) && *fsname != '/')
+ while (*fsname && !isspace(*fsname) && *fsname != '/')
fsname++;

- while (*fsname && !isspace((uint8_t)*fsname)) {
+ while (*fsname && !isspace(*fsname)) {
uint64_t childobj;

while (*fsname == '/')
fsname++;

cname = fsname;
- while (*fsname && !isspace((uint8_t)*fsname) && *fsname != '/')
+ while (*fsname && !isspace(*fsname) && *fsname != '/')
fsname++;
ch = *fsname;
*fsname = 0;

+ snapname = cname;
+ while (*snapname && !isspace(*snapname) && *snapname != '@')
+ snapname++;
+ if (*snapname == '@') {
+ issnapshot = 1;
+ *snapname = 0;
+ }
childobj =
((dsl_dir_phys_t *)DN_BONUS(mdn))->dd_child_dir_zapobj;
- if ((errnum = dnode_get(ffi, mosmdn, childobj,
+ if ((errnum = dnode_get(mosmdn, childobj,
DMU_OT_DSL_DIR_CHILD_MAP, mdn, stack)))
return (errnum);

- if (zap_lookup(ffi, mdn, cname, &objnum, stack))
+ if (zap_lookup(mdn, cname, &objnum, stack))
return (ERR_FILESYSTEM_NOT_FOUND);

- if ((errnum = dnode_get(ffi, mosmdn, objnum, DMU_OT_DSL_DIR,
+ if ((errnum = dnode_get(mosmdn, objnum, DMU_OT_DSL_DIR,
mdn, stack)))
return (errnum);

*fsname = ch;
+ if (issnapshot)
+ *snapname = '@';
}
headobj = ((dsl_dir_phys_t *)DN_BONUS(mdn))->dd_head_dataset_obj;
if (obj)
*obj = headobj;

skip:
- if ((errnum = dnode_get(ffi, mosmdn, headobj, DMU_OT_DSL_DATASET, mdn,
- stack)))
+ if ((errnum = dnode_get(mosmdn, headobj, DMU_OT_DSL_DATASET, mdn, stack)))
return (errnum);
-
- /* TODO: Add snapshot support here - for fsname=snapshot-name */
+ if (issnapshot) {
+ uint64_t snapobj;
+
+ snapobj = ((dsl_dataset_phys_t *)DN_BONUS(mdn))->
+ ds_snapnames_zapobj;
+
+ if ((errnum = dnode_get(mosmdn, snapobj,
+ DMU_OT_DSL_DS_SNAP_MAP, mdn, stack)))
+ return (errnum);
+ if (zap_lookup(mdn, snapname + 1, &headobj, stack))
+ return (ERR_FILESYSTEM_NOT_FOUND);
+ if ((errnum = dnode_get(mosmdn, headobj,
+ DMU_OT_DSL_DATASET, mdn, stack)))
+ return (errnum);
+ if (obj)
+ *obj = headobj;
+ }

bp = &((dsl_dataset_phys_t *)DN_BONUS(mdn))->ds_bp;
osp = (objset_phys_t *)stack;
stack += sizeof (objset_phys_t);
- if ((errnum = zio_read(ffi, bp, osp, stack)))
+ if ((errnum = zio_read(bp, osp, stack)))
return (errnum);

grub_memmove((char *)mdn, (char *)&osp->os_meta_dnode, DNODE_SIZE);
@@ -1019,11 +1070,11 @@ nvlist_lookup_value(char *nvlist, char *
type = BSWAP_32(*(uint32_t *)nvpair);
nvpair += 4;

- if (((strncmp(nvp_name, name, name_len) == 0) &&
- type == valtype)) {
+ if ((grub_strncmp(nvp_name, name, name_len) == 0) &&
+ type == valtype) {
int nelm;

- if (((nelm = BSWAP_32(*(uint32_t *)nvpair)) < 1))
+ if ((nelm = BSWAP_32(*(uint32_t *)nvpair)) < 1)
return (1);
nvpair += 4;

@@ -1069,8 +1120,6 @@ vdev_validate(char *nv)
DATA_TYPE_UINT64, NULL) == 0 ||
nvlist_lookup_value(nv, ZPOOL_CONFIG_FAULTED, &ival,
DATA_TYPE_UINT64, NULL) == 0 ||
- nvlist_lookup_value(nv, ZPOOL_CONFIG_DEGRADED, &ival,
- DATA_TYPE_UINT64, NULL) == 0 ||
nvlist_lookup_value(nv, ZPOOL_CONFIG_REMOVED, &ival,
DATA_TYPE_UINT64, NULL) == 0)
return (ERR_DEV_VALUES);
@@ -1079,26 +1128,58 @@ vdev_validate(char *nv)
}

/*
- * Get a list of valid vdev pathname from the boot device.
- * The caller should already allocate MAXNAMELEN memory for bootpath.
- */
-static int
-vdev_get_bootpath(char *nv, char *bootpath)
+ * Get a valid vdev pathname/devid from the boot device.
+ * The caller should already allocate MAXPATHLEN memory for bootpath and devid.
+ */
+static int
+vdev_get_bootpath(char *nv, uint64_t inguid, char *devid, char *bootpath,
+ int is_spare)
{
char type[16];

- bootpath[0] = '\0';
if (nvlist_lookup_value(nv, ZPOOL_CONFIG_TYPE, &type, DATA_TYPE_STRING,
NULL))
return (ERR_FSYS_CORRUPT);

if (strcmp(type, VDEV_TYPE_DISK) == 0) {
- if (vdev_validate(nv) != 0 ||
- nvlist_lookup_value(nv, ZPOOL_CONFIG_PHYS_PATH, bootpath,
- DATA_TYPE_STRING, NULL) != 0)
+ uint64_t guid;
+
+ if (vdev_validate(nv) != 0)
return (ERR_NO_BOOTPATH);

- } else if (strcmp(type, VDEV_TYPE_MIRROR) == 0) {
+ if (nvlist_lookup_value(nv, ZPOOL_CONFIG_GUID,
+ &guid, DATA_TYPE_UINT64, NULL) != 0)
+ return (ERR_NO_BOOTPATH);
+
+ if (guid != inguid)
+ return (ERR_NO_BOOTPATH);
+
+ /* for a spare vdev, pick the disk labeled with "is_spare" */
+ if (is_spare) {
+ uint64_t spare = 0;
+ (void) nvlist_lookup_value(nv, ZPOOL_CONFIG_IS_SPARE,
+ &spare, DATA_TYPE_UINT64, NULL);
+ if (!spare)
+ return (ERR_NO_BOOTPATH);
+ }
+
+ if (nvlist_lookup_value(nv, ZPOOL_CONFIG_PHYS_PATH,
+ bootpath, DATA_TYPE_STRING, NULL) != 0)
+ bootpath[0] = '\0';
+
+ if (nvlist_lookup_value(nv, ZPOOL_CONFIG_DEVID,
+ devid, DATA_TYPE_STRING, NULL) != 0)
+ devid[0] = '\0';
+
+ if (strlen(bootpath) >= MAXPATHLEN ||
+ strlen(devid) >= MAXPATHLEN)
+ return (ERR_WONT_FIT);
+
+ return (0);
+
+ } else if (strcmp(type, VDEV_TYPE_MIRROR) == 0 ||
+ strcmp(type, VDEV_TYPE_REPLACING) == 0 ||
+ (is_spare = (strcmp(type, VDEV_TYPE_SPARE) == 0))) {
int nelm, i;
char *child;

@@ -1107,28 +1188,16 @@ vdev_get_bootpath(char *nv, char *bootpa
return (ERR_FSYS_CORRUPT);

for (i = 0; i < nelm; i++) {
- char tmp_path[MAXNAMELEN];
char *child_i;

child_i = nvlist_array(child, i);
- if (vdev_validate(child_i) != 0)
- continue;
-
- if (nvlist_lookup_value(child_i, ZPOOL_CONFIG_PHYS_PATH,
- tmp_path, DATA_TYPE_STRING, NULL) != 0)
- return (ERR_NO_BOOTPATH);
-
- if ((strlen(bootpath) + strlen(tmp_path)) > MAXNAMELEN)
- return (ERR_WONT_FIT);
-
- if (strlen(bootpath) == 0)
- sprintf(bootpath, "%s", tmp_path);
- else
- sprintf(bootpath, "%s %s", bootpath, tmp_path);
+ if (vdev_get_bootpath(child_i, inguid, devid,
+ bootpath, is_spare) == 0)
+ return (0);
}
}

- return (strlen(bootpath) > 0 ? 0 : ERR_NO_BOOTPATH);
+ return (ERR_NO_BOOTPATH);
}

/*
@@ -1138,22 +1207,24 @@ vdev_get_bootpath(char *nv, char *bootpa
* 0 - success
* ERR_* - failure
*/
-static int
-check_pool_label(fsi_file_t *ffi, int label, char *stack)
+int
+check_pool_label(uint64_t sector, char *stack, char *outdevid,
+ char *outpath, uint64_t *outguid)
{
vdev_phys_t *vdev;
- uint64_t sector, pool_state, txg = 0;
+ uint64_t pool_state, txg = 0;
char *nvlist, *nv;
- zfs_bootarea_t *zfs_ba = (zfs_bootarea_t *)ffi->ff_fsi->f_data;
-
- sector = (label * sizeof (vdev_label_t) + VDEV_SKIP_SIZE +
- VDEV_BOOT_HEADER_SIZE) >> SPA_MINBLOCKSHIFT;
+ uint64_t diskguid;
+ uint64_t version;
+
+ sector += (VDEV_SKIP_SIZE >> SPA_MINBLOCKSHIFT);

/* Read in the vdev name-value pair list (112K). */
- if (devread(ffi, sector, 0, VDEV_PHYS_SIZE, stack) == 0)
+ if (devread(sector, 0, VDEV_PHYS_SIZE, stack) == 0)
return (ERR_READ);

vdev = (vdev_phys_t *)stack;
+ stack += sizeof (vdev_phys_t);

if (nvlist_unpack(vdev->vp_nvlist, &nvlist))
return (ERR_FSYS_CORRUPT);
@@ -1177,13 +1248,22 @@ check_pool_label(fsi_file_t *ffi, int la
if (txg == 0)
return (ERR_NO_BOOTPATH);

+ if (nvlist_lookup_value(nvlist, ZPOOL_CONFIG_VERSION, &version,
+ DATA_TYPE_UINT64, NULL))
+ return (ERR_FSYS_CORRUPT);
+ if (version > SPA_VERSION)
+ return (ERR_NEWER_VERSION);
if (nvlist_lookup_value(nvlist, ZPOOL_CONFIG_VDEV_TREE, &nv,
DATA_TYPE_NVLIST, NULL))
return (ERR_FSYS_CORRUPT);
-
- if (vdev_get_bootpath(nv, current_bootpath))
+ if (nvlist_lookup_value(nvlist, ZPOOL_CONFIG_GUID, &diskguid,
+ DATA_TYPE_UINT64, NULL))
+ return (ERR_FSYS_CORRUPT);
+ if (vdev_get_bootpath(nv, diskguid, outdevid, outpath, 0))
return (ERR_NO_BOOTPATH);
-
+ if (nvlist_lookup_value(nvlist, ZPOOL_CONFIG_POOL_GUID, outguid,
+ DATA_TYPE_UINT64, NULL))
+ return (ERR_FSYS_CORRUPT);
return (0);
}

@@ -1195,34 +1275,23 @@ check_pool_label(fsi_file_t *ffi, int la
* 1 - success
* 0 - failure
*/
-static int
-zfs_mount(fsi_file_t *ffi, const char *options)
+int
+zfs_mount(void)
{
char *stack;
int label = 0;
- uberblock_phys_t *ub_array, *ubbest = NULL;
+ uberblock_phys_t *ub_array, *ubbest;
objset_phys_t *osp;
- zfs_bootarea_t *zfs_ba;
-
- /* if zfs is already mounted, don't do it again */
- if (is_zfs_mount == 1)
- return (1);
-
- /* get much bigger data block for zfs */
- if (((zfs_ba = malloc(sizeof (zfs_bootarea_t))) == NULL)) {
- return (1);
- }
- bzero(zfs_ba, sizeof (zfs_bootarea_t));
-
- /* replace small data area in fsi with big one */
- free(ffi->ff_fsi->f_data);
- ffi->ff_fsi->f_data = (void *)zfs_ba;
-
- /* If an boot filesystem is passed in, set it to current_bootfs */
- if (options != NULL) {
- if (strlen(options) < MAXNAMELEN) {
- strcpy(current_bootfs, options);
- }
+ char tmp_bootpath[MAXNAMELEN];
+ char tmp_devid[MAXNAMELEN];
+ uint64_t tmp_guid;
+ uint64_t adjpl = (uint64_t)part_length << SPA_MINBLOCKSHIFT;
+ int err = errnum; /* preserve previous errnum state */
+
+ /* if it's our first time here, zero the best uberblock out */
+ if (best_drive == 0 && best_part == 0 && find_best_root) {
+ grub_memset(&current_uberblock, 0, sizeof (uberblock_t));
+ pool_guid = 0;
}

stackbase = ZFS_SCRATCH;
@@ -1232,43 +1301,71 @@ zfs_mount(fsi_file_t *ffi, const char *o

osp = (objset_phys_t *)stack;
stack += sizeof (objset_phys_t);
-
- /* XXX add back labels support? */
- for (label = 0; ubbest == NULL && label < (VDEV_LABELS/2); label++) {
- uint64_t sector = (label * sizeof (vdev_label_t) +
- VDEV_SKIP_SIZE + VDEV_BOOT_HEADER_SIZE +
- VDEV_PHYS_SIZE) >> SPA_MINBLOCKSHIFT;
-
+ adjpl = P2ALIGN(adjpl, (uint64_t)sizeof (vdev_label_t));
+
+ for (label = 0; label < VDEV_LABELS; label++) {
+
+ uint64_t sector;
+
+ /*
+ * some eltorito stacks don't give us a size and
+ * we end up setting the size to MAXUINT, further
+ * some of these devices stop working once a single
+ * read past the end has been issued. Checking
+ * for a maximum part_length and skipping the backup
+ * labels at the end of the slice/partition/device
+ * avoids breaking down on such devices.
+ */
+ if (part_length == MAXUINT && label == 2)
+ break;
+
+ sector = vdev_label_start(adjpl,
+ label) >> SPA_MINBLOCKSHIFT;

/* Read in the uberblock ring (128K). */
- if (devread(ffi, sector, 0, VDEV_UBERBLOCK_RING,
+ if (devread(sector +
+ ((VDEV_SKIP_SIZE + VDEV_PHYS_SIZE) >>
+ SPA_MINBLOCKSHIFT), 0, VDEV_UBERBLOCK_RING,
(char *)ub_array) == 0)
continue;

- if ((ubbest = find_bestub(ffi, ub_array, label)) != NULL &&
- zio_read(ffi, &ubbest->ubp_uberblock.ub_rootbp, osp, stack)
+ if ((ubbest = find_bestub(ub_array, sector)) != NULL &&
+ zio_read(&ubbest->ubp_uberblock.ub_rootbp, osp, stack)
== 0) {

VERIFY_OS_TYPE(osp, DMU_OST_META);
+
+ if (check_pool_label(sector, stack, tmp_devid,
+ tmp_bootpath, &tmp_guid))
+ continue;
+ if (pool_guid == 0)
+ pool_guid = tmp_guid;
+
+ if (find_best_root && ((pool_guid != tmp_guid) ||
+ vdev_uberblock_compare(&ubbest->ubp_uberblock,
+ &(current_uberblock)) <= 0))
+ continue;

/* Got the MOS. Save it at the memory addr MOS. */
grub_memmove(MOS, &osp->os_meta_dnode, DNODE_SIZE);
-
- if (check_pool_label(ffi, label, stack))
- return (0);
-
- /*
- * Copy fsi->f_data to ffi->ff_data since
- * fsig_mount copies from ff_data to f_data
- * overwriting fsi->f_data.
- */
- bcopy(zfs_ba, fsig_file_buf(ffi), FSYS_BUFLEN);
-
+ grub_memmove(&current_uberblock,
+ &ubbest->ubp_uberblock, sizeof (uberblock_t));
+ grub_memmove(current_bootpath, tmp_bootpath,
+ MAXNAMELEN);
+ grub_memmove(current_devid, tmp_devid,
+ grub_strlen(tmp_devid));
is_zfs_mount = 1;
return (1);
}
}

+ /*
+ * While some fs impls. (tftp) rely on setting and keeping
+ * global errnums set, others won't reset it and will break
+ * when issuing rawreads. The goal here is to simply not
+ * have zfs mount attempts impact the previous state.
+ */
+ errnum = err;
return (0);
}

@@ -1280,13 +1377,11 @@ zfs_mount(fsi_file_t *ffi, const char *o
* 1 - success
* 0 - failure
*/
-static int
-zfs_open(fsi_file_t *ffi, char *filename)
+int
+zfs_open(char *filename)
{
char *stack;
dnode_phys_t *mdn;
- char *bootstring;
- zfs_bootarea_t *zfs_ba = (zfs_bootarea_t *)ffi->ff_fsi->f_data;

file_buf = NULL;
stackbase = ZFS_SCRATCH;
@@ -1304,62 +1399,72 @@ zfs_open(fsi_file_t *ffi, char *filename
* do not goto 'current_bootfs'.
*/
if (is_top_dataset_file(filename)) {
- if ((errnum = get_objset_mdn(ffi, MOS, NULL, NULL, mdn, stack)))
+ if ((errnum = get_objset_mdn(MOS, NULL, NULL, mdn, stack)))
return (0);

current_bootfs_obj = 0;
} else {
if (current_bootfs[0] == '\0') {
/* Get the default root filesystem object number */
- if ((errnum = get_default_bootfsobj(ffi, MOS,
+ if ((errnum = get_default_bootfsobj(MOS,
&current_bootfs_obj, stack)))
return (0);
- if ((errnum = get_objset_mdn(ffi, MOS, NULL,
+
+ if ((errnum = get_objset_mdn(MOS, NULL,
&current_bootfs_obj, mdn, stack)))
return (0);
} else {
- if ((errnum = get_objset_mdn(ffi, MOS,
- current_bootfs, &current_bootfs_obj, mdn, stack)))
+ if ((errnum = get_objset_mdn(MOS, current_bootfs,
+ &current_bootfs_obj, mdn, stack))) {
+ grub_memset(current_bootfs, 0, MAXNAMELEN);
return (0);
- }
-
- /*
- * Put zfs rootpool and boot obj number into bootstring.
- */
- if (is_zfs_open == 0) {
- char temp[25]; /* needs to hold long long */
- int alloc_size;
- char zfs_bootstr[] = "zfs-bootfs=";
- char zfs_bootpath[] = ",bootpath='";
-
- snprintf(temp, sizeof(temp), "%llu", (unsigned long long)
- current_bootfs_obj);
- alloc_size = strlen(zfs_bootstr) +
- strlen(current_rootpool) +
- strlen(temp) + strlen(zfs_bootpath) +
- strlen(current_bootpath) + 3;
- bootstring = fsi_bootstring_alloc(ffi->ff_fsi,
- alloc_size);
- if (bootstring != NULL) {
- strcpy(bootstring, zfs_bootstr);
- strcat(bootstring, current_rootpool);
- strcat(bootstring, "/");
- strcat(bootstring, temp);
- strcat(bootstring, zfs_bootpath);
- strcat(bootstring, current_bootpath);
- strcat(bootstring, "'");
- is_zfs_open = 1;
}
}
}

- if (dnode_get_path(ffi, mdn, filename, DNODE, stack)) {
+ if (dnode_get_path(mdn, filename, DNODE, stack)) {
errnum = ERR_FILE_NOT_FOUND;
return (0);
}

/* get the file size and set the file position to 0 */
- filemax = ((znode_phys_t *)DN_BONUS(DNODE))->zp_size;
+
+ /*
+ * For DMU_OT_SA we will need to locate the SIZE attribute
+ * attribute, which could be either in the bonus buffer
+ * or the "spill" block.
+ */
+ if (DNODE->dn_bonustype == DMU_OT_SA) {
+ sa_hdr_phys_t *sahdrp;
+ int hdrsize;
+
+ if (DNODE->dn_bonuslen != 0) {
+ sahdrp = (sa_hdr_phys_t *)DN_BONUS(DNODE);
+ } else {
+ if (DNODE->dn_flags & DNODE_FLAG_SPILL_BLKPTR) {
+ blkptr_t *bp = &DNODE->dn_spill;
+ void *buf;
+
+ buf = (void *)stack;
+ stack += BP_GET_LSIZE(bp);
+
+ /* reset errnum to rawread() failure */
+ errnum = 0;
+ if (zio_read(bp, buf, stack) != 0) {
+ return (0);
+ }
+ sahdrp = buf;
+ } else {
+ errnum = ERR_FSYS_CORRUPT;
+ return (0);
+ }
+ }
+ hdrsize = SA_HDR_SIZE(sahdrp);
+ filemax = *(uint64_t *)((char *)sahdrp + hdrsize +
+ SA_SIZE_OFFSET);
+ } else {
+ filemax = ((znode_phys_t *)DN_BONUS(DNODE))->zp_size;
+ }
filepos = 0;

dnode_buf = NULL;
@@ -1373,12 +1478,11 @@ zfs_open(fsi_file_t *ffi, char *filename
* len - the length successfully read in to the buffer
* 0 - failure
*/
-static int
-zfs_read(fsi_file_t *ffi, char *buf, int len)
+int
+zfs_read(char *buf, int len)
{
char *stack;
int blksz, length, movesize;
- zfs_bootarea_t *zfs_ba = (zfs_bootarea_t *)ffi->ff_fsi->f_data;

if (file_buf == NULL) {
file_buf = stackbase;
@@ -1411,7 +1515,7 @@ zfs_read(fsi_file_t *ffi, char *buf, int
*/
uint64_t blkid = filepos / blksz;

- if ((errnum = dmu_read(ffi, DNODE, blkid, file_buf, stack)))
+ if ((errnum = dmu_read(DNODE, blkid, file_buf, stack)))
return (0);

file_start = blkid * blksz;
@@ -1438,16 +1542,4 @@ zfs_embed(int *start_sector, int needed_
return (1);
}

-fsi_plugin_ops_t *
-fsi_init_plugin(int version, fsi_plugin_t *fp, const char **name)
-{
- static fsig_plugin_ops_t ops = {
- FSIMAGE_PLUGIN_VERSION,
- .fpo_mount = zfs_mount,
- .fpo_dir = zfs_open,
- .fpo_read = zfs_read
- };
-
- *name = "zfs";
- return (fsig_init(fp, &ops));
-}
+#endif /* FSYS_ZFS */
diff -r 07befd9cf6d3 -r ae08db793feb tools/libfsimage/zfs/fsys_zfs.h
--- a/tools/libfsimage/zfs/fsys_zfs.h Wed Apr 14 11:29:05 2010 +0100
+++ b/tools/libfsimage/zfs/fsys_zfs.h Wed Apr 14 11:56:54 2010 +0100
@@ -17,63 +17,55 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _FSYS_ZFS_H
#define _FSYS_ZFS_H

-#include <fsimage_grub.h>
-#include <fsimage_priv.h>
-
-#include "zfs-include/zfs.h"
-#include "zfs-include/dmu.h"
-#include "zfs-include/spa.h"
-#include "zfs-include/zio.h"
-#include "zfs-include/zio_checksum.h"
-#include "zfs-include/vdev_impl.h"
-#include "zfs-include/zap_impl.h"
-#include "zfs-include/zap_leaf.h"
-#include "zfs-include/uberblock_impl.h"
-#include "zfs-include/dnode.h"
-#include "zfs-include/dsl_dir.h"
-#include "zfs-include/zfs_acl.h"
-#include "zfs-include/zfs_znode.h"
-#include "zfs-include/dsl_dataset.h"
-#include "zfs-include/zil.h"
-#include "zfs-include/dmu_objset.h"
+#ifdef FSYS_ZFS
+
+#ifndef FSIMAGE
+typedef unsigned long long uint64_t;
+typedef unsigned int uint32_t;
+typedef unsigned short uint16_t;
+typedef unsigned char uint8_t;
+typedef unsigned char uchar_t;
+
+#if defined(_LP64) || defined(_I32LPx)
+typedef unsigned long size_t;
+#else
+typedef unsigned int size_t;
+#endif
+#else
+#include "fsi_zfs.h"
+#endif /* !FSIMAGE */
+
+#include <zfs-include/zfs.h>
+#include <zfs-include/dmu.h>
+#include <zfs-include/spa.h>
+#include <zfs-include/zio.h>
+#include <zfs-include/zio_checksum.h>
+#include <zfs-include/vdev_impl.h>
+#include <zfs-include/zap_impl.h>
+#include <zfs-include/zap_leaf.h>
+#include <zfs-include/uberblock_impl.h>
+#include <zfs-include/dnode.h>
+#include <zfs-include/dsl_dir.h>
+#include <zfs-include/zfs_acl.h>
+#include <zfs-include/zfs_znode.h>
+#include <zfs-include/dsl_dataset.h>
+#include <zfs-include/zil.h>
+#include <zfs-include/dmu_objset.h>
+#include <zfs-include/sa_impl.h>

/*
* Global Memory addresses to store MOS and DNODE data
*/
-#define MOS ((dnode_phys_t *)(((zfs_bootarea_t *) \
- (ffi->ff_fsi->f_data))->zfs_data))
+#define MOS ((dnode_phys_t *)\
+ (RAW_ADDR((mbi.mem_upper << 10) + 0x100000) - ZFS_SCRATCH_SIZE))
#define DNODE (MOS+1) /* move sizeof(dnode_phys_t) bytes */
#define ZFS_SCRATCH ((char *)(DNODE+1))
-
-#define MAXNAMELEN 256
-
-typedef struct zfs_bootarea {
- char zfs_current_bootpath[MAXNAMELEN];
- char zfs_current_rootpool[MAXNAMELEN];
- char zfs_current_bootfs[MAXNAMELEN];
- uint64_t zfs_current_bootfs_obj;
- int zfs_open;
-
- /* cache for a file block of the currently zfs_open()-ed file */
- void *zfs_file_buf;
- uint64_t zfs_file_start;
- uint64_t zfs_file_end;
-
- /* cache for a dnode block */
- dnode_phys_t *zfs_dnode_buf;
- dnode_phys_t *zfs_dnode_mdn;
- uint64_t zfs_dnode_start;
- uint64_t zfs_dnode_end;
-
- char *zfs_stackbase;
- char zfs_data[0x400000];
-} zfs_bootarea_t;

/*
* Verify dnode type.
@@ -108,9 +100,8 @@ typedef struct zfs_bootarea {
* can support large sector disks.
*/
#define UBERBLOCK_SIZE (1ULL << UBERBLOCK_SHIFT)
-#undef offsetof
-#define offsetof(t, m) (size_t)(&(((t *)0)->m))
#define VDEV_UBERBLOCK_SHIFT UBERBLOCK_SHIFT
+#include <stddef.h>
#define VDEV_UBERBLOCK_OFFSET(n) \
offsetof(vdev_label_t, vl_uberblock[(n) << VDEV_UBERBLOCK_SHIFT])

@@ -120,8 +111,8 @@ typedef struct uberblock_phys {
typedef struct uberblock_phys {
uberblock_t ubp_uberblock;
char ubp_pad[UBERBLOCK_SIZE - sizeof (uberblock_t) -
- sizeof (zio_block_tail_t)];
- zio_block_tail_t ubp_zbt;
+ sizeof (zio_eck_t)];
+ zio_eck_t ubp_zec;
} uberblock_phys_t;

/*
@@ -130,6 +121,15 @@ typedef struct uberblock_phys {
#define P2PHASE(x, align) ((x) & ((align) - 1))
#define DVA_OFFSET_TO_PHYS_SECTOR(offset) \
((offset + VDEV_LABEL_START_SIZE) >> SPA_MINBLOCKSHIFT)
+
+/*
+ * return x rounded down to an align boundary
+ * eg, P2ALIGN(1200, 1024) == 1024 (1*align)
+ * eg, P2ALIGN(1024, 1024) == 1024 (1*align)
+ * eg, P2ALIGN(0x1234, 0x100) == 0x1200 (0x12*align)
+ * eg, P2ALIGN(0x5600, 0x100) == 0x5600 (0x56*align)
+ */
+#define P2ALIGN(x, align) ((x) & -(align))

/*
* For nvlist manipulation. (from nvpair.h)
@@ -200,4 +200,6 @@ extern void zio_checksum_SHA256(const vo
extern void zio_checksum_SHA256(const void *, uint64_t, zio_cksum_t *);
extern int lzjb_decompress(void *, void *, size_t, size_t);

+#endif /* FSYS_ZFS */
+
#endif /* !_FSYS_ZFS_H */
diff -r 07befd9cf6d3 -r ae08db793feb tools/libfsimage/zfs/shared.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libfsimage/zfs/shared.h Wed Apr 14 11:56:54 2010 +0100
@@ -0,0 +1,33 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/*
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+#ifndef _SHARED_H
+#define _SHARED_H
+
+#ifdef FSYS_ZFS
+
+/* THIS FILE IS INTENTIONALLY BLANK */
+
+#endif /* FSI_ZFS */
+
+#endif /* !_SHARED_H */
+
diff -r 07befd9cf6d3 -r ae08db793feb tools/libfsimage/zfs/zfs-include/dmu.h
--- a/tools/libfsimage/zfs/zfs-include/dmu.h Wed Apr 14 11:29:05 2010 +0100
+++ b/tools/libfsimage/zfs/zfs-include/dmu.h Wed Apr 14 11:56:54 2010 +0100
@@ -17,7 +17,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/

@@ -56,7 +56,7 @@ typedef enum dmu_object_type {
DMU_OT_DSL_DATASET, /* UINT64 */
/* zpl: */
DMU_OT_ZNODE, /* ZNODE */
- DMU_OT_ACL, /* ACL */
+ DMU_OT_OLDACL, /* OLD ACL */
DMU_OT_PLAIN_FILE_CONTENTS, /* UINT8 */
DMU_OT_DIRECTORY_CONTENTS, /* ZAP */
DMU_OT_MASTER_NODE, /* ZAP */
@@ -73,7 +73,22 @@ typedef enum dmu_object_type {
DMU_OT_SPA_HISTORY, /* UINT8 */
DMU_OT_SPA_HISTORY_OFFSETS, /* spa_his_phys_t */
DMU_OT_POOL_PROPS, /* ZAP */
-
+ DMU_OT_DSL_PERMS, /* ZAP */
+ DMU_OT_ACL, /* ACL */
+ DMU_OT_SYSACL, /* SYSACL */
+ DMU_OT_FUID, /* FUID table (Packed NVLIST UINT8) */
+ DMU_OT_FUID_SIZE, /* FUID table size UINT64 */
+ DMU_OT_NEXT_CLONES, /* ZAP */
+ DMU_OT_SCRUB_QUEUE, /* ZAP */
+ DMU_OT_USERGROUP_USED, /* ZAP */
+ DMU_OT_USERGROUP_QUOTA, /* ZAP */
+ DMU_OT_USERREFS, /* ZAP */
+ DMU_OT_DDT_ZAP, /* ZAP */
+ DMU_OT_DDT_STATS, /* ZAP */
+ DMU_OT_SA, /* System attr */
+ DMU_OT_SA_MASTER_NODE, /* ZAP */
+ DMU_OT_SA_ATTR_REGISTRATION, /* ZAP */
+ DMU_OT_SA_ATTR_LAYOUTS, /* ZAP */
DMU_OT_NUMTYPES
} dmu_object_type_t;

diff -r 07befd9cf6d3 -r ae08db793feb tools/libfsimage/zfs/zfs-include/dnode.h
--- a/tools/libfsimage/zfs/zfs-include/dnode.h Wed Apr 14 11:29:05 2010 +0100
+++ b/tools/libfsimage/zfs/zfs-include/dnode.h Wed Apr 14 11:56:54 2010 +0100
@@ -17,7 +17,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/

@@ -47,6 +47,8 @@
#define DNODES_PER_BLOCK (1ULL << DNODES_PER_BLOCK_SHIFT)
#define DNODES_PER_LEVEL_SHIFT (DN_MAX_INDBLKSHIFT - SPA_BLKPTRSHIFT)

+#define DNODE_FLAG_SPILL_BLKPTR (1<<2)
+
#define DN_BONUS(dnp) ((void*)((dnp)->dn_bonus + \
(((dnp)->dn_nblkptr - 1) * sizeof (blkptr_t))))

@@ -70,7 +72,8 @@ typedef struct dnode_phys {
uint64_t dn_pad3[4];

blkptr_t dn_blkptr[1];
- uint8_t dn_bonus[DN_MAX_BONUSLEN];
+ uint8_t dn_bonus[DN_MAX_BONUSLEN - sizeof (blkptr_t)];
+ blkptr_t dn_spill;
} dnode_phys_t;

#endif /* _SYS_DNODE_H */
diff -r 07befd9cf6d3 -r ae08db793feb tools/libfsimage/zfs/zfs-include/dsl_dataset.h
--- a/tools/libfsimage/zfs/zfs-include/dsl_dataset.h Wed Apr 14 11:29:05 2010 +0100
+++ b/tools/libfsimage/zfs/zfs-include/dsl_dataset.h Wed Apr 14 11:56:54 2010 +0100
@@ -23,6 +23,8 @@

#ifndef _SYS_DSL_DATASET_H
#define _SYS_DSL_DATASET_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"

typedef struct dsl_dataset_phys {
uint64_t ds_dir_obj;
diff -r 07befd9cf6d3 -r ae08db793feb tools/libfsimage/zfs/zfs-include/dsl_dir.h
--- a/tools/libfsimage/zfs/zfs-include/dsl_dir.h Wed Apr 14 11:29:05 2010 +0100
+++ b/tools/libfsimage/zfs/zfs-include/dsl_dir.h Wed Apr 14 11:56:54 2010 +0100
@@ -24,6 +24,8 @@
#ifndef _SYS_DSL_DIR_H
#define _SYS_DSL_DIR_H

+#pragma ident "%Z%%M% %I% %E% SMI"
+
typedef struct dsl_dir_phys {
uint64_t dd_creation_time; /* not actually used */
uint64_t dd_head_dataset_obj;
diff -r 07befd9cf6d3 -r ae08db793feb tools/libfsimage/zfs/zfs-include/sa_impl.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libfsimage/zfs/zfs-include/sa_impl.h Wed Apr 14 11:56:54 2010 +0100
@@ -0,0 +1,35 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/*
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+#ifndef _SYS_SA_IMPL_H
+#define _SYS_SA_IMPL_H
+
+typedef struct sa_hdr_phys {
+ uint32_t sa_magic;
+ uint16_t sa_layout_info;
+ uint16_t sa_lengths[1];
+} sa_hdr_phys_t;
+
+#define SA_HDR_SIZE(hdr) BF32_GET_SB(hdr->sa_layout_info, 10, 16, 3, 0)
+#define SA_SIZE_OFFSET 0x8
+
+#endif /* _SYS_SA_IMPL_H */
diff -r 07befd9cf6d3 -r ae08db793feb tools/libfsimage/zfs/zfs-include/spa.h
--- a/tools/libfsimage/zfs/zfs-include/spa.h Wed Apr 14 11:29:05 2010 +0100
+++ b/tools/libfsimage/zfs/zfs-include/spa.h Wed Apr 14 11:56:54 2010 +0100
@@ -17,7 +17,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/

@@ -61,6 +61,11 @@
#define SPA_MAXBLOCKSIZE (1ULL << SPA_MAXBLOCKSHIFT)

#define SPA_BLOCKSIZES (SPA_MAXBLOCKSHIFT - SPA_MINBLOCKSHIFT + 1)
+
+/*
+ * Size of block to hold the configuration data (a packed nvlist)
+ */
+#define SPA_CONFIG_BLOCKSIZE (1 << 14)

/*
* The DVA size encodings for LSIZE and PSIZE support blocks up to 32MB.
@@ -106,15 +111,15 @@ typedef struct zio_cksum {
* +-------+-------+-------+-------+-------+-------+-------+-------+
* 5 |G| offset3 |
* +-------+-------+-------+-------+-------+-------+-------+-------+
- * 6 |E| lvl | type | cksum | comp | PSIZE | LSIZE |
+ * 6 |BDX|lvl| type | cksum | comp | PSIZE | LSIZE |
* +-------+-------+-------+-------+-------+-------+-------+-------+
* 7 | padding |
* +-------+-------+-------+-------+-------+-------+-------+-------+
* 8 | padding |
* +-------+-------+-------+-------+-------+-------+-------+-------+
- * 9 | padding |
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * a | birth txg |
+ * 9 | physical birth txg |
+ * +-------+-------+-------+-------+-------+-------+-------+-------+
+ * a | logical birth txg |
* +-------+-------+-------+-------+-------+-------+-------+-------+
* b | fill count |
* +-------+-------+-------+-------+-------+-------+-------+-------+
@@ -138,24 +143,28 @@ typedef struct zio_cksum {
* cksum checksum function
* comp compression function
* G gang block indicator
- * E endianness
+ * B byteorder (endianness)
+ * D dedup
+ * X unused
+ * lvl level of indirection
* type DMU object type
- * lvl level of indirection
- * birth txg transaction group in which the block was born
+ * phys birth txg of block allocation; zero if same as logical birth txg
+ * log. birth transaction group in which the block was logically born
* fill count number of non-zero blocks under this bp
* checksum[4] 256-bit checksum of the data this bp describes
*/
-typedef struct blkptr {
- dva_t blk_dva[3]; /* 128-bit Data Virtual Address */
- uint64_t blk_prop; /* size, compression, type, etc */
- uint64_t blk_pad[3]; /* Extra space for the future */
- uint64_t blk_birth; /* transaction group at birth */
- uint64_t blk_fill; /* fill count */
- zio_cksum_t blk_cksum; /* 256-bit checksum */
-} blkptr_t;
-
#define SPA_BLKPTRSHIFT 7 /* blkptr_t is 128 bytes */
#define SPA_DVAS_PER_BP 3 /* Number of DVAs in a bp */
+
+typedef struct blkptr {
+ dva_t blk_dva[SPA_DVAS_PER_BP]; /* Data Virtual Addresses */
+ uint64_t blk_prop; /* size, compression, type, etc */
+ uint64_t blk_pad[2]; /* Extra space for the future */
+ uint64_t blk_phys_birth; /* txg when block was allocated */
+ uint64_t blk_birth; /* transaction group at birth */
+ uint64_t blk_fill; /* fill count */
+ zio_cksum_t blk_cksum; /* 256-bit checksum */
+} blkptr_t;

/*
* Macros to get and set fields in a bp or DVA.
@@ -180,8 +189,7 @@ typedef struct blkptr {
#define DVA_SET_GANG(dva, x) BF64_SET((dva)->dva_word[1], 63, 1, x)

#define BP_GET_LSIZE(bp) \
- (BP_IS_HOLE(bp) ? 0 : \
- BF64_GET_SB((bp)->blk_prop, 0, 16, SPA_MINBLOCKSHIFT, 1))
+ BF64_GET_SB((bp)->blk_prop, 0, 16, SPA_MINBLOCKSHIFT, 1)
#define BP_SET_LSIZE(bp, x) \
BF64_SET_SB((bp)->blk_prop, 0, 16, SPA_MINBLOCKSHIFT, 1, x)

@@ -190,20 +198,35 @@ typedef struct blkptr {
#define BP_SET_PSIZE(bp, x) \
BF64_SET_SB((bp)->blk_prop, 16, 16, SPA_MINBLOCKSHIFT, 1, x)

-#define BP_GET_COMPRESS(bp) BF64_GET((bp)->blk_prop, 32, 8)
-#define BP_SET_COMPRESS(bp, x) BF64_SET((bp)->blk_prop, 32, 8, x)
-
-#define BP_GET_CHECKSUM(bp) BF64_GET((bp)->blk_prop, 40, 8)
-#define BP_SET_CHECKSUM(bp, x) BF64_SET((bp)->blk_prop, 40, 8, x)
-
-#define BP_GET_TYPE(bp) BF64_GET((bp)->blk_prop, 48, 8)
-#define BP_SET_TYPE(bp, x) BF64_SET((bp)->blk_prop, 48, 8, x)
-
-#define BP_GET_LEVEL(bp) BF64_GET((bp)->blk_prop, 56, 5)
-#define BP_SET_LEVEL(bp, x) BF64_SET((bp)->blk_prop, 56, 5, x)
-
-#define BP_GET_BYTEORDER(bp) (0 - BF64_GET((bp)->blk_prop, 63, 1))
-#define BP_SET_BYTEORDER(bp, x) BF64_SET((bp)->blk_prop, 63, 1, x)
+#define BP_GET_COMPRESS(bp) BF64_GET((bp)->blk_prop, 32, 8)
+#define BP_SET_COMPRESS(bp, x) BF64_SET((bp)->blk_prop, 32, 8, x)
+
+#define BP_GET_CHECKSUM(bp) BF64_GET((bp)->blk_prop, 40, 8)
+#define BP_SET_CHECKSUM(bp, x) BF64_SET((bp)->blk_prop, 40, 8, x)
+
+#define BP_GET_TYPE(bp) BF64_GET((bp)->blk_prop, 48, 8)
+#define BP_SET_TYPE(bp, x) BF64_SET((bp)->blk_prop, 48, 8, x)
+
+#define BP_GET_LEVEL(bp) BF64_GET((bp)->blk_prop, 56, 5)
+#define BP_SET_LEVEL(bp, x) BF64_SET((bp)->blk_prop, 56, 5, x)
+
+#define BP_GET_PROP_BIT_61(bp) BF64_GET((bp)->blk_prop, 61, 1)
+#define BP_SET_PROP_BIT_61(bp, x) BF64_SET((bp)->blk_prop, 61, 1, x)
+
+#define BP_GET_DEDUP(bp) BF64_GET((bp)->blk_prop, 62, 1)
+#define BP_SET_DEDUP(bp, x) BF64_SET((bp)->blk_prop, 62, 1, x)
+
+#define BP_GET_BYTEORDER(bp) (0 - BF64_GET((bp)->blk_prop, 63, 1))
+#define BP_SET_BYTEORDER(bp, x) BF64_SET((bp)->blk_prop, 63, 1, x)
+
+#define BP_PHYSICAL_BIRTH(bp) \
+ ((bp)->blk_phys_birth ? (bp)->blk_phys_birth : (bp)->blk_birth)
+
+#define BP_SET_BIRTH(bp, logical, physical) \
+{ \
+ (bp)->blk_birth = (logical); \
+ (bp)->blk_phys_birth = ((logical) == (physical) ? 0 : (physical)); \
+}

#define BP_GET_ASIZE(bp) \
(DVA_GET_ASIZE(&(bp)->blk_dva[0]) + DVA_GET_ASIZE(&(bp)->blk_dva[1]) + \
@@ -226,13 +249,18 @@ typedef struct blkptr {
#define DVA_EQUAL(dva1, dva2) \
((dva1)->dva_word[1] == (dva2)->dva_word[1] && \
(dva1)->dva_word[0] == (dva2)->dva_word[0])
+
+#define BP_EQUAL(bp1, bp2) \
+ (BP_PHYSICAL_BIRTH(bp1) == BP_PHYSICAL_BIRTH(bp2) && \
+ DVA_EQUAL(&(bp1)->blk_dva[0], &(bp2)->blk_dva[0]) && \
+ DVA_EQUAL(&(bp1)->blk_dva[1], &(bp2)->blk_dva[1]) && \
+ DVA_EQUAL(&(bp1)->blk_dva[2], &(bp2)->blk_dva[2]))

#define ZIO_CHECKSUM_EQUAL(zc1, zc2) \
(0 == (((zc1).zc_word[0] - (zc2).zc_word[0]) | \
((zc1).zc_word[1] - (zc2).zc_word[1]) | \
((zc1).zc_word[2] - (zc2).zc_word[2]) | \
((zc1).zc_word[3] - (zc2).zc_word[3])))
-

#define DVA_IS_VALID(dva) (DVA_GET_ASIZE(dva) != 0)

@@ -247,7 +275,10 @@ typedef struct blkptr {
#define BP_IDENTITY(bp) (&(bp)->blk_dva[0])
#define BP_IS_GANG(bp) DVA_GET_GANG(BP_IDENTITY(bp))
#define BP_IS_HOLE(bp) ((bp)->blk_birth == 0)
-#define BP_IS_OLDER(bp, txg) (!BP_IS_HOLE(bp) && (bp)->blk_birth < (txg))
+
+/* BP_IS_RAIDZ(bp) assumes no block compression */
+#define BP_IS_RAIDZ(bp) (DVA_GET_ASIZE(&(bp)->blk_dva[0]) > \
+ BP_GET_PSIZE(bp))

#define BP_ZERO(bp) \
{ \
@@ -260,7 +291,7 @@ typedef struct blkptr {
(bp)->blk_prop = 0; \
(bp)->blk_pad[0] = 0; \
(bp)->blk_pad[1] = 0; \
- (bp)->blk_pad[2] = 0; \
+ (bp)->blk_phys_birth = 0; \
(bp)->blk_birth = 0; \
(bp)->blk_fill = 0; \
ZIO_SET_CHECKSUM(&(bp)->blk_cksum, 0, 0, 0, 0); \
diff -r 07befd9cf6d3 -r ae08db793feb tools/libfsimage/zfs/zfs-include/uberblock_impl.h
--- a/tools/libfsimage/zfs/zfs-include/uberblock_impl.h Wed Apr 14 11:29:05 2010 +0100
+++ b/tools/libfsimage/zfs/zfs-include/uberblock_impl.h Wed Apr 14 11:56:54 2010 +0100
@@ -24,6 +24,8 @@
#ifndef _SYS_UBERBLOCK_IMPL_H
#define _SYS_UBERBLOCK_IMPL_H

+#pragma ident "%Z%%M% %I% %E% SMI"
+
/*
* The uberblock version is incremented whenever an incompatible on-disk
* format change is made to the SPA, DMU, or ZAP.
diff -r 07befd9cf6d3 -r ae08db793feb tools/libfsimage/zfs/zfs-include/vdev_impl.h
--- a/tools/libfsimage/zfs/zfs-include/vdev_impl.h Wed Apr 14 11:29:05 2010 +0100
+++ b/tools/libfsimage/zfs/zfs-include/vdev_impl.h Wed Apr 14 11:56:54 2010 +0100
@@ -17,38 +17,27 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/

#ifndef _SYS_VDEV_IMPL_H
#define _SYS_VDEV_IMPL_H

-#define VDEV_SKIP_SIZE (8 << 10)
-#define VDEV_BOOT_HEADER_SIZE (8 << 10)
+#define VDEV_PAD_SIZE (8 << 10)
+/* 2 padding areas (vl_pad1 and vl_pad2) to skip */
+#define VDEV_SKIP_SIZE VDEV_PAD_SIZE * 2
#define VDEV_PHYS_SIZE (112 << 10)
#define VDEV_UBERBLOCK_RING (128 << 10)

-/* ZFS boot block */
-#define VDEV_BOOT_MAGIC 0x2f5b007b10cULL
-#define VDEV_BOOT_VERSION 1 /* version number */
-
-typedef struct vdev_boot_header {
- uint64_t vb_magic; /* VDEV_BOOT_MAGIC */
- uint64_t vb_version; /* VDEV_BOOT_VERSION */
- uint64_t vb_offset; /* start offset (bytes) */
- uint64_t vb_size; /* size (bytes) */
- char vb_pad[VDEV_BOOT_HEADER_SIZE - 4 * sizeof (uint64_t)];
-} vdev_boot_header_t;
-
typedef struct vdev_phys {
- char vp_nvlist[VDEV_PHYS_SIZE - sizeof (zio_block_tail_t)];
- zio_block_tail_t vp_zbt;
+ char vp_nvlist[VDEV_PHYS_SIZE - sizeof (zio_eck_t)];
+ zio_eck_t vp_zbt;
} vdev_phys_t;

typedef struct vdev_label {
- char vl_pad[VDEV_SKIP_SIZE]; /* 8K */
- vdev_boot_header_t vl_boot_header; /* 8K */
+ char vl_pad1[VDEV_PAD_SIZE]; /* 8K */
+ char vl_pad2[VDEV_PAD_SIZE]; /* 8K */
vdev_phys_t vl_vdev_phys; /* 112K */
char vl_uberblock[VDEV_UBERBLOCK_RING]; /* 128K */
} vdev_label_t; /* 256K total */
diff -r 07befd9cf6d3 -r ae08db793feb tools/libfsimage/zfs/zfs-include/zap_impl.h
--- a/tools/libfsimage/zfs/zfs-include/zap_impl.h Wed Apr 14 11:29:05 2010 +0100
+++ b/tools/libfsimage/zfs/zfs-include/zap_impl.h Wed Apr 14 11:56:54 2010 +0100
@@ -17,7 +17,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/

@@ -26,7 +26,6 @@

#define ZAP_MAGIC 0x2F52AB2ABULL

-#define ZAP_HASHBITS 28
#define MZAP_ENT_LEN 64
#define MZAP_NAME_LEN (MZAP_ENT_LEN - 8 - 4 - 2)
#define MZAP_MAX_BLKSHIFT SPA_MAXBLOCKSHIFT
@@ -99,6 +98,8 @@ typedef struct zap_phys {
uint64_t zap_num_leafs; /* number of leafs */
uint64_t zap_num_entries; /* number of entries */
uint64_t zap_salt; /* salt to stir into hash function */
+ uint64_t zap_normflags; /* flags for u8_textprep_str() */
+ uint64_t zap_flags; /* zap_flag_t */
/*
* This structure is followed by padding, and then the embedded
* pointer table. The embedded pointer table takes up second
diff -r 07befd9cf6d3 -r ae08db793feb tools/libfsimage/zfs/zfs-include/zap_leaf.h
--- a/tools/libfsimage/zfs/zfs-include/zap_leaf.h Wed Apr 14 11:29:05 2010 +0100
+++ b/tools/libfsimage/zfs/zfs-include/zap_leaf.h Wed Apr 14 11:56:54 2010 +0100
@@ -23,6 +23,8 @@

#ifndef _SYS_ZAP_LEAF_H
#define _SYS_ZAP_LEAF_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"

#define ZAP_LEAF_MAGIC 0x2AB1EAF

diff -r 07befd9cf6d3 -r ae08db793feb tools/libfsimage/zfs/zfs-include/zfs.h
--- a/tools/libfsimage/zfs/zfs-include/zfs.h Wed Apr 14 11:29:05 2010 +0100
+++ b/tools/libfsimage/zfs/zfs-include/zfs.h Wed Apr 14 11:56:54 2010 +0100
@@ -17,18 +17,17 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/

#ifndef _SYS_FS_ZFS_H
#define _SYS_FS_ZFS_H

-
/*
* On-disk version number.
*/
-#define SPA_VERSION 16ULL
+#define SPA_VERSION 24ULL

/*
* The following are configuration names used in the nvlist describing a pool's
@@ -62,6 +61,12 @@
#define ZPOOL_CONFIG_NPARITY "nparity"
#define ZPOOL_CONFIG_PHYS_PATH "phys_path"
#define ZPOOL_CONFIG_L2CACHE "l2cache"
+#define ZPOOL_CONFIG_HOLE_ARRAY "hole_array"
+#define ZPOOL_CONFIG_VDEV_CHILDREN "vdev_children"
+#define ZPOOL_CONFIG_IS_HOLE "is_hole"
+#define ZPOOL_CONFIG_DDT_HISTOGRAM "ddt_histogram"
+#define ZPOOL_CONFIG_DDT_OBJ_STATS "ddt_object_stats"
+#define ZPOOL_CONFIG_DDT_STATS "ddt_stats"
/*
* The persistent vdev state is stored as separate values rather than a single
* 'vdev_state' entry. This is because a device can be in multiple states, such
@@ -79,6 +84,7 @@
#define VDEV_TYPE_DISK "disk"
#define VDEV_TYPE_FILE "file"
#define VDEV_TYPE_MISSING "missing"
+#define VDEV_TYPE_HOLE "hole"
#define VDEV_TYPE_SPARE "spare"
#define VDEV_TYPE_L2CACHE "l2cache"

diff -r 07befd9cf6d3 -r ae08db793feb tools/libfsimage/zfs/zfs-include/zfs_acl.h
--- a/tools/libfsimage/zfs/zfs-include/zfs_acl.h Wed Apr 14 11:29:05 2010 +0100
+++ b/tools/libfsimage/zfs/zfs-include/zfs_acl.h Wed Apr 14 11:56:54 2010 +0100
@@ -23,6 +23,13 @@

#ifndef _SYS_FS_ZFS_ACL_H
#define _SYS_FS_ZFS_ACL_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifndef _UID_T
+#define _UID_T
+typedef unsigned int uid_t; /* UID type */
+#endif /* _UID_T */

typedef struct zfs_oldace {
uint32_t z_fuid; /* "who" */
diff -r 07befd9cf6d3 -r ae08db793feb tools/libfsimage/zfs/zfs-include/zfs_znode.h
--- a/tools/libfsimage/zfs/zfs-include/zfs_znode.h Wed Apr 14 11:29:05 2010 +0100
+++ b/tools/libfsimage/zfs/zfs-include/zfs_znode.h Wed Apr 14 11:56:54 2010 +0100
@@ -17,7 +17,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/

@@ -27,8 +27,9 @@
#define MASTER_NODE_OBJ 1
#define ZFS_ROOT_OBJ "ROOT"
#define ZPL_VERSION_STR "VERSION"
+#define ZFS_SA_ATTRS "SA_ATTRS"

-#define ZPL_VERSION 4ULL
+#define ZPL_VERSION 5ULL

#define ZFS_DIRENT_OBJ(de) BF64_GET(de, 0, 48)

diff -r 07befd9cf6d3 -r ae08db793feb tools/libfsimage/zfs/zfs-include/zil.h
--- a/tools/libfsimage/zfs/zfs-include/zil.h Wed Apr 14 11:29:05 2010 +0100
+++ b/tools/libfsimage/zfs/zfs-include/zil.h Wed Apr 14 11:56:54 2010 +0100
@@ -17,7 +17,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/

@@ -45,7 +45,13 @@ typedef struct zil_header {
uint64_t zh_replay_seq; /* highest replayed sequence number */
blkptr_t zh_log; /* log chain */
uint64_t zh_claim_seq; /* highest claimed sequence number */
- uint64_t zh_pad[5];
+ uint64_t zh_flags; /* header flags */
+ uint64_t zh_pad[4];
} zil_header_t;

+/*
+ * zh_flags bit settings
+ */
+#define ZIL_REPLAY_NEEDED 0x1 /* replay needed - internal only */
+
#endif /* _SYS_ZIL_H */
diff -r 07befd9cf6d3 -r ae08db793feb tools/libfsimage/zfs/zfs-include/zio.h
--- a/tools/libfsimage/zfs/zfs-include/zio.h Wed Apr 14 11:29:05 2010 +0100
+++ b/tools/libfsimage/zfs/zfs-include/zio.h Wed Apr 14 11:56:54 2010 +0100
@@ -17,19 +17,19 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/

#ifndef _ZIO_H
#define _ZIO_H

-#define ZBT_MAGIC 0x210da7ab10c7a11ULL /* zio data bloc tail */
+#define ZEC_MAGIC 0x210da7ab10c7a11ULL /* zio data bloc tail */

-typedef struct zio_block_tail {
- uint64_t zbt_magic; /* for validation, endianness */
- zio_cksum_t zbt_cksum; /* 256-bit checksum */
-} zio_block_tail_t;
+typedef struct zio_eck {
+ uint64_t zec_magic; /* for validation, endianness */
+ zio_cksum_t zec_cksum; /* 256-bit checksum */
+} zio_eck_t;

/*
* Gang block headers are self-checksumming and contain an array
@@ -37,9 +37,9 @@ typedef struct zio_block_tail {
*/
#define SPA_GANGBLOCKSIZE SPA_MINBLOCKSIZE
#define SPA_GBH_NBLKPTRS ((SPA_GANGBLOCKSIZE - \
- sizeof (zio_block_tail_t)) / sizeof (blkptr_t))
+ sizeof (zio_eck_t)) / sizeof (blkptr_t))
#define SPA_GBH_FILLER ((SPA_GANGBLOCKSIZE - \
- sizeof (zio_block_tail_t) - \
+ sizeof (zio_eck_t) - \
(SPA_GBH_NBLKPTRS * sizeof (blkptr_t))) /\
sizeof (uint64_t))

@@ -50,7 +50,7 @@ typedef struct zio_gbh {
typedef struct zio_gbh {
blkptr_t zg_blkptr[SPA_GBH_NBLKPTRS];
uint64_t zg_filler[SPA_GBH_FILLER];
- zio_block_tail_t zg_tail;
+ zio_eck_t zg_tail;
} zio_gbh_phys_t;

enum zio_checksum {
@@ -63,11 +63,9 @@ enum zio_checksum {
ZIO_CHECKSUM_FLETCHER_2,
ZIO_CHECKSUM_FLETCHER_4,
ZIO_CHECKSUM_SHA256,
+ ZIO_CHECKSUM_ZILOG2,
ZIO_CHECKSUM_FUNCTIONS
};
-
-#define ZIO_CHECKSUM_ON_VALUE ZIO_CHECKSUM_FLETCHER_2
-#define ZIO_CHECKSUM_DEFAULT ZIO_CHECKSUM_ON

enum zio_compress {
ZIO_COMPRESS_INHERIT = 0,
diff -r 07befd9cf6d3 -r ae08db793feb tools/libfsimage/zfs/zfs-include/zio_checksum.h
--- a/tools/libfsimage/zfs/zfs-include/zio_checksum.h Wed Apr 14 11:29:05 2010 +0100
+++ b/tools/libfsimage/zfs/zfs-include/zio_checksum.h Wed Apr 14 11:56:54 2010 +0100
@@ -17,7 +17,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/

@@ -35,7 +35,7 @@ typedef struct zio_checksum_info {
typedef struct zio_checksum_info {
zio_checksum_t *ci_func[2]; /* checksum function for each byteorder */
int ci_correctable; /* number of correctable bits */
- int ci_zbt; /* uses zio block tail? */
+ int ci_eck; /* uses zio embedded checksum? */
char *ci_name; /* descriptive name */
} zio_checksum_info_t;

diff -r 07befd9cf6d3 -r ae08db793feb tools/libfsimage/zfs/zfs_fletcher.c
--- a/tools/libfsimage/zfs/zfs_fletcher.c Wed Apr 14 11:29:05 2010 +0100
+++ b/tools/libfsimage/zfs/zfs_fletcher.c Wed Apr 14 11:56:54 2010 +0100
@@ -20,6 +20,8 @@
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+
+#pragma ident "%Z%%M% %I% %E% SMI"

#include "fsys_zfs.h"

diff -r 07befd9cf6d3 -r ae08db793feb tools/libfsimage/zfs/zfs_lzjb.c
--- a/tools/libfsimage/zfs/zfs_lzjb.c Wed Apr 14 11:29:05 2010 +0100
+++ b/tools/libfsimage/zfs/zfs_lzjb.c Wed Apr 14 11:56:54 2010 +0100
@@ -21,6 +21,8 @@
* Use is subject to license terms.
*/

+#pragma ident "%Z%%M% %I% %E% SMI"
+
#include "fsys_zfs.h"

#define MATCH_BITS 6
@@ -32,11 +34,10 @@ int
int
lzjb_decompress(void *s_start, void *d_start, size_t s_len, size_t d_len)
{
- unsigned char *src = s_start;
- unsigned char *dst = d_start;
- unsigned char *d_end = (unsigned char *)d_start + d_len;
- unsigned char *cpy;
- unsigned char copymap = '\0';
+ uchar_t *src = s_start;
+ uchar_t *dst = d_start;
+ uchar_t *d_end = (uchar_t *)d_start + d_len;
+ uchar_t *cpy, copymap = '\0';
int copymask = 1 << (NBBY - 1);

while (dst < d_end) {
@@ -44,11 +45,11 @@ lzjb_decompress(void *s_start, void *d_s
copymask = 1;
copymap = *src++;
}
- if (copymap & (unsigned char)copymask) {
+ if (copymap & copymask) {
int mlen = (src[0] >> (NBBY - MATCH_BITS)) + MATCH_MIN;
int offset = ((src[0] << NBBY) | src[1]) & OFFSET_MASK;
src += 2;
- if ((cpy = dst - offset) < (unsigned char *)d_start)
+ if ((cpy = dst - offset) < (uchar_t *)d_start)
return (-1);
while (--mlen >= 0 && dst < d_end)
*dst++ = *cpy++;
diff -r 07befd9cf6d3 -r ae08db793feb tools/libfsimage/zfs/zfs_sha256.c
--- a/tools/libfsimage/zfs/zfs_sha256.c Wed Apr 14 11:29:05 2010 +0100
+++ b/tools/libfsimage/zfs/zfs_sha256.c Wed Apr 14 11:56:54 2010 +0100
@@ -20,6 +20,8 @@
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+
+#pragma ident "%Z%%M% %I% %E% SMI"

#include "fsys_zfs.h"


_______________________________________________
Xen-changelog mailing list
Xen-changelog@lists.xensource.com
http://lists.xensource.com/xen-changelog