ia64/xen-unstable

changeset 17564:64f790e90d3d

Add ZFS libfsimage support patch

Add support to pygrub and libfsimage to boot ZFS root filesystems.
Boot argument of zfs-bootfs is set to describe ZFS root pool and
boot filesystem object number. Boot argument bootpath is set to
describe the virtual device root mirror components.

Signed-off-by: Susan Kamm-Worrell <susan.kamm-worrell@sun.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu May 01 16:38:56 2008 +0100 (2008-05-01)
parents 8ccaf43782bd
children a353dd2ab944
files tools/libfsimage/Makefile tools/libfsimage/common/fsimage.c tools/libfsimage/common/fsimage.h tools/libfsimage/common/fsimage_grub.c tools/libfsimage/common/fsimage_grub.h tools/libfsimage/common/fsimage_priv.h tools/libfsimage/common/mapfile-GNU tools/libfsimage/common/mapfile-SunOS tools/libfsimage/zfs/Makefile tools/libfsimage/zfs/fsys_zfs.c tools/libfsimage/zfs/fsys_zfs.h tools/libfsimage/zfs/mb_info.h tools/libfsimage/zfs/zfs-include/dmu.h tools/libfsimage/zfs/zfs-include/dmu_objset.h tools/libfsimage/zfs/zfs-include/dnode.h tools/libfsimage/zfs/zfs-include/dsl_dataset.h tools/libfsimage/zfs/zfs-include/dsl_dir.h tools/libfsimage/zfs/zfs-include/spa.h tools/libfsimage/zfs/zfs-include/uberblock_impl.h tools/libfsimage/zfs/zfs-include/vdev_impl.h tools/libfsimage/zfs/zfs-include/zap_impl.h tools/libfsimage/zfs/zfs-include/zap_leaf.h tools/libfsimage/zfs/zfs-include/zfs.h tools/libfsimage/zfs/zfs-include/zfs_acl.h tools/libfsimage/zfs/zfs-include/zfs_znode.h tools/libfsimage/zfs/zfs-include/zil.h tools/libfsimage/zfs/zfs-include/zio.h tools/libfsimage/zfs/zfs-include/zio_checksum.h tools/libfsimage/zfs/zfs_fletcher.c tools/libfsimage/zfs/zfs_lzjb.c tools/libfsimage/zfs/zfs_sha256.c tools/pygrub/src/fsimage/fsimage.c tools/pygrub/src/pygrub
line diff
     1.1 --- a/tools/libfsimage/Makefile	Thu May 01 16:37:46 2008 +0100
     1.2 +++ b/tools/libfsimage/Makefile	Thu May 01 16:38:56 2008 +0100
     1.3 @@ -1,7 +1,7 @@
     1.4  XEN_ROOT = ../..
     1.5  include $(XEN_ROOT)/tools/Rules.mk
     1.6  
     1.7 -SUBDIRS-y = common ufs reiserfs iso9660 fat
     1.8 +SUBDIRS-y = common ufs reiserfs iso9660 fat zfs
     1.9  SUBDIRS-y += $(shell env CC="$(CC)" ./check-libext2fs)
    1.10  
    1.11  .PHONY: all clean install
     2.1 --- a/tools/libfsimage/common/fsimage.c	Thu May 01 16:37:46 2008 +0100
     2.2 +++ b/tools/libfsimage/common/fsimage.c	Thu May 01 16:38:56 2008 +0100
     2.3 @@ -17,7 +17,7 @@
     2.4   * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     2.5   * DEALINGS IN THE SOFTWARE.
     2.6   *
     2.7 - * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
     2.8 + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     2.9   * Use is subject to license terms.
    2.10   */
    2.11  
    2.12 @@ -51,6 +51,7 @@ fsi_t *fsi_open_fsimage(const char *path
    2.13  	fsi->f_fd = fd;
    2.14  	fsi->f_off = off;
    2.15  	fsi->f_data = NULL;
    2.16 +	fsi->f_bootstring = NULL;
    2.17  
    2.18  	pthread_mutex_lock(&fsi_lock);
    2.19  	err = find_plugin(fsi, path, options);
    2.20 @@ -140,3 +141,29 @@ ssize_t fsi_pread_file(fsi_file_t *ffi, 
    2.21  
    2.22  	return (ret);
    2.23  }
    2.24 +
    2.25 +char *
    2.26 +fsi_bootstring_alloc(fsi_t *fsi, size_t len)
    2.27 +{
    2.28 +	fsi->f_bootstring = malloc(len);
    2.29 +	if (fsi->f_bootstring == NULL)
    2.30 +		return (NULL);
    2.31 +
    2.32 +	bzero(fsi->f_bootstring, len);
    2.33 +	return (fsi->f_bootstring);
    2.34 +}
    2.35 +
    2.36 +void
    2.37 +fsi_bootstring_free(fsi_t *fsi)
    2.38 +{
    2.39 +	if (fsi->f_bootstring != NULL) {
    2.40 +		free(fsi->f_bootstring);
    2.41 +		fsi->f_bootstring = NULL;
    2.42 +	}
    2.43 +}
    2.44 +
    2.45 +char *
    2.46 +fsi_fs_bootstring(fsi_t *fsi)
    2.47 +{
    2.48 +	return (fsi->f_bootstring);
    2.49 +}
     3.1 --- a/tools/libfsimage/common/fsimage.h	Thu May 01 16:37:46 2008 +0100
     3.2 +++ b/tools/libfsimage/common/fsimage.h	Thu May 01 16:38:56 2008 +0100
     3.3 @@ -17,7 +17,7 @@
     3.4   * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     3.5   * DEALINGS IN THE SOFTWARE.
     3.6   *
     3.7 - * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
     3.8 + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     3.9   * Use is subject to license terms.
    3.10   */
    3.11  
    3.12 @@ -45,6 +45,10 @@ int fsi_close_file(fsi_file_t *);
    3.13  ssize_t fsi_read_file(fsi_file_t *, void *, size_t);
    3.14  ssize_t fsi_pread_file(fsi_file_t *, void *, size_t, uint64_t);
    3.15  
    3.16 +char *fsi_bootstring_alloc(fsi_t *, size_t);
    3.17 +void fsi_bootstring_free(fsi_t *);
    3.18 +char *fsi_fs_bootstring(fsi_t *);
    3.19 +
    3.20  #ifdef __cplusplus
    3.21  };
    3.22  #endif
     4.1 --- a/tools/libfsimage/common/fsimage_grub.c	Thu May 01 16:37:46 2008 +0100
     4.2 +++ b/tools/libfsimage/common/fsimage_grub.c	Thu May 01 16:38:56 2008 +0100
     4.3 @@ -17,7 +17,7 @@
     4.4   * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     4.5   * DEALINGS IN THE SOFTWARE.
     4.6   *
     4.7 - * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
     4.8 + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     4.9   * Use is subject to license terms.
    4.10   */
    4.11  
    4.12 @@ -286,6 +286,7 @@ fsig_mount(fsi_t *fsi, const char *path,
    4.13  
    4.14  	if (!ops->fpo_mount(ffi, options)) {
    4.15  		fsip_file_free(ffi);
    4.16 +		fsi_bootstring_free(fsi);
    4.17  		free(fsi->f_data);
    4.18  		fsi->f_data = NULL;
    4.19  		return (-1);
    4.20 @@ -299,6 +300,7 @@ fsig_mount(fsi_t *fsi, const char *path,
    4.21  static int
    4.22  fsig_umount(fsi_t *fsi)
    4.23  {
    4.24 +	fsi_bootstring_free(fsi);
    4.25  	free(fsi->f_data);
    4.26  	return (0);
    4.27  }
     5.1 --- a/tools/libfsimage/common/fsimage_grub.h	Thu May 01 16:37:46 2008 +0100
     5.2 +++ b/tools/libfsimage/common/fsimage_grub.h	Thu May 01 16:38:56 2008 +0100
     5.3 @@ -17,7 +17,7 @@
     5.4   * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     5.5   * DEALINGS IN THE SOFTWARE.
     5.6   *
     5.7 - * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
     5.8 + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     5.9   * Use is subject to license terms.
    5.10   */
    5.11  
    5.12 @@ -72,6 +72,12 @@ unsigned long fsig_log2(unsigned long);
    5.13  #define	ERR_FILELENGTH 1
    5.14  #define	ERR_BAD_FILETYPE 1
    5.15  #define	ERR_FILE_NOT_FOUND 1
    5.16 +#define	ERR_BAD_ARGUMENT 1
    5.17 +#define	ERR_FILESYSTEM_NOT_FOUND 1
    5.18 +#define	ERR_NO_BOOTPATH 1
    5.19 +#define	ERR_DEV_VALUES 1
    5.20 +#define	ERR_WONT_FIT 1
    5.21 +#define	ERR_READ 1
    5.22  
    5.23  fsi_plugin_ops_t *fsig_init(fsi_plugin_t *, fsig_plugin_ops_t *);
    5.24  
     6.1 --- a/tools/libfsimage/common/fsimage_priv.h	Thu May 01 16:37:46 2008 +0100
     6.2 +++ b/tools/libfsimage/common/fsimage_priv.h	Thu May 01 16:38:56 2008 +0100
     6.3 @@ -17,7 +17,7 @@
     6.4   * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     6.5   * DEALINGS IN THE SOFTWARE.
     6.6   *
     6.7 - * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
     6.8 + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     6.9   * Use is subject to license terms.
    6.10   */
    6.11  
    6.12 @@ -46,6 +46,7 @@ struct fsi {
    6.13  	uint64_t f_off;
    6.14  	void *f_data;
    6.15  	fsi_plugin_t *f_plugin;
    6.16 +	char *f_bootstring;
    6.17  };
    6.18  
    6.19  struct fsi_file {
     7.1 --- a/tools/libfsimage/common/mapfile-GNU	Thu May 01 16:37:46 2008 +0100
     7.2 +++ b/tools/libfsimage/common/mapfile-GNU	Thu May 01 16:38:56 2008 +0100
     7.3 @@ -8,6 +8,9 @@ VERSION {
     7.4  			fsi_close_file;
     7.5  			fsi_read_file;
     7.6  			fsi_pread_file;
     7.7 +			fsi_bootstring_alloc;
     7.8 +			fsi_bootstring_free;
     7.9 +			fsi_fs_bootstring;
    7.10  	
    7.11  			fsip_fs_set_data;
    7.12  			fsip_file_alloc;
     8.1 --- a/tools/libfsimage/common/mapfile-SunOS	Thu May 01 16:37:46 2008 +0100
     8.2 +++ b/tools/libfsimage/common/mapfile-SunOS	Thu May 01 16:38:56 2008 +0100
     8.3 @@ -7,6 +7,9 @@ libfsimage.so.1.0 {
     8.4  		fsi_close_file;
     8.5  		fsi_read_file;
     8.6  		fsi_pread_file;
     8.7 +		fsi_bootstring_alloc;
     8.8 +		fsi_bootstring_free;
     8.9 +		fsi_fs_bootstring;
    8.10  
    8.11  		fsip_fs_set_data;
    8.12  		fsip_file_alloc;
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/tools/libfsimage/zfs/Makefile	Thu May 01 16:38:56 2008 +0100
     9.3 @@ -0,0 +1,37 @@
     9.4 +#
     9.5 +#  GRUB  --  GRand Unified Bootloader
     9.6 +#  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
     9.7 +#
     9.8 +#  This program is free software; you can redistribute it and/or modify
     9.9 +#  it under the terms of the GNU General Public License as published by
    9.10 +#  the Free Software Foundation; either version 2 of the License, or
    9.11 +#  (at your option) any later version.
    9.12 +#
    9.13 +#  This program is distributed in the hope that it will be useful,
    9.14 +#  but WITHOUT ANY WARRANTY; without even the implied warranty of
    9.15 +#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    9.16 +#  GNU General Public License for more details.
    9.17 +#
    9.18 +#  You should have received a copy of the GNU General Public License
    9.19 +#  along with this program; if not, write to the Free Software
    9.20 +#  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    9.21 +#
    9.22 +
    9.23 +# 
    9.24 +#  Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
    9.25 +#  Use is subject to license terms.
    9.26 +#
    9.27 +
    9.28 +XEN_ROOT = ../../..
    9.29 +
    9.30 +LIB_SRCS-y = fsys_zfs.c zfs_lzjb.c zfs_sha256.c zfs_fletcher.c
    9.31 +
    9.32 +FS = zfs
    9.33 +
    9.34 +.PHONY: all
    9.35 +all: fs-all
    9.36 +
    9.37 +.PHONY: install
    9.38 +install: fs-install
    9.39 +
    9.40 +include $(XEN_ROOT)/tools/libfsimage/Rules.mk
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/tools/libfsimage/zfs/fsys_zfs.c	Thu May 01 16:38:56 2008 +0100
    10.3 @@ -0,0 +1,1457 @@
    10.4 +/*
    10.5 + *  GRUB  --  GRand Unified Bootloader
    10.6 + *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
    10.7 + *
    10.8 + *  This program is free software; you can redistribute it and/or modify
    10.9 + *  it under the terms of the GNU General Public License as published by
   10.10 + *  the Free Software Foundation; either version 2 of the License, or
   10.11 + *  (at your option) any later version.
   10.12 + *
   10.13 + *  This program is distributed in the hope that it will be useful,
   10.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   10.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   10.16 + *  GNU General Public License for more details.
   10.17 + *
   10.18 + *  You should have received a copy of the GNU General Public License
   10.19 + *  along with this program; if not, write to the Free Software
   10.20 + *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   10.21 + */
   10.22 +/*
   10.23 + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
   10.24 + * Use is subject to license terms.
   10.25 + */
   10.26 +
   10.27 +/*
   10.28 + * All files in the zfs directory are derived from the OpenSolaris
   10.29 + * zfs grub files.  All files in the zfs-include directory were
   10.30 + * included without changes.
   10.31 + */
   10.32 +
   10.33 +/*
   10.34 + * The zfs plug-in routines for GRUB are:
   10.35 + *
   10.36 + * zfs_mount() - locates a valid uberblock of the root pool and reads
   10.37 + *		in its MOS at the memory address MOS.
   10.38 + *
   10.39 + * zfs_open() - locates a plain file object by following the MOS
   10.40 + *		and places its dnode at the memory address DNODE.
   10.41 + *
   10.42 + * zfs_read() - read in the data blocks pointed by the DNODE.
   10.43 + *
   10.44 + * ZFS_SCRATCH is used as a working area.
   10.45 + *
   10.46 + * (memory addr)   MOS      DNODE	ZFS_SCRATCH
   10.47 + *		    |         |          |
   10.48 + *	    +-------V---------V----------V---------------+
   10.49 + *   memory |       | dnode   | dnode    |  scratch      |
   10.50 + *	    |       | 512B    | 512B     |  area         |
   10.51 + *	    +--------------------------------------------+
   10.52 + */
   10.53 +
   10.54 +#include <stdio.h>
   10.55 +#include <strings.h>
   10.56 +
   10.57 +/* From "shared.h" */
   10.58 +#include "mb_info.h"
   10.59 +
   10.60 +/* Boot signature related defines for the findroot command */
   10.61 +#define	BOOTSIGN_DIR	"/boot/grub/bootsign"
   10.62 +#define	BOOTSIGN_BACKUP	"/etc/bootsign"
   10.63 +
   10.64 +/* Maybe redirect memory requests through grub_scratch_mem. */
   10.65 +#define	RAW_ADDR(x) (x)
   10.66 +#define	RAW_SEG(x) (x)
   10.67 +
   10.68 +/* ZFS will use the top 4 Meg of physical memory (below 4Gig) for sratch */
   10.69 +#define	ZFS_SCRATCH_SIZE 0x400000
   10.70 +
   10.71 +#define	MIN(x, y) ((x) < (y) ? (x) : (y))
   10.72 +/* End from shared.h */
   10.73 +
   10.74 +#include "fsys_zfs.h"
   10.75 +
   10.76 +/* cache for a file block of the currently zfs_open()-ed file */
   10.77 +#define	file_buf zfs_ba->zfs_file_buf
   10.78 +#define	file_start zfs_ba->zfs_file_start
   10.79 +#define	file_end zfs_ba->zfs_file_end
   10.80 +
   10.81 +/* cache for a dnode block */
   10.82 +#define	dnode_buf zfs_ba->zfs_dnode_buf
   10.83 +#define	dnode_mdn zfs_ba->zfs_dnode_mdn
   10.84 +#define	dnode_start zfs_ba->zfs_dnode_start
   10.85 +#define	dnode_end zfs_ba->zfs_dnode_end
   10.86 +
   10.87 +#define	stackbase zfs_ba->zfs_stackbase
   10.88 +
   10.89 +decomp_entry_t decomp_table[ZIO_COMPRESS_FUNCTIONS] =
   10.90 +{
   10.91 +	{"noop", 0},
   10.92 +	{"on", lzjb_decompress}, 	/* ZIO_COMPRESS_ON */
   10.93 +	{"off", 0},
   10.94 +	{"lzjb", lzjb_decompress}	/* ZIO_COMPRESS_LZJB */
   10.95 +};
   10.96 +
   10.97 +/* From disk_io.c */
   10.98 +/* ZFS root filesystem for booting */
   10.99 +#define	current_bootpath zfs_ba->zfs_current_bootpath
  10.100 +#define	current_rootpool zfs_ba->zfs_current_rootpool
  10.101 +#define	current_bootfs zfs_ba->zfs_current_bootfs
  10.102 +#define	current_bootfs_obj zfs_ba->zfs_current_bootfs_obj
  10.103 +#define	is_zfs_mount (*fsig_int1(ffi))
  10.104 +/* End from disk_io.c */
  10.105 +
  10.106 +#define	is_zfs_open zfs_ba->zfs_open
  10.107 +
  10.108 +/*
  10.109 + * Our own version of bcmp().
  10.110 + */
  10.111 +static int
  10.112 +zfs_bcmp(const void *s1, const void *s2, size_t n)
  10.113 +{
  10.114 +	const unsigned char *ps1 = s1;
  10.115 +	const unsigned char *ps2 = s2;
  10.116 +
  10.117 +	if (s1 != s2 && n != 0) {
  10.118 +		do {
  10.119 +			if (*ps1++ != *ps2++)
  10.120 +				return (1);
  10.121 +		} while (--n != 0);
  10.122 +	}
  10.123 +
  10.124 +	return (0);
  10.125 +}
  10.126 +
  10.127 +/*
  10.128 + * Our own version of log2().  Same thing as highbit()-1.
  10.129 + */
  10.130 +static int
  10.131 +zfs_log2(uint64_t num)
  10.132 +{
  10.133 +	int i = 0;
  10.134 +
  10.135 +	while (num > 1) {
  10.136 +		i++;
  10.137 +		num = num >> 1;
  10.138 +	}
  10.139 +
  10.140 +	return (i);
  10.141 +}
  10.142 +
  10.143 +/* Checksum Functions */
  10.144 +static void
  10.145 +zio_checksum_off(const void *buf, uint64_t size, zio_cksum_t *zcp)
  10.146 +{
  10.147 +	ZIO_SET_CHECKSUM(zcp, 0, 0, 0, 0);
  10.148 +}
  10.149 +
  10.150 +/* Checksum Table and Values */
  10.151 +zio_checksum_info_t zio_checksum_table[ZIO_CHECKSUM_FUNCTIONS] = {
  10.152 +	{{NULL,			NULL},			0, 0,	"inherit"},
  10.153 +	{{NULL,			NULL},			0, 0,	"on"},
  10.154 +	{{zio_checksum_off,	zio_checksum_off},	0, 0,	"off"},
  10.155 +	{{zio_checksum_SHA256,	zio_checksum_SHA256},	1, 1,	"label"},
  10.156 +	{{zio_checksum_SHA256,	zio_checksum_SHA256},	1, 1,	"gang_header"},
  10.157 +	{{fletcher_2_native,	fletcher_2_byteswap},	0, 1,	"zilog"},
  10.158 +	{{fletcher_2_native,	fletcher_2_byteswap},	0, 0,	"fletcher2"},
  10.159 +	{{fletcher_4_native,	fletcher_4_byteswap},	1, 0,	"fletcher4"},
  10.160 +	{{zio_checksum_SHA256,	zio_checksum_SHA256},	1, 0,	"SHA256"}
  10.161 +};
  10.162 +
  10.163 +/*
  10.164 + * zio_checksum_verify: Provides support for checksum verification.
  10.165 + *
  10.166 + * Fletcher2, Fletcher4, and SHA256 are supported.
  10.167 + *
  10.168 + * Return:
  10.169 + * 	-1 = Failure
  10.170 + *	 0 = Success
  10.171 + */
  10.172 +static int
  10.173 +zio_checksum_verify(blkptr_t *bp, char *data, int size)
  10.174 +{
  10.175 +	zio_cksum_t zc = bp->blk_cksum;
  10.176 +	uint32_t checksum = BP_IS_GANG(bp) ? ZIO_CHECKSUM_GANG_HEADER :
  10.177 +	    BP_GET_CHECKSUM(bp);
  10.178 +	int byteswap = BP_SHOULD_BYTESWAP(bp);
  10.179 +	zio_block_tail_t *zbt = (zio_block_tail_t *)(data + size) - 1;
  10.180 +	zio_checksum_info_t *ci = &zio_checksum_table[checksum];
  10.181 +	zio_cksum_t actual_cksum, expected_cksum;
  10.182 +
  10.183 +	/* byteswap is not supported */
  10.184 +	if (byteswap)
  10.185 +		return (-1);
  10.186 +
  10.187 +	if (checksum >= ZIO_CHECKSUM_FUNCTIONS || ci->ci_func[0] == NULL)
  10.188 +		return (-1);
  10.189 +
  10.190 +	if (ci->ci_zbt) {
  10.191 +		if (checksum == ZIO_CHECKSUM_GANG_HEADER) {
  10.192 +			/*
  10.193 +			 * 'gang blocks' is not supported.
  10.194 +			 */
  10.195 +			return (-1);
  10.196 +		}
  10.197 +
  10.198 +		if (zbt->zbt_magic == BSWAP_64(ZBT_MAGIC)) {
  10.199 +			/* byte swapping is not supported */
  10.200 +			return (-1);
  10.201 +		} else {
  10.202 +			expected_cksum = zbt->zbt_cksum;
  10.203 +			zbt->zbt_cksum = zc;
  10.204 +			ci->ci_func[0](data, size, &actual_cksum);
  10.205 +			zbt->zbt_cksum = expected_cksum;
  10.206 +		}
  10.207 +		zc = expected_cksum;
  10.208 +
  10.209 +	} else {
  10.210 +		if (BP_IS_GANG(bp))
  10.211 +			return (-1);
  10.212 +		ci->ci_func[byteswap](data, size, &actual_cksum);
  10.213 +	}
  10.214 +
  10.215 +	if ((actual_cksum.zc_word[0] - zc.zc_word[0]) |
  10.216 +	    (actual_cksum.zc_word[1] - zc.zc_word[1]) |
  10.217 +	    (actual_cksum.zc_word[2] - zc.zc_word[2]) |
  10.218 +	    (actual_cksum.zc_word[3] - zc.zc_word[3]))
  10.219 +		return (-1);
  10.220 +
  10.221 +	return (0);
  10.222 +}
  10.223 +
  10.224 +/*
  10.225 + * vdev_label_offset takes "offset" (the offset within a vdev_label) and
  10.226 + * returns its physical disk offset (starting from the beginning of the vdev).
  10.227 + *
  10.228 + * Input:
  10.229 + *	psize	: Physical size of this vdev
  10.230 + *      l	: Label Number (0-3)
  10.231 + *	offset	: The offset with a vdev_label in which we want the physical
  10.232 + *		  address
  10.233 + * Return:
  10.234 + * 	Success : physical disk offset
  10.235 + * 	Failure : errnum = ERR_BAD_ARGUMENT, return value is meaningless
  10.236 + */
  10.237 +static uint64_t
  10.238 +vdev_label_offset(fsi_file_t *ffi, uint64_t psize, int l, uint64_t offset)
  10.239 +{
  10.240 +	/* XXX Need to add back label support! */
  10.241 +	if (l >= VDEV_LABELS/2 || offset > sizeof (vdev_label_t)) {
  10.242 +		errnum = ERR_BAD_ARGUMENT;
  10.243 +		return (0);
  10.244 +	}
  10.245 +
  10.246 +	return (offset + l * sizeof (vdev_label_t) + (l < VDEV_LABELS / 2 ?
  10.247 +	    0 : psize - VDEV_LABELS * sizeof (vdev_label_t)));
  10.248 +
  10.249 +}
  10.250 +
  10.251 +/*
  10.252 + * vdev_uberblock_compare takes two uberblock structures and returns an integer
  10.253 + * indicating the more recent of the two.
  10.254 + * 	Return Value = 1 if ub2 is more recent
  10.255 + * 	Return Value = -1 if ub1 is more recent
  10.256 + * The most recent uberblock is determined using its transaction number and
  10.257 + * timestamp.  The uberblock with the highest transaction number is
  10.258 + * considered "newer".  If the transaction numbers of the two blocks match, the
  10.259 + * timestamps are compared to determine the "newer" of the two.
  10.260 + */
  10.261 +static int
  10.262 +vdev_uberblock_compare(uberblock_t *ub1, uberblock_t *ub2)
  10.263 +{
  10.264 +	if (ub1->ub_txg < ub2->ub_txg)
  10.265 +		return (-1);
  10.266 +	if (ub1->ub_txg > ub2->ub_txg)
  10.267 +		return (1);
  10.268 +
  10.269 +	if (ub1->ub_timestamp < ub2->ub_timestamp)
  10.270 +		return (-1);
  10.271 +	if (ub1->ub_timestamp > ub2->ub_timestamp)
  10.272 +		return (1);
  10.273 +
  10.274 +	return (0);
  10.275 +}
  10.276 +
  10.277 +/*
  10.278 + * Three pieces of information are needed to verify an uberblock: the magic
  10.279 + * number, the version number, and the checksum.
  10.280 + *
  10.281 + * Currently Implemented: version number, magic number
  10.282 + * Need to Implement: checksum
  10.283 + *
  10.284 + * Return:
  10.285 + *     0 - Success
  10.286 + *    -1 - Failure
  10.287 + */
  10.288 +static int
  10.289 +uberblock_verify(uberblock_phys_t *ub, int offset)
  10.290 +{
  10.291 +
  10.292 +	uberblock_t *uber = &ub->ubp_uberblock;
  10.293 +	blkptr_t bp;
  10.294 +
  10.295 +	BP_ZERO(&bp);
  10.296 +	BP_SET_CHECKSUM(&bp, ZIO_CHECKSUM_LABEL);
  10.297 +	BP_SET_BYTEORDER(&bp, ZFS_HOST_BYTEORDER);
  10.298 +	ZIO_SET_CHECKSUM(&bp.blk_cksum, offset, 0, 0, 0);
  10.299 +
  10.300 +	if (zio_checksum_verify(&bp, (char *)ub, UBERBLOCK_SIZE) != 0)
  10.301 +		return (-1);
  10.302 +
  10.303 +	if (uber->ub_magic == UBERBLOCK_MAGIC &&
  10.304 +	    uber->ub_version >= SPA_VERSION_1 &&
  10.305 +	    uber->ub_version <= SPA_VERSION)
  10.306 +		return (0);
  10.307 +
  10.308 +	return (-1);
  10.309 +}
  10.310 +
  10.311 +/*
  10.312 + * Find the best uberblock.
  10.313 + * Return:
  10.314 + *    Success - Pointer to the best uberblock.
  10.315 + *    Failure - NULL
  10.316 + */
  10.317 +static uberblock_phys_t *
  10.318 +find_bestub(fsi_file_t *ffi, uberblock_phys_t *ub_array, int label)
  10.319 +{
  10.320 +	uberblock_phys_t *ubbest = NULL;
  10.321 +	int i, offset;
  10.322 +
  10.323 +	for (i = 0; i < (VDEV_UBERBLOCK_RING >> VDEV_UBERBLOCK_SHIFT); i++) {
  10.324 +		offset = vdev_label_offset(ffi, 0, label,
  10.325 +		    VDEV_UBERBLOCK_OFFSET(i));
  10.326 +		if (errnum == ERR_BAD_ARGUMENT)
  10.327 +			return (NULL);
  10.328 +		if (uberblock_verify(&ub_array[i], offset) == 0) {
  10.329 +			if (ubbest == NULL) {
  10.330 +				ubbest = &ub_array[i];
  10.331 +			} else if (vdev_uberblock_compare(
  10.332 +			    &(ub_array[i].ubp_uberblock),
  10.333 +			    &(ubbest->ubp_uberblock)) > 0) {
  10.334 +				ubbest = &ub_array[i];
  10.335 +			}
  10.336 +		}
  10.337 +	}
  10.338 +
  10.339 +	return (ubbest);
  10.340 +}
  10.341 +
  10.342 +/*
  10.343 + * Read in a block and put its uncompressed data in buf.
  10.344 + *
  10.345 + * Return:
  10.346 + *	0 - success
  10.347 + *	errnum - failure
  10.348 + */
  10.349 +static int
  10.350 +zio_read(fsi_file_t *ffi, blkptr_t *bp, void *buf, char *stack)
  10.351 +{
  10.352 +	uint64_t offset, sector;
  10.353 +	int psize, lsize;
  10.354 +	int i, comp, cksum;
  10.355 +
  10.356 +	psize = BP_GET_PSIZE(bp);
  10.357 +	lsize = BP_GET_LSIZE(bp);
  10.358 +	comp = BP_GET_COMPRESS(bp);
  10.359 +	cksum = BP_GET_CHECKSUM(bp);
  10.360 +
  10.361 +	if ((unsigned int)comp >= ZIO_COMPRESS_FUNCTIONS ||
  10.362 +	    (comp != ZIO_COMPRESS_OFF &&
  10.363 +	    decomp_table[comp].decomp_func == NULL))
  10.364 +		return (ERR_FSYS_CORRUPT);
  10.365 +
  10.366 +	/* pick a good dva from the block pointer */
  10.367 +	for (i = 0; i < SPA_DVAS_PER_BP; i++) {
  10.368 +
  10.369 +		if (bp->blk_dva[i].dva_word[0] == 0 &&
  10.370 +		    bp->blk_dva[i].dva_word[1] == 0)
  10.371 +			continue;
  10.372 +
  10.373 +		/* read in a block */
  10.374 +		offset = DVA_GET_OFFSET(&bp->blk_dva[i]);
  10.375 +		sector =  DVA_OFFSET_TO_PHYS_SECTOR(offset);
  10.376 +
  10.377 +		if (comp != ZIO_COMPRESS_OFF) {
  10.378 +
  10.379 +			if (devread(ffi, sector, 0, psize, stack) == 0)
  10.380 +				continue;
  10.381 +			if (zio_checksum_verify(bp, stack, psize) != 0)
  10.382 +				continue;
  10.383 +			decomp_table[comp].decomp_func(stack, buf, psize,
  10.384 +			    lsize);
  10.385 +		} else {
  10.386 +			if (devread(ffi, sector, 0, psize, buf) == 0)
  10.387 +				continue;
  10.388 +			if (zio_checksum_verify(bp, buf, psize) != 0)
  10.389 +				continue;
  10.390 +		}
  10.391 +		return (0);
  10.392 +	}
  10.393 +
  10.394 +	return (ERR_FSYS_CORRUPT);
  10.395 +}
  10.396 +
  10.397 +/*
  10.398 + * Get the block from a block id.
  10.399 + * push the block onto the stack.
  10.400 + *
  10.401 + * Return:
  10.402 + * 	0 - success
  10.403 + * 	errnum - failure
  10.404 + */
  10.405 +static int
  10.406 +dmu_read(fsi_file_t *ffi, dnode_phys_t *dn, uint64_t blkid, void *buf,
  10.407 +    char *stack)
  10.408 +{
  10.409 +	int idx, level;
  10.410 +	blkptr_t *bp_array = dn->dn_blkptr;
  10.411 +	int epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
  10.412 +	blkptr_t *bp, *tmpbuf;
  10.413 +
  10.414 +	bp = (blkptr_t *)stack;
  10.415 +	stack += sizeof (blkptr_t);
  10.416 +
  10.417 +	tmpbuf = (blkptr_t *)stack;
  10.418 +	stack += 1<<dn->dn_indblkshift;
  10.419 +
  10.420 +	for (level = dn->dn_nlevels - 1; level >= 0; level--) {
  10.421 +		idx = (blkid >> (epbs * level)) & ((1<<epbs)-1);
  10.422 +		*bp = bp_array[idx];
  10.423 +		if (level == 0)
  10.424 +			tmpbuf = buf;
  10.425 +		if (BP_IS_HOLE(bp)) {
  10.426 +			grub_memset(buf, 0,
  10.427 +			    dn->dn_datablkszsec << SPA_MINBLOCKSHIFT);
  10.428 +			break;
  10.429 +		} else if ((errnum = zio_read(ffi, bp, tmpbuf, stack))) {
  10.430 +			return (errnum);
  10.431 +		}
  10.432 +		bp_array = tmpbuf;
  10.433 +	}
  10.434 +
  10.435 +	return (0);
  10.436 +}
  10.437 +
  10.438 +/*
  10.439 + * mzap_lookup: Looks up property described by "name" and returns the value
  10.440 + * in "value".
  10.441 + *
  10.442 + * Return:
  10.443 + *	0 - success
  10.444 + *	errnum - failure
  10.445 + */
  10.446 +static int
  10.447 +mzap_lookup(mzap_phys_t *zapobj, int objsize, char *name,
  10.448 +	uint64_t *value)
  10.449 +{
  10.450 +	int i, chunks;
  10.451 +	mzap_ent_phys_t *mzap_ent = zapobj->mz_chunk;
  10.452 +
  10.453 +	chunks = objsize/MZAP_ENT_LEN - 1;
  10.454 +	for (i = 0; i < chunks; i++) {
  10.455 +		if (strcmp(mzap_ent[i].mze_name, name) == 0) {
  10.456 +			*value = mzap_ent[i].mze_value;
  10.457 +			return (0);
  10.458 +		}
  10.459 +	}
  10.460 +
  10.461 +	return (ERR_FSYS_CORRUPT);
  10.462 +}
  10.463 +
  10.464 +static uint64_t
  10.465 +zap_hash(fsi_file_t *ffi, uint64_t salt, const char *name)
  10.466 +{
  10.467 +	static uint64_t table[256];
  10.468 +	const uint8_t *cp;
  10.469 +	uint8_t c;
  10.470 +	uint64_t crc = salt;
  10.471 +
  10.472 +	if (table[128] == 0) {
  10.473 +		uint64_t *ct;
  10.474 +		int i, j;
  10.475 +		for (i = 0; i < 256; i++) {
  10.476 +			for (ct = table + i, *ct = i, j = 8; j > 0; j--)
  10.477 +				*ct = (*ct >> 1) ^ (-(*ct & 1) &
  10.478 +				    ZFS_CRC64_POLY);
  10.479 +		}
  10.480 +	}
  10.481 +
  10.482 +	if (crc == 0 || table[128] != ZFS_CRC64_POLY) {
  10.483 +		errnum = ERR_FSYS_CORRUPT;
  10.484 +		return (0);
  10.485 +	}
  10.486 +
  10.487 +	for (cp = (const uint8_t *)name; (c = *cp) != '\0'; cp++)
  10.488 +		crc = (crc >> 8) ^ table[(crc ^ c) & 0xFF];
  10.489 +
  10.490 +	/*
  10.491 +	 * Only use 28 bits, since we need 4 bits in the cookie for the
  10.492 +	 * collision differentiator.  We MUST use the high bits, since
  10.493 +	 * those are the onces that we first pay attention to when
  10.494 +	 * chosing the bucket.
  10.495 +	 */
  10.496 +	crc &= ~((1ULL << (64 - ZAP_HASHBITS)) - 1);
  10.497 +
  10.498 +	return (crc);
  10.499 +}
  10.500 +
  10.501 +/*
  10.502 + * Only to be used on 8-bit arrays.
  10.503 + * array_len is actual len in bytes (not encoded le_value_length).
  10.504 + * buf is null-terminated.
  10.505 + */
  10.506 +static int
  10.507 +zap_leaf_array_equal(zap_leaf_phys_t *l, int blksft, int chunk,
  10.508 +    int array_len, const char *buf)
  10.509 +{
  10.510 +	int bseen = 0;
  10.511 +
  10.512 +	while (bseen < array_len) {
  10.513 +		struct zap_leaf_array *la =
  10.514 +		    &ZAP_LEAF_CHUNK(l, blksft, chunk).l_array;
  10.515 +		int toread = MIN(array_len - bseen, ZAP_LEAF_ARRAY_BYTES);
  10.516 +
  10.517 +		if (chunk >= ZAP_LEAF_NUMCHUNKS(blksft))
  10.518 +			return (0);
  10.519 +
  10.520 +		if (zfs_bcmp(la->la_array, buf + bseen, toread) != 0)
  10.521 +			break;
  10.522 +		chunk = la->la_next;
  10.523 +		bseen += toread;
  10.524 +	}
  10.525 +	return (bseen == array_len);
  10.526 +}
  10.527 +
  10.528 +/*
  10.529 + * Given a zap_leaf_phys_t, walk thru the zap leaf chunks to get the
  10.530 + * value for the property "name".
  10.531 + *
  10.532 + * Return:
  10.533 + *	0 - success
  10.534 + *	errnum - failure
  10.535 + */
  10.536 +static int
  10.537 +zap_leaf_lookup(zap_leaf_phys_t *l, int blksft, uint64_t h,
  10.538 +    const char *name, uint64_t *value)
  10.539 +{
  10.540 +	uint16_t chunk;
  10.541 +	struct zap_leaf_entry *le;
  10.542 +
  10.543 +	/* Verify if this is a valid leaf block */
  10.544 +	if (l->l_hdr.lh_block_type != ZBT_LEAF)
  10.545 +		return (ERR_FSYS_CORRUPT);
  10.546 +	if (l->l_hdr.lh_magic != ZAP_LEAF_MAGIC)
  10.547 +		return (ERR_FSYS_CORRUPT);
  10.548 +
  10.549 +	for (chunk = l->l_hash[LEAF_HASH(blksft, h)];
  10.550 +	    chunk != CHAIN_END; chunk = le->le_next) {
  10.551 +
  10.552 +		if (chunk >= ZAP_LEAF_NUMCHUNKS(blksft))
  10.553 +			return (ERR_FSYS_CORRUPT);
  10.554 +
  10.555 +		le = ZAP_LEAF_ENTRY(l, blksft, chunk);
  10.556 +
  10.557 +		/* Verify the chunk entry */
  10.558 +		if (le->le_type != ZAP_CHUNK_ENTRY)
  10.559 +			return (ERR_FSYS_CORRUPT);
  10.560 +
  10.561 +		if (le->le_hash != h)
  10.562 +			continue;
  10.563 +
  10.564 +		if (zap_leaf_array_equal(l, blksft, le->le_name_chunk,
  10.565 +		    le->le_name_length, name)) {
  10.566 +
  10.567 +			struct zap_leaf_array *la;
  10.568 +			uint8_t *ip;
  10.569 +
  10.570 +			if (le->le_int_size != 8 || le->le_value_length != 1)
  10.571 +				return (ERR_FSYS_CORRUPT);
  10.572 +
  10.573 +			/* get the uint64_t property value */
  10.574 +			la = &ZAP_LEAF_CHUNK(l, blksft,
  10.575 +			    le->le_value_chunk).l_array;
  10.576 +			ip = la->la_array;
  10.577 +
  10.578 +			*value = (uint64_t)ip[0] << 56 | (uint64_t)ip[1] << 48 |
  10.579 +			    (uint64_t)ip[2] << 40 | (uint64_t)ip[3] << 32 |
  10.580 +			    (uint64_t)ip[4] << 24 | (uint64_t)ip[5] << 16 |
  10.581 +			    (uint64_t)ip[6] << 8 | (uint64_t)ip[7];
  10.582 +
  10.583 +			return (0);
  10.584 +		}
  10.585 +	}
  10.586 +
  10.587 +	return (ERR_FSYS_CORRUPT);
  10.588 +}
  10.589 +
  10.590 +/*
  10.591 + * Fat ZAP lookup
  10.592 + *
  10.593 + * Return:
  10.594 + *	0 - success
  10.595 + *	errnum - failure
  10.596 + */
  10.597 +static int
  10.598 +fzap_lookup(fsi_file_t *ffi, dnode_phys_t *zap_dnode, zap_phys_t *zap,
  10.599 +    char *name, uint64_t *value, char *stack)
  10.600 +{
  10.601 +	zap_leaf_phys_t *l;
  10.602 +	uint64_t hash, idx, blkid;
  10.603 +	int blksft = zfs_log2(zap_dnode->dn_datablkszsec << DNODE_SHIFT);
  10.604 +
  10.605 +	/* Verify if this is a fat zap header block */
  10.606 +	if (zap->zap_magic != (uint64_t)ZAP_MAGIC)
  10.607 +		return (ERR_FSYS_CORRUPT);
  10.608 +
  10.609 +	hash = zap_hash(ffi, zap->zap_salt, name);
  10.610 +	if (errnum)
  10.611 +		return (errnum);
  10.612 +
  10.613 +	/* get block id from index */
  10.614 +	if (zap->zap_ptrtbl.zt_numblks != 0) {
  10.615 +		/* external pointer tables not supported */
  10.616 +		return (ERR_FSYS_CORRUPT);
  10.617 +	}
  10.618 +	idx = ZAP_HASH_IDX(hash, zap->zap_ptrtbl.zt_shift);
  10.619 +	blkid = ((uint64_t *)zap)[idx + (1<<(blksft-3-1))];
  10.620 +
  10.621 +	/* Get the leaf block */
  10.622 +	l = (zap_leaf_phys_t *)stack;
  10.623 +	stack += 1<<blksft;
  10.624 +	if ((errnum = dmu_read(ffi, zap_dnode, blkid, l, stack)))
  10.625 +		return (errnum);
  10.626 +
  10.627 +	return (zap_leaf_lookup(l, blksft, hash, name, value));
  10.628 +}
  10.629 +
  10.630 +/*
  10.631 + * Read in the data of a zap object and find the value for a matching
  10.632 + * property name.
  10.633 + *
  10.634 + * Return:
  10.635 + *	0 - success
  10.636 + *	errnum - failure
  10.637 + */
  10.638 +static int
  10.639 +zap_lookup(fsi_file_t *ffi, dnode_phys_t *zap_dnode, char *name,
  10.640 +    uint64_t *val, char *stack)
  10.641 +{
  10.642 +	uint64_t block_type;
  10.643 +	int size;
  10.644 +	void *zapbuf;
  10.645 +
  10.646 +	/* Read in the first block of the zap object data. */
  10.647 +	zapbuf = stack;
  10.648 +	size = zap_dnode->dn_datablkszsec << SPA_MINBLOCKSHIFT;
  10.649 +	stack += size;
  10.650 +	if ((errnum = dmu_read(ffi, zap_dnode, 0, zapbuf, stack)))
  10.651 +		return (errnum);
  10.652 +
  10.653 +	block_type = *((uint64_t *)zapbuf);
  10.654 +
  10.655 +	if (block_type == ZBT_MICRO) {
  10.656 +		return (mzap_lookup(zapbuf, size, name, val));
  10.657 +	} else if (block_type == ZBT_HEADER) {
  10.658 +		/* this is a fat zap */
  10.659 +		return (fzap_lookup(ffi, zap_dnode, zapbuf, name,
  10.660 +		    val, stack));
  10.661 +	}
  10.662 +
  10.663 +	return (ERR_FSYS_CORRUPT);
  10.664 +}
  10.665 +
  10.666 +/*
  10.667 + * Get the dnode of an object number from the metadnode of an object set.
  10.668 + *
  10.669 + * Input
  10.670 + *	mdn - metadnode to get the object dnode
  10.671 + *	objnum - object number for the object dnode
  10.672 + *	buf - data buffer that holds the returning dnode
  10.673 + *	stack - scratch area
  10.674 + *
  10.675 + * Return:
  10.676 + *	0 - success
  10.677 + *	errnum - failure
  10.678 + */
  10.679 +static int
  10.680 +dnode_get(fsi_file_t *ffi, dnode_phys_t *mdn, uint64_t objnum,
  10.681 +    uint8_t type, dnode_phys_t *buf, char *stack)
  10.682 +{
  10.683 +	uint64_t blkid, blksz; /* the block id this object dnode is in */
  10.684 +	int epbs; /* shift of number of dnodes in a block */
  10.685 +	int idx; /* index within a block */
  10.686 +	dnode_phys_t *dnbuf;
  10.687 +	zfs_bootarea_t *zfs_ba = (zfs_bootarea_t *)ffi->ff_fsi->f_data;
  10.688 +
  10.689 +	blksz = mdn->dn_datablkszsec << SPA_MINBLOCKSHIFT;
  10.690 +	epbs = zfs_log2(blksz) - DNODE_SHIFT;
  10.691 +	blkid = objnum >> epbs;
  10.692 +	idx = objnum & ((1<<epbs)-1);
  10.693 +
  10.694 +	if (dnode_buf != NULL && dnode_mdn == mdn &&
  10.695 +	    objnum >= dnode_start && objnum < dnode_end) {
  10.696 +		grub_memmove(buf, &dnode_buf[idx], DNODE_SIZE);
  10.697 +		VERIFY_DN_TYPE(buf, type);
  10.698 +		return (0);
  10.699 +	}
  10.700 +
  10.701 +	if (dnode_buf && blksz == 1<<DNODE_BLOCK_SHIFT) {
  10.702 +		dnbuf = dnode_buf;
  10.703 +		dnode_mdn = mdn;
  10.704 +		dnode_start = blkid << epbs;
  10.705 +		dnode_end = (blkid + 1) << epbs;
  10.706 +	} else {
  10.707 +		dnbuf = (dnode_phys_t *)stack;
  10.708 +		stack += blksz;
  10.709 +	}
  10.710 +
  10.711 +	if ((errnum = dmu_read(ffi, mdn, blkid, (char *)dnbuf, stack)))
  10.712 +		return (errnum);
  10.713 +
  10.714 +	grub_memmove(buf, &dnbuf[idx], DNODE_SIZE);
  10.715 +	VERIFY_DN_TYPE(buf, type);
  10.716 +
  10.717 +	return (0);
  10.718 +}
  10.719 +
  10.720 +/*
  10.721 + * Check if this is a special file that resides at the top
  10.722 + * dataset of the pool. Currently this is the GRUB menu,
  10.723 + * boot signature and boot signature backup.
  10.724 + * str starts with '/'.
  10.725 + */
  10.726 +static int
  10.727 +is_top_dataset_file(char *str)
  10.728 +{
  10.729 +	char *tptr;
  10.730 +
  10.731 +	if (((tptr = strstr(str, "menu.lst"))) &&
  10.732 +	    (tptr[8] == '\0' || tptr[8] == ' ') &&
  10.733 +	    *(tptr-1) == '/')
  10.734 +		return (1);
  10.735 +
  10.736 +	if (strncmp(str, BOOTSIGN_DIR"/",
  10.737 +	    strlen(BOOTSIGN_DIR) + 1) == 0)
  10.738 +		return (1);
  10.739 +
  10.740 +	if (strcmp(str, BOOTSIGN_BACKUP) == 0)
  10.741 +		return (1);
  10.742 +
  10.743 +	return (0);
  10.744 +}
  10.745 +
  10.746 +/*
  10.747 + * Get the file dnode for a given file name where mdn is the meta dnode
  10.748 + * for this ZFS object set. When found, place the file dnode in dn.
  10.749 + * The 'path' argument will be mangled.
  10.750 + *
  10.751 + * Return:
  10.752 + *	0 - success
  10.753 + *	errnum - failure
  10.754 + */
  10.755 +static int
  10.756 +dnode_get_path(fsi_file_t *ffi, dnode_phys_t *mdn, char *path,
  10.757 +    dnode_phys_t *dn, char *stack)
  10.758 +{
  10.759 +	uint64_t objnum, version;
  10.760 +	char *cname, ch;
  10.761 +
  10.762 +	if ((errnum = dnode_get(ffi, mdn, MASTER_NODE_OBJ, DMU_OT_MASTER_NODE,
  10.763 +	    dn, stack)))
  10.764 +		return (errnum);
  10.765 +
  10.766 +	if ((errnum = zap_lookup(ffi, dn, ZPL_VERSION_STR, &version, stack)))
  10.767 +		return (errnum);
  10.768 +	if (version > ZPL_VERSION)
  10.769 +		return (-1);
  10.770 +
  10.771 +	if ((errnum = zap_lookup(ffi, dn, ZFS_ROOT_OBJ, &objnum, stack)))
  10.772 +		return (errnum);
  10.773 +
  10.774 +	if ((errnum = dnode_get(ffi, mdn, objnum, DMU_OT_DIRECTORY_CONTENTS,
  10.775 +	    dn, stack)))
  10.776 +		return (errnum);
  10.777 +
  10.778 +	/* skip leading slashes */
  10.779 +	while (*path == '/')
  10.780 +		path++;
  10.781 +
  10.782 +	while (*path && !isspace(*path)) {
  10.783 +
  10.784 +		/* get the next component name */
  10.785 +		cname = path;
  10.786 +		while (*path && !isspace(*path) && *path != '/')
  10.787 +			path++;
  10.788 +		ch = *path;
  10.789 +		*path = 0;   /* ensure null termination */
  10.790 +
  10.791 +		if ((errnum = zap_lookup(ffi, dn, cname, &objnum, stack)))
  10.792 +			return (errnum);
  10.793 +
  10.794 +		objnum = ZFS_DIRENT_OBJ(objnum);
  10.795 +		if ((errnum = dnode_get(ffi, mdn, objnum, 0, dn, stack)))
  10.796 +			return (errnum);
  10.797 +
  10.798 +		*path = ch;
  10.799 +		while (*path == '/')
  10.800 +			path++;
  10.801 +	}
  10.802 +
  10.803 +	/* We found the dnode for this file. Verify if it is a plain file. */
  10.804 +	VERIFY_DN_TYPE(dn, DMU_OT_PLAIN_FILE_CONTENTS);
  10.805 +
  10.806 +	return (0);
  10.807 +}
  10.808 +
  10.809 +/*
  10.810 + * Get the default 'bootfs' property value from the rootpool.
  10.811 + *
  10.812 + * Return:
  10.813 + *	0 - success
  10.814 + *	errnum -failure
  10.815 + */
  10.816 +static int
  10.817 +get_default_bootfsobj(fsi_file_t *ffi, dnode_phys_t *mosmdn,
  10.818 +    uint64_t *obj, char *stack)
  10.819 +{
  10.820 +	uint64_t objnum = 0;
  10.821 +	dnode_phys_t *dn = (dnode_phys_t *)stack;
  10.822 +	stack += DNODE_SIZE;
  10.823 +
  10.824 +	if ((errnum = dnode_get(ffi, mosmdn, DMU_POOL_DIRECTORY_OBJECT,
  10.825 +	    DMU_OT_OBJECT_DIRECTORY, dn, stack)))
  10.826 +		return (errnum);
  10.827 +
  10.828 +	/*
  10.829 +	 * find the object number for 'pool_props', and get the dnode
  10.830 +	 * of the 'pool_props'.
  10.831 +	 */
  10.832 +	if (zap_lookup(ffi, dn, DMU_POOL_PROPS, &objnum, stack))
  10.833 +		return (ERR_FILESYSTEM_NOT_FOUND);
  10.834 +
  10.835 +	if ((errnum = dnode_get(ffi, mosmdn, objnum, DMU_OT_POOL_PROPS, dn,
  10.836 +	    stack)))
  10.837 +		return (errnum);
  10.838 +
  10.839 +	if (zap_lookup(ffi, dn, ZPOOL_PROP_BOOTFS, &objnum, stack))
  10.840 +		return (ERR_FILESYSTEM_NOT_FOUND);
  10.841 +
  10.842 +	if (!objnum)
  10.843 +		return (ERR_FILESYSTEM_NOT_FOUND);
  10.844 +
  10.845 +
  10.846 +	*obj = objnum;
  10.847 +	return (0);
  10.848 +}
  10.849 +
  10.850 +/*
  10.851 + * Given a MOS metadnode, get the metadnode of a given filesystem name (fsname),
  10.852 + * e.g. pool/rootfs, or a given object number (obj), e.g. the object number
  10.853 + * of pool/rootfs.
  10.854 + *
  10.855 + * If no fsname and no obj are given, return the DSL_DIR metadnode.
  10.856 + * If fsname is given, return its metadnode and its matching object number.
  10.857 + * If only obj is given, return the metadnode for this object number.
  10.858 + *
  10.859 + * Return:
  10.860 + *	0 - success
  10.861 + *	errnum - failure
  10.862 + */
  10.863 +static int
  10.864 +get_objset_mdn(fsi_file_t *ffi, dnode_phys_t *mosmdn, char *fsname,
  10.865 +    uint64_t *obj, dnode_phys_t *mdn, char *stack)
  10.866 +{
  10.867 +	uint64_t objnum, headobj;
  10.868 +	char *cname, ch;
  10.869 +	blkptr_t *bp;
  10.870 +	objset_phys_t *osp;
  10.871 +
  10.872 +	if (fsname == NULL && obj) {
  10.873 +		headobj = *obj;
  10.874 +		goto skip;
  10.875 +	}
  10.876 +
  10.877 +	if ((errnum = dnode_get(ffi, mosmdn, DMU_POOL_DIRECTORY_OBJECT,
  10.878 +	    DMU_OT_OBJECT_DIRECTORY, mdn, stack)))
  10.879 +		return (errnum);
  10.880 +
  10.881 +	if ((errnum = zap_lookup(ffi, mdn, DMU_POOL_ROOT_DATASET, &objnum,
  10.882 +	    stack)))
  10.883 +		return (errnum);
  10.884 +
  10.885 +	if ((errnum = dnode_get(ffi, mosmdn, objnum, DMU_OT_DSL_DIR, mdn,
  10.886 +	    stack)))
  10.887 +		return (errnum);
  10.888 +
  10.889 +	if (fsname == NULL) {
  10.890 +		headobj =
  10.891 +		    ((dsl_dir_phys_t *)DN_BONUS(mdn))->dd_head_dataset_obj;
  10.892 +		goto skip;
  10.893 +	}
  10.894 +
  10.895 +	/* take out the pool name */
  10.896 +	while (*fsname && !isspace(*fsname) && *fsname != '/')
  10.897 +		fsname++;
  10.898 +
  10.899 +	while (*fsname && !isspace(*fsname)) {
  10.900 +		uint64_t childobj;
  10.901 +
  10.902 +		while (*fsname == '/')
  10.903 +			fsname++;
  10.904 +
  10.905 +		cname = fsname;
  10.906 +		while (*fsname && !isspace(*fsname) && *fsname != '/')
  10.907 +			fsname++;
  10.908 +		ch = *fsname;
  10.909 +		*fsname = 0;
  10.910 +
  10.911 +		childobj =
  10.912 +		    ((dsl_dir_phys_t *)DN_BONUS(mdn))->dd_child_dir_zapobj;
  10.913 +		if ((errnum = dnode_get(ffi, mosmdn, childobj,
  10.914 +		    DMU_OT_DSL_DIR_CHILD_MAP, mdn, stack)))
  10.915 +			return (errnum);
  10.916 +
  10.917 +		if (zap_lookup(ffi, mdn, cname, &objnum, stack))
  10.918 +			return (ERR_FILESYSTEM_NOT_FOUND);
  10.919 +
  10.920 +		if ((errnum = dnode_get(ffi, mosmdn, objnum, DMU_OT_DSL_DIR,
  10.921 +		    mdn, stack)))
  10.922 +			return (errnum);
  10.923 +
  10.924 +		*fsname = ch;
  10.925 +	}
  10.926 +	headobj = ((dsl_dir_phys_t *)DN_BONUS(mdn))->dd_head_dataset_obj;
  10.927 +	if (obj)
  10.928 +		*obj = headobj;
  10.929 +
  10.930 +skip:
  10.931 +	if ((errnum = dnode_get(ffi, mosmdn, headobj, DMU_OT_DSL_DATASET, mdn,
  10.932 +	    stack)))
  10.933 +		return (errnum);
  10.934 +
  10.935 +	/* TODO: Add snapshot support here - for fsname=snapshot-name */
  10.936 +
  10.937 +	bp = &((dsl_dataset_phys_t *)DN_BONUS(mdn))->ds_bp;
  10.938 +	osp = (objset_phys_t *)stack;
  10.939 +	stack += sizeof (objset_phys_t);
  10.940 +	if ((errnum = zio_read(ffi, bp, osp, stack)))
  10.941 +		return (errnum);
  10.942 +
  10.943 +	grub_memmove((char *)mdn, (char *)&osp->os_meta_dnode, DNODE_SIZE);
  10.944 +
  10.945 +	return (0);
  10.946 +}
  10.947 +
  10.948 +/*
  10.949 + * For a given XDR packed nvlist, verify the first 4 bytes and move on.
  10.950 + *
  10.951 + * An XDR packed nvlist is encoded as (comments from nvs_xdr_create) :
  10.952 + *
  10.953 + *      encoding method/host endian     (4 bytes)
  10.954 + *      nvl_version                     (4 bytes)
  10.955 + *      nvl_nvflag                      (4 bytes)
  10.956 + *	encoded nvpairs:
  10.957 + *		encoded size of the nvpair      (4 bytes)
  10.958 + *		decoded size of the nvpair      (4 bytes)
  10.959 + *		name string size                (4 bytes)
  10.960 + *		name string data                (sizeof(NV_ALIGN4(string))
  10.961 + *		data type                       (4 bytes)
  10.962 + *		# of elements in the nvpair     (4 bytes)
  10.963 + *		data
  10.964 + *      2 zero's for the last nvpair
  10.965 + *		(end of the entire list)	(8 bytes)
  10.966 + *
  10.967 + * Return:
  10.968 + *	0 - success
  10.969 + *	1 - failure
  10.970 + */
  10.971 +static int
  10.972 +nvlist_unpack(char *nvlist, char **out)
  10.973 +{
  10.974 +	/* Verify if the 1st and 2nd byte in the nvlist are valid. */
  10.975 +	if (nvlist[0] != NV_ENCODE_XDR || nvlist[1] != HOST_ENDIAN)
  10.976 +		return (1);
  10.977 +
  10.978 +	nvlist += 4;
  10.979 +	*out = nvlist;
  10.980 +	return (0);
  10.981 +}
  10.982 +
  10.983 +static char *
  10.984 +nvlist_array(char *nvlist, int index)
  10.985 +{
  10.986 +	int i, encode_size;
  10.987 +
  10.988 +	for (i = 0; i < index; i++) {
  10.989 +		/* skip the header, nvl_version, and nvl_nvflag */
  10.990 +		nvlist = nvlist + 4 * 2;
  10.991 +
  10.992 +		while ((encode_size = BSWAP_32(*(uint32_t *)nvlist)))
  10.993 +			nvlist += encode_size; /* goto the next nvpair */
  10.994 +
  10.995 +		nvlist = nvlist + 4 * 2; /* skip the ending 2 zeros - 8 bytes */
  10.996 +	}
  10.997 +
  10.998 +	return (nvlist);
  10.999 +}
 10.1000 +
 10.1001 +static int
 10.1002 +nvlist_lookup_value(char *nvlist, char *name, void *val, int valtype,
 10.1003 +    int *nelmp)
 10.1004 +{
 10.1005 +	int name_len, type, slen, encode_size;
 10.1006 +	char *nvpair, *nvp_name, *strval = val;
 10.1007 +	uint64_t *intval = val;
 10.1008 +
 10.1009 +	/* skip the header, nvl_version, and nvl_nvflag */
 10.1010 +	nvlist = nvlist + 4 * 2;
 10.1011 +
 10.1012 +	/*
 10.1013 +	 * Loop thru the nvpair list
 10.1014 +	 * The XDR representation of an integer is in big-endian byte order.
 10.1015 +	 */
 10.1016 +	while ((encode_size = BSWAP_32(*(uint32_t *)nvlist)))  {
 10.1017 +
 10.1018 +		nvpair = nvlist + 4 * 2; /* skip the encode/decode size */
 10.1019 +
 10.1020 +		name_len = BSWAP_32(*(uint32_t *)nvpair);
 10.1021 +		nvpair += 4;
 10.1022 +
 10.1023 +		nvp_name = nvpair;
 10.1024 +		nvpair = nvpair + ((name_len + 3) & ~3); /* align */
 10.1025 +
 10.1026 +		type = BSWAP_32(*(uint32_t *)nvpair);
 10.1027 +		nvpair += 4;
 10.1028 +
 10.1029 +		if (((strncmp(nvp_name, name, name_len) == 0) &&
 10.1030 +		    type == valtype)) {
 10.1031 +			int nelm;
 10.1032 +
 10.1033 +			if (((nelm = BSWAP_32(*(uint32_t *)nvpair)) < 1))
 10.1034 +				return (1);
 10.1035 +			nvpair += 4;
 10.1036 +
 10.1037 +			switch (valtype) {
 10.1038 +			case DATA_TYPE_STRING:
 10.1039 +				slen = BSWAP_32(*(uint32_t *)nvpair);
 10.1040 +				nvpair += 4;
 10.1041 +				grub_memmove(strval, nvpair, slen);
 10.1042 +				strval[slen] = '\0';
 10.1043 +				return (0);
 10.1044 +
 10.1045 +			case DATA_TYPE_UINT64:
 10.1046 +				*intval = BSWAP_64(*(uint64_t *)nvpair);
 10.1047 +				return (0);
 10.1048 +
 10.1049 +			case DATA_TYPE_NVLIST:
 10.1050 +				*(void **)val = (void *)nvpair;
 10.1051 +				return (0);
 10.1052 +
 10.1053 +			case DATA_TYPE_NVLIST_ARRAY:
 10.1054 +				*(void **)val = (void *)nvpair;
 10.1055 +				if (nelmp)
 10.1056 +					*nelmp = nelm;
 10.1057 +				return (0);
 10.1058 +			}
 10.1059 +		}
 10.1060 +
 10.1061 +		nvlist += encode_size; /* goto the next nvpair */
 10.1062 +	}
 10.1063 +
 10.1064 +	return (1);
 10.1065 +}
 10.1066 +
 10.1067 +/*
 10.1068 + * Check if this vdev is online and is in a good state.
 10.1069 + */
 10.1070 +static int
 10.1071 +vdev_validate(char *nv)
 10.1072 +{
 10.1073 +	uint64_t ival;
 10.1074 +
 10.1075 +	if (nvlist_lookup_value(nv, ZPOOL_CONFIG_OFFLINE, &ival,
 10.1076 +	    DATA_TYPE_UINT64, NULL) == 0 ||
 10.1077 +	    nvlist_lookup_value(nv, ZPOOL_CONFIG_FAULTED, &ival,
 10.1078 +	    DATA_TYPE_UINT64, NULL) == 0 ||
 10.1079 +	    nvlist_lookup_value(nv, ZPOOL_CONFIG_DEGRADED, &ival,
 10.1080 +	    DATA_TYPE_UINT64, NULL) == 0 ||
 10.1081 +	    nvlist_lookup_value(nv, ZPOOL_CONFIG_REMOVED, &ival,
 10.1082 +	    DATA_TYPE_UINT64, NULL) == 0)
 10.1083 +		return (ERR_DEV_VALUES);
 10.1084 +
 10.1085 +	return (0);
 10.1086 +}
 10.1087 +
 10.1088 +/*
 10.1089 + * Get a list of valid vdev pathname from the boot device.
 10.1090 + * The caller should already allocate MAXNAMELEN memory for bootpath.
 10.1091 + */
 10.1092 +static int
 10.1093 +vdev_get_bootpath(char *nv, char *bootpath)
 10.1094 +{
 10.1095 +	char type[16];
 10.1096 +
 10.1097 +	bootpath[0] = '\0';
 10.1098 +	if (nvlist_lookup_value(nv, ZPOOL_CONFIG_TYPE, &type, DATA_TYPE_STRING,
 10.1099 +	    NULL))
 10.1100 +		return (ERR_FSYS_CORRUPT);
 10.1101 +
 10.1102 +	if (strcmp(type, VDEV_TYPE_DISK) == 0) {
 10.1103 +		if (vdev_validate(nv) != 0 ||
 10.1104 +		    nvlist_lookup_value(nv, ZPOOL_CONFIG_PHYS_PATH, bootpath,
 10.1105 +		    DATA_TYPE_STRING, NULL) != 0)
 10.1106 +			return (ERR_NO_BOOTPATH);
 10.1107 +
 10.1108 +	} else if (strcmp(type, VDEV_TYPE_MIRROR) == 0) {
 10.1109 +		int nelm, i;
 10.1110 +		char *child;
 10.1111 +
 10.1112 +		if (nvlist_lookup_value(nv, ZPOOL_CONFIG_CHILDREN, &child,
 10.1113 +		    DATA_TYPE_NVLIST_ARRAY, &nelm))
 10.1114 +			return (ERR_FSYS_CORRUPT);
 10.1115 +
 10.1116 +		for (i = 0; i < nelm; i++) {
 10.1117 +			char tmp_path[MAXNAMELEN];
 10.1118 +			char *child_i;
 10.1119 +
 10.1120 +			child_i = nvlist_array(child, i);
 10.1121 +			if (vdev_validate(child_i) != 0)
 10.1122 +				continue;
 10.1123 +
 10.1124 +			if (nvlist_lookup_value(child_i, ZPOOL_CONFIG_PHYS_PATH,
 10.1125 +			    tmp_path, DATA_TYPE_STRING, NULL) != 0)
 10.1126 +				return (ERR_NO_BOOTPATH);
 10.1127 +
 10.1128 +			if ((strlen(bootpath) + strlen(tmp_path)) > MAXNAMELEN)
 10.1129 +				return (ERR_WONT_FIT);
 10.1130 +
 10.1131 +			if (strlen(bootpath) == 0)
 10.1132 +				sprintf(bootpath, "%s", tmp_path);
 10.1133 +			else
 10.1134 +				sprintf(bootpath, "%s %s", bootpath, tmp_path);
 10.1135 +		}
 10.1136 +	}
 10.1137 +
 10.1138 +	return (strlen(bootpath) > 0 ? 0 : ERR_NO_BOOTPATH);
 10.1139 +}
 10.1140 +
 10.1141 +/*
 10.1142 + * Check the disk label information and retrieve needed vdev name-value pairs.
 10.1143 + *
 10.1144 + * Return:
 10.1145 + *	0 - success
 10.1146 + *	ERR_* - failure
 10.1147 + */
 10.1148 +static int
 10.1149 +check_pool_label(fsi_file_t *ffi, int label, char *stack)
 10.1150 +{
 10.1151 +	vdev_phys_t *vdev;
 10.1152 +	uint64_t sector, pool_state, txg = 0;
 10.1153 +	char *nvlist, *nv;
 10.1154 +	zfs_bootarea_t *zfs_ba = (zfs_bootarea_t *)ffi->ff_fsi->f_data;
 10.1155 +
 10.1156 +	sector = (label * sizeof (vdev_label_t) + VDEV_SKIP_SIZE +
 10.1157 +	    VDEV_BOOT_HEADER_SIZE) >> SPA_MINBLOCKSHIFT;
 10.1158 +
 10.1159 +	/* Read in the vdev name-value pair list (112K). */
 10.1160 +	if (devread(ffi, sector, 0, VDEV_PHYS_SIZE, stack) == 0)
 10.1161 +		return (ERR_READ);
 10.1162 +
 10.1163 +	vdev = (vdev_phys_t *)stack;
 10.1164 +
 10.1165 +	if (nvlist_unpack(vdev->vp_nvlist, &nvlist))
 10.1166 +		return (ERR_FSYS_CORRUPT);
 10.1167 +
 10.1168 +	if (nvlist_lookup_value(nvlist, ZPOOL_CONFIG_POOL_STATE, &pool_state,
 10.1169 +	    DATA_TYPE_UINT64, NULL))
 10.1170 +		return (ERR_FSYS_CORRUPT);
 10.1171 +
 10.1172 +	if (pool_state == POOL_STATE_DESTROYED)
 10.1173 +		return (ERR_FILESYSTEM_NOT_FOUND);
 10.1174 +
 10.1175 +	if (nvlist_lookup_value(nvlist, ZPOOL_CONFIG_POOL_NAME,
 10.1176 +	    current_rootpool, DATA_TYPE_STRING, NULL))
 10.1177 +		return (ERR_FSYS_CORRUPT);
 10.1178 +
 10.1179 +	if (nvlist_lookup_value(nvlist, ZPOOL_CONFIG_POOL_TXG, &txg,
 10.1180 +	    DATA_TYPE_UINT64, NULL))
 10.1181 +		return (ERR_FSYS_CORRUPT);
 10.1182 +
 10.1183 +	/* not an active device */
 10.1184 +	if (txg == 0)
 10.1185 +		return (ERR_NO_BOOTPATH);
 10.1186 +
 10.1187 +	if (nvlist_lookup_value(nvlist, ZPOOL_CONFIG_VDEV_TREE, &nv,
 10.1188 +	    DATA_TYPE_NVLIST, NULL))
 10.1189 +		return (ERR_FSYS_CORRUPT);
 10.1190 +
 10.1191 +	if (vdev_get_bootpath(nv, current_bootpath))
 10.1192 +		return (ERR_NO_BOOTPATH);
 10.1193 +
 10.1194 +	return (0);
 10.1195 +}
 10.1196 +
 10.1197 +/*
 10.1198 + * zfs_mount() locates a valid uberblock of the root pool and read in its MOS
 10.1199 + * to the memory address MOS.
 10.1200 + *
 10.1201 + * Return:
 10.1202 + *	1 - success
 10.1203 + *	0 - failure
 10.1204 + */
 10.1205 +int
 10.1206 +zfs_mount(fsi_file_t *ffi, const char *options)
 10.1207 +{
 10.1208 +	char *stack;
 10.1209 +	int label = 0;
 10.1210 +	uberblock_phys_t *ub_array, *ubbest = NULL;
 10.1211 +	objset_phys_t *osp;
 10.1212 +	zfs_bootarea_t *zfs_ba;
 10.1213 +
 10.1214 +	/* if zfs is already mounted, don't do it again */
 10.1215 +	if (is_zfs_mount == 1)
 10.1216 +		return (1);
 10.1217 +
 10.1218 +	/* get much bigger data block for zfs */
 10.1219 +	if (((zfs_ba = malloc(sizeof (zfs_bootarea_t))) == NULL)) {
 10.1220 +		return (1);
 10.1221 +	}
 10.1222 +	bzero(zfs_ba, sizeof (zfs_bootarea_t));
 10.1223 +
 10.1224 +	/* replace small data area in fsi with big one */
 10.1225 +	free(ffi->ff_fsi->f_data);
 10.1226 +	ffi->ff_fsi->f_data = (void *)zfs_ba;
 10.1227 +
 10.1228 +	/* If an boot filesystem is passed in, set it to current_bootfs */
 10.1229 +	if (options != NULL) {
 10.1230 +		if (strlen(options) < MAXNAMELEN) {
 10.1231 +			strcpy(current_bootfs, options);
 10.1232 +		}
 10.1233 +	}
 10.1234 +
 10.1235 +	stackbase = ZFS_SCRATCH;
 10.1236 +	stack = stackbase;
 10.1237 +	ub_array = (uberblock_phys_t *)stack;
 10.1238 +	stack += VDEV_UBERBLOCK_RING;
 10.1239 +
 10.1240 +	osp = (objset_phys_t *)stack;
 10.1241 +	stack += sizeof (objset_phys_t);
 10.1242 +
 10.1243 +	/* XXX add back labels support? */
 10.1244 +	for (label = 0; ubbest == NULL && label < (VDEV_LABELS/2); label++) {
 10.1245 +		uint64_t sector = (label * sizeof (vdev_label_t) +
 10.1246 +		    VDEV_SKIP_SIZE + VDEV_BOOT_HEADER_SIZE +
 10.1247 +		    VDEV_PHYS_SIZE) >> SPA_MINBLOCKSHIFT;
 10.1248 +
 10.1249 +
 10.1250 +		/* Read in the uberblock ring (128K). */
 10.1251 +		if (devread(ffi, sector, 0, VDEV_UBERBLOCK_RING,
 10.1252 +		    (char *)ub_array) == 0)
 10.1253 +			continue;
 10.1254 +
 10.1255 +		if ((ubbest = find_bestub(ffi, ub_array, label)) != NULL &&
 10.1256 +		    zio_read(ffi, &ubbest->ubp_uberblock.ub_rootbp, osp, stack)
 10.1257 +		    == 0) {
 10.1258 +
 10.1259 +			VERIFY_OS_TYPE(osp, DMU_OST_META);
 10.1260 +
 10.1261 +			/* Got the MOS. Save it at the memory addr MOS. */
 10.1262 +			grub_memmove(MOS, &osp->os_meta_dnode, DNODE_SIZE);
 10.1263 +
 10.1264 +			if (check_pool_label(ffi, label, stack))
 10.1265 +				return (0);
 10.1266 +
 10.1267 +			/*
 10.1268 +			 * Copy fsi->f_data to ffi->ff_data since
 10.1269 +			 * fsig_mount copies from ff_data to f_data
 10.1270 +			 * overwriting fsi->f_data.
 10.1271 +			 */
 10.1272 +			bcopy(zfs_ba, fsig_file_buf(ffi), FSYS_BUFLEN);
 10.1273 +
 10.1274 +			is_zfs_mount = 1;
 10.1275 +			return (1);
 10.1276 +		}
 10.1277 +	}
 10.1278 +
 10.1279 +	return (0);
 10.1280 +}
 10.1281 +
 10.1282 +/*
 10.1283 + * zfs_open() locates a file in the rootpool by following the
 10.1284 + * MOS and places the dnode of the file in the memory address DNODE.
 10.1285 + *
 10.1286 + * Return:
 10.1287 + *	1 - success
 10.1288 + *	0 - failure
 10.1289 + */
 10.1290 +int
 10.1291 +zfs_open(fsi_file_t *ffi, char *filename)
 10.1292 +{
 10.1293 +	char *stack;
 10.1294 +	dnode_phys_t *mdn;
 10.1295 +	char *bootstring;
 10.1296 +	zfs_bootarea_t *zfs_ba = (zfs_bootarea_t *)ffi->ff_fsi->f_data;
 10.1297 +
 10.1298 +	file_buf = NULL;
 10.1299 +	stackbase = ZFS_SCRATCH;
 10.1300 +	stack = stackbase;
 10.1301 +
 10.1302 +	mdn = (dnode_phys_t *)stack;
 10.1303 +	stack += sizeof (dnode_phys_t);
 10.1304 +
 10.1305 +	dnode_mdn = NULL;
 10.1306 +	dnode_buf = (dnode_phys_t *)stack;
 10.1307 +	stack += 1<<DNODE_BLOCK_SHIFT;
 10.1308 +
 10.1309 +	/*
 10.1310 +	 * menu.lst is placed at the root pool filesystem level,
 10.1311 +	 * do not goto 'current_bootfs'.
 10.1312 +	 */
 10.1313 +	if (is_top_dataset_file(filename)) {
 10.1314 +		if ((errnum = get_objset_mdn(ffi, MOS, NULL, NULL, mdn, stack)))
 10.1315 +			return (0);
 10.1316 +
 10.1317 +		current_bootfs_obj = 0;
 10.1318 +	} else {
 10.1319 +		if (current_bootfs[0] == '\0') {
 10.1320 +			/* Get the default root filesystem object number */
 10.1321 +			if ((errnum = get_default_bootfsobj(ffi, MOS,
 10.1322 +			    &current_bootfs_obj, stack)))
 10.1323 +				return (0);
 10.1324 +			if ((errnum = get_objset_mdn(ffi, MOS, NULL,
 10.1325 +			    &current_bootfs_obj, mdn, stack)))
 10.1326 +				return (0);
 10.1327 +		} else {
 10.1328 +			if ((errnum = get_objset_mdn(ffi, MOS,
 10.1329 +			    current_bootfs, &current_bootfs_obj, mdn, stack)))
 10.1330 +				return (0);
 10.1331 +		}
 10.1332 +
 10.1333 +		/*
 10.1334 +		 * Put zfs rootpool and boot obj number into bootstring.
 10.1335 +		 */
 10.1336 +		if (is_zfs_open == 0) {
 10.1337 +			char temp[25];		/* needs to hold long long */
 10.1338 +			int alloc_size;
 10.1339 +			char zfs_bootstr[] = "zfs-bootfs=";
 10.1340 +			char zfs_bootpath[] = ",bootpath='";
 10.1341 +
 10.1342 +			sprintf(temp, "%llu", (unsigned long long)
 10.1343 +			    current_bootfs_obj);
 10.1344 +			alloc_size = strlen(zfs_bootstr) +
 10.1345 +			    strlen(current_rootpool) +
 10.1346 +			    strlen(temp) + strlen(zfs_bootpath) +
 10.1347 +			    strlen(current_bootpath) + 3;
 10.1348 +			bootstring = fsi_bootstring_alloc(ffi->ff_fsi,
 10.1349 +			    alloc_size);
 10.1350 +			if (bootstring != NULL) {
 10.1351 +				strcpy(bootstring, zfs_bootstr);
 10.1352 +				strcat(bootstring, current_rootpool);
 10.1353 +				strcat(bootstring, "/");
 10.1354 +				strcat(bootstring, temp);
 10.1355 +				strcat(bootstring, zfs_bootpath);
 10.1356 +				strcat(bootstring, current_bootpath);
 10.1357 +				strcat(bootstring, "'");
 10.1358 +				is_zfs_open = 1;
 10.1359 +			}
 10.1360 +		}
 10.1361 +	}
 10.1362 +
 10.1363 +	if (dnode_get_path(ffi, mdn, filename, DNODE, stack)) {
 10.1364 +		errnum = ERR_FILE_NOT_FOUND;
 10.1365 +		return (0);
 10.1366 +	}
 10.1367 +
 10.1368 +	/* get the file size and set the file position to 0 */
 10.1369 +	filemax = ((znode_phys_t *)DN_BONUS(DNODE))->zp_size;
 10.1370 +	filepos = 0;
 10.1371 +
 10.1372 +	dnode_buf = NULL;
 10.1373 +	return (1);
 10.1374 +}
 10.1375 +
 10.1376 +/*
 10.1377 + * zfs_read reads in the data blocks pointed by the DNODE.
 10.1378 + *
 10.1379 + * Return:
 10.1380 + *	len - the length successfully read in to the buffer
 10.1381 + *	0   - failure
 10.1382 + */
 10.1383 +int
 10.1384 +zfs_read(fsi_file_t *ffi, char *buf, int len)
 10.1385 +{
 10.1386 +	char *stack;
 10.1387 +	int blksz, length, movesize;
 10.1388 +	zfs_bootarea_t *zfs_ba = (zfs_bootarea_t *)ffi->ff_fsi->f_data;
 10.1389 +
 10.1390 +	if (file_buf == NULL) {
 10.1391 +		file_buf = stackbase;
 10.1392 +		stackbase += SPA_MAXBLOCKSIZE;
 10.1393 +		file_start = file_end = 0;
 10.1394 +	}
 10.1395 +	stack = stackbase;
 10.1396 +
 10.1397 +	/*
 10.1398 +	 * If offset is in memory, move it into the buffer provided and return.
 10.1399 +	 */
 10.1400 +	if (filepos >= file_start && filepos+len <= file_end) {
 10.1401 +		grub_memmove(buf, file_buf + filepos - file_start, len);
 10.1402 +		filepos += len;
 10.1403 +		return (len);
 10.1404 +	}
 10.1405 +
 10.1406 +	blksz = DNODE->dn_datablkszsec << SPA_MINBLOCKSHIFT;
 10.1407 +
 10.1408 +	/*
 10.1409 +	 * Entire Dnode is too big to fit into the space available.  We
 10.1410 +	 * will need to read it in chunks.  This could be optimized to
 10.1411 +	 * read in as large a chunk as there is space available, but for
 10.1412 +	 * now, this only reads in one data block at a time.
 10.1413 +	 */
 10.1414 +	length = len;
 10.1415 +	while (length) {
 10.1416 +		/*
 10.1417 +		 * Find requested blkid and the offset within that block.
 10.1418 +		 */
 10.1419 +		uint64_t blkid = filepos / blksz;
 10.1420 +
 10.1421 +		if ((errnum = dmu_read(ffi, DNODE, blkid, file_buf, stack)))
 10.1422 +			return (0);
 10.1423 +
 10.1424 +		file_start = blkid * blksz;
 10.1425 +		file_end = file_start + blksz;
 10.1426 +
 10.1427 +		movesize = MIN(length, file_end - filepos);
 10.1428 +
 10.1429 +		grub_memmove(buf, file_buf + filepos - file_start,
 10.1430 +		    movesize);
 10.1431 +		buf += movesize;
 10.1432 +		length -= movesize;
 10.1433 +		filepos += movesize;
 10.1434 +	}
 10.1435 +
 10.1436 +	return (len);
 10.1437 +}
 10.1438 +
 10.1439 +/*
 10.1440 + * No-Op
 10.1441 + */
 10.1442 +int
 10.1443 +zfs_embed(int *start_sector, int needed_sectors)
 10.1444 +{
 10.1445 +	return (1);
 10.1446 +}
 10.1447 +
 10.1448 +fsi_plugin_ops_t *
 10.1449 +fsi_init_plugin(int version, fsi_plugin_t *fp, const char **name)
 10.1450 +{
 10.1451 +	static fsig_plugin_ops_t ops = {
 10.1452 +		FSIMAGE_PLUGIN_VERSION,
 10.1453 +		.fpo_mount = zfs_mount,
 10.1454 +		.fpo_dir = zfs_open,
 10.1455 +		.fpo_read = zfs_read
 10.1456 +	};
 10.1457 +
 10.1458 +	*name = "zfs";
 10.1459 +	return (fsig_init(fp, &ops));
 10.1460 +}
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/tools/libfsimage/zfs/fsys_zfs.h	Thu May 01 16:38:56 2008 +0100
    11.3 @@ -0,0 +1,203 @@
    11.4 +/*
    11.5 + *  GRUB  --  GRand Unified Bootloader
    11.6 + *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
    11.7 + *
    11.8 + *  This program is free software; you can redistribute it and/or modify
    11.9 + *  it under the terms of the GNU General Public License as published by
   11.10 + *  the Free Software Foundation; either version 2 of the License, or
   11.11 + *  (at your option) any later version.
   11.12 + *
   11.13 + *  This program is distributed in the hope that it will be useful,
   11.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   11.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   11.16 + *  GNU General Public License for more details.
   11.17 + *
   11.18 + *  You should have received a copy of the GNU General Public License
   11.19 + *  along with this program; if not, write to the Free Software
   11.20 + *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   11.21 + */
   11.22 +/*
   11.23 + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
   11.24 + * Use is subject to license terms.
   11.25 + */
   11.26 +#ifndef _FSYS_ZFS_H
   11.27 +#define	_FSYS_ZFS_H
   11.28 +
   11.29 +#include <fsimage_grub.h>
   11.30 +#include <fsimage_priv.h>
   11.31 +
   11.32 +#include "zfs-include/zfs.h"
   11.33 +#include "zfs-include/dmu.h"
   11.34 +#include "zfs-include/spa.h"
   11.35 +#include "zfs-include/zio.h"
   11.36 +#include "zfs-include/zio_checksum.h"
   11.37 +#include "zfs-include/vdev_impl.h"
   11.38 +#include "zfs-include/zap_impl.h"
   11.39 +#include "zfs-include/zap_leaf.h"
   11.40 +#include "zfs-include/uberblock_impl.h"
   11.41 +#include "zfs-include/dnode.h"
   11.42 +#include "zfs-include/dsl_dir.h"
   11.43 +#include "zfs-include/zfs_acl.h"
   11.44 +#include "zfs-include/zfs_znode.h"
   11.45 +#include "zfs-include/dsl_dataset.h"
   11.46 +#include "zfs-include/zil.h"
   11.47 +#include "zfs-include/dmu_objset.h"
   11.48 +
   11.49 +/*
   11.50 + * Global Memory addresses to store MOS and DNODE data
   11.51 + */
   11.52 +#define	MOS		((dnode_phys_t *)(((zfs_bootarea_t *) \
   11.53 +			    (ffi->ff_fsi->f_data))->zfs_data))
   11.54 +#define	DNODE		(MOS+1) /* move sizeof(dnode_phys_t) bytes */
   11.55 +#define	ZFS_SCRATCH	((char *)(DNODE+1))
   11.56 +
   11.57 +#define	MAXNAMELEN	256
   11.58 +
   11.59 +typedef struct zfs_bootarea {
   11.60 +	char zfs_current_bootpath[MAXNAMELEN];
   11.61 +	char zfs_current_rootpool[MAXNAMELEN];
   11.62 +	char zfs_current_bootfs[MAXNAMELEN];
   11.63 +	uint64_t zfs_current_bootfs_obj;
   11.64 +	int zfs_open;
   11.65 +
   11.66 +	/* cache for a file block of the currently zfs_open()-ed file */
   11.67 +	void *zfs_file_buf;
   11.68 +	uint64_t zfs_file_start;
   11.69 +	uint64_t zfs_file_end;
   11.70 +
   11.71 +	/* cache for a dnode block */
   11.72 +	dnode_phys_t *zfs_dnode_buf;
   11.73 +	dnode_phys_t *zfs_dnode_mdn;
   11.74 +	uint64_t zfs_dnode_start;
   11.75 +	uint64_t zfs_dnode_end;
   11.76 +
   11.77 +	char *zfs_stackbase;
   11.78 +	char zfs_data[0x400000];
   11.79 +} zfs_bootarea_t;
   11.80 +
   11.81 +/*
   11.82 + * Verify dnode type.
   11.83 + * Can only be used in functions returning non-0 for failure.
   11.84 + */
   11.85 +#define	VERIFY_DN_TYPE(dnp, type) \
   11.86 +	if (type && (dnp)->dn_type != type) { \
   11.87 +		return (ERR_FSYS_CORRUPT); \
   11.88 +	}
   11.89 +
   11.90 +/*
   11.91 + * Verify object set type.
   11.92 + * Can only be used in functions returning 0 for failure.
   11.93 + */
   11.94 +#define	VERIFY_OS_TYPE(osp, type) \
   11.95 +	if (type && (osp)->os_type != type) { \
   11.96 +		errnum = ERR_FSYS_CORRUPT; \
   11.97 +		return (0); \
   11.98 +	}
   11.99 +
  11.100 +#define	ZPOOL_PROP_BOOTFS		"bootfs"
  11.101 +
  11.102 +/* General macros */
  11.103 +#define	BSWAP_8(x)	((x) & 0xff)
  11.104 +#define	BSWAP_16(x)	((BSWAP_8(x) << 8) | BSWAP_8((x) >> 8))
  11.105 +#define	BSWAP_32(x)	((BSWAP_16(x) << 16) | BSWAP_16((x) >> 16))
  11.106 +#define	BSWAP_64(x)	((BSWAP_32(x) << 32) | BSWAP_32((x) >> 32))
  11.107 +#define	P2ROUNDUP(x, align)	(-(-(x) & -(align)))
  11.108 +
  11.109 +/*
  11.110 + * XXX Match these macro up with real zfs once we have nvlist support so that we
  11.111 + * can support large sector disks.
  11.112 + */
  11.113 +#define	UBERBLOCK_SIZE		(1ULL << UBERBLOCK_SHIFT)
  11.114 +#undef	offsetof
  11.115 +#define	offsetof(t, m)   (size_t)(&(((t *)0)->m))
  11.116 +#define	VDEV_UBERBLOCK_SHIFT	UBERBLOCK_SHIFT
  11.117 +#define	VDEV_UBERBLOCK_OFFSET(n) \
  11.118 +offsetof(vdev_label_t, vl_uberblock[(n) << VDEV_UBERBLOCK_SHIFT])
  11.119 +
  11.120 +typedef struct uberblock uberblock_t;
  11.121 +
  11.122 +/* XXX Uberblock_phys_t is no longer in the kernel zfs */
  11.123 +typedef struct uberblock_phys {
  11.124 +	uberblock_t	ubp_uberblock;
  11.125 +	char		ubp_pad[UBERBLOCK_SIZE - sizeof (uberblock_t) -
  11.126 +				sizeof (zio_block_tail_t)];
  11.127 +	zio_block_tail_t ubp_zbt;
  11.128 +} uberblock_phys_t;
  11.129 +
  11.130 +/*
  11.131 + * Macros to get fields in a bp or DVA.
  11.132 + */
  11.133 +#define	P2PHASE(x, align)		((x) & ((align) - 1))
  11.134 +#define	DVA_OFFSET_TO_PHYS_SECTOR(offset) \
  11.135 +	((offset + VDEV_LABEL_START_SIZE) >> SPA_MINBLOCKSHIFT)
  11.136 +
  11.137 +/*
  11.138 + * For nvlist manipulation. (from nvpair.h)
  11.139 + */
  11.140 +#define	NV_ENCODE_NATIVE	0
  11.141 +#define	NV_ENCODE_XDR		1
  11.142 +#define	HOST_ENDIAN		1	/* for x86 machine */
  11.143 +#define	DATA_TYPE_UINT64	8
  11.144 +#define	DATA_TYPE_STRING	9
  11.145 +#define	DATA_TYPE_NVLIST	19
  11.146 +#define	DATA_TYPE_NVLIST_ARRAY	20
  11.147 +
  11.148 +/*
  11.149 + * Decompression Entry - lzjb
  11.150 + */
  11.151 +#ifndef	NBBY
  11.152 +#define	NBBY	8
  11.153 +#endif
  11.154 +
  11.155 +typedef int zfs_decomp_func_t(void *s_start, void *d_start, size_t s_len,
  11.156 +			size_t d_len);
  11.157 +typedef struct decomp_entry {
  11.158 +	char *name;
  11.159 +	zfs_decomp_func_t *decomp_func;
  11.160 +} decomp_entry_t;
  11.161 +
  11.162 +/*
  11.163 + * FAT ZAP data structures
  11.164 + */
  11.165 +#define	ZFS_CRC64_POLY 0xC96C5795D7870F42ULL /* ECMA-182, reflected form */
  11.166 +#define	ZAP_HASH_IDX(hash, n)	(((n) == 0) ? 0 : ((hash) >> (64 - (n))))
  11.167 +#define	CHAIN_END	0xffff	/* end of the chunk chain */
  11.168 +
  11.169 +/*
  11.170 + * The amount of space within the chunk available for the array is:
  11.171 + * chunk size - space for type (1) - space for next pointer (2)
  11.172 + */
  11.173 +#define	ZAP_LEAF_ARRAY_BYTES (ZAP_LEAF_CHUNKSIZE - 3)
  11.174 +
  11.175 +#define	ZAP_LEAF_HASH_SHIFT(bs)	(bs - 5)
  11.176 +#define	ZAP_LEAF_HASH_NUMENTRIES(bs) (1 << ZAP_LEAF_HASH_SHIFT(bs))
  11.177 +#define	LEAF_HASH(bs, h) \
  11.178 +	((ZAP_LEAF_HASH_NUMENTRIES(bs)-1) & \
  11.179 +	((h) >> (64 - ZAP_LEAF_HASH_SHIFT(bs)-l->l_hdr.lh_prefix_len)))
  11.180 +
  11.181 +/*
  11.182 + * The amount of space available for chunks is:
  11.183 + * block size shift - hash entry size (2) * number of hash
  11.184 + * entries - header space (2*chunksize)
  11.185 + */
  11.186 +#define	ZAP_LEAF_NUMCHUNKS(bs) \
  11.187 +	(((1<<bs) - 2*ZAP_LEAF_HASH_NUMENTRIES(bs)) / \
  11.188 +	ZAP_LEAF_CHUNKSIZE - 2)
  11.189 +
  11.190 +/*
  11.191 + * The chunks start immediately after the hash table.  The end of the
  11.192 + * hash table is at l_hash + HASH_NUMENTRIES, which we simply cast to a
  11.193 + * chunk_t.
  11.194 + */
  11.195 +#define	ZAP_LEAF_CHUNK(l, bs, idx) \
  11.196 +	((zap_leaf_chunk_t *)(l->l_hash + ZAP_LEAF_HASH_NUMENTRIES(bs)))[idx]
  11.197 +#define	ZAP_LEAF_ENTRY(l, bs, idx) (&ZAP_LEAF_CHUNK(l, bs, idx).l_entry)
  11.198 +
  11.199 +extern void fletcher_2_native(const void *, uint64_t, zio_cksum_t *);
  11.200 +extern void fletcher_2_byteswap(const void *, uint64_t, zio_cksum_t *);
  11.201 +extern void fletcher_4_native(const void *, uint64_t, zio_cksum_t *);
  11.202 +extern void fletcher_4_byteswap(const void *, uint64_t, zio_cksum_t *);
  11.203 +extern void zio_checksum_SHA256(const void *, uint64_t, zio_cksum_t *);
  11.204 +extern int lzjb_decompress(void *, void *, size_t, size_t);
  11.205 +
  11.206 +#endif /* !_FSYS_ZFS_H */
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/tools/libfsimage/zfs/mb_info.h	Thu May 01 16:38:56 2008 +0100
    12.3 @@ -0,0 +1,217 @@
    12.4 +/*
    12.5 + *  GRUB  --  GRand Unified Bootloader
    12.6 + *  Copyright (C) 2000,2003  Free Software Foundation, Inc.
    12.7 + *
    12.8 + *  This program is free software; you can redistribute it and/or modify
    12.9 + *  it under the terms of the GNU General Public License as published by
   12.10 + *  the Free Software Foundation; either version 2 of the License, or
   12.11 + *  (at your option) any later version.
   12.12 + *
   12.13 + *  This program is distributed in the hope that it will be useful,
   12.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   12.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12.16 + *  GNU General Public License for more details.
   12.17 + *
   12.18 + *  You should have received a copy of the GNU General Public License
   12.19 + *  along with this program; if not, write to the Free Software
   12.20 + *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   12.21 + */
   12.22 +
   12.23 +/*
   12.24 + *  The structure type "mod_list" is used by the "multiboot_info" structure.
   12.25 + */
   12.26 +
   12.27 +struct mod_list
   12.28 +{
   12.29 +  /* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */
   12.30 +  unsigned long mod_start;
   12.31 +  unsigned long mod_end;
   12.32 +  
   12.33 +  /* Module command line */
   12.34 +  unsigned long cmdline;
   12.35 +  
   12.36 +  /* padding to take it to 16 bytes (must be zero) */
   12.37 +  unsigned long pad;
   12.38 +};
   12.39 +
   12.40 +
   12.41 +/*
   12.42 + *  INT-15, AX=E820 style "AddressRangeDescriptor"
   12.43 + *  ...with a "size" parameter on the front which is the structure size - 4,
   12.44 + *  pointing to the next one, up until the full buffer length of the memory
   12.45 + *  map has been reached.
   12.46 + */
   12.47 +
   12.48 +struct AddrRangeDesc
   12.49 +{
   12.50 +  unsigned long size;
   12.51 +  unsigned long long BaseAddr;
   12.52 +  unsigned long long Length;
   12.53 +  unsigned long Type;
   12.54 +  
   12.55 +  /* unspecified optional padding... */
   12.56 +} __attribute__ ((packed));
   12.57 +
   12.58 +/* usable memory "Type", all others are reserved.  */
   12.59 +#define MB_ARD_MEMORY		1
   12.60 +
   12.61 +
   12.62 +/* Drive Info structure.  */
   12.63 +struct drive_info
   12.64 +{
   12.65 +  /* The size of this structure.  */
   12.66 +  unsigned long size;
   12.67 +
   12.68 +  /* The BIOS drive number.  */
   12.69 +  unsigned char drive_number;
   12.70 +
   12.71 +  /* The access mode (see below).  */
   12.72 +  unsigned char drive_mode;
   12.73 +
   12.74 +  /* The BIOS geometry.  */
   12.75 +  unsigned short drive_cylinders;
   12.76 +  unsigned char drive_heads;
   12.77 +  unsigned char drive_sectors;
   12.78 +
   12.79 +  /* The array of I/O ports used for the drive.  */
   12.80 +  unsigned short drive_ports[0];
   12.81 +};
   12.82 +
   12.83 +/* Drive Mode.  */
   12.84 +#define MB_DI_CHS_MODE		0
   12.85 +#define MB_DI_LBA_MODE		1
   12.86 +
   12.87 +
   12.88 +/* APM BIOS info.  */
   12.89 +struct apm_info
   12.90 +{
   12.91 +  unsigned short version;
   12.92 +  unsigned short cseg;
   12.93 +  unsigned long offset;
   12.94 +  unsigned short cseg_16;
   12.95 +  unsigned short dseg_16;
   12.96 +  unsigned short cseg_len;
   12.97 +  unsigned short cseg_16_len;
   12.98 +  unsigned short dseg_16_len;
   12.99 +};
  12.100 +
  12.101 +
  12.102 +/*
  12.103 + *  MultiBoot Info description
  12.104 + *
  12.105 + *  This is the struct passed to the boot image.  This is done by placing
  12.106 + *  its address in the EAX register.
  12.107 + */
  12.108 +
  12.109 +struct multiboot_info
  12.110 +{
  12.111 +  /* MultiBoot info version number */
  12.112 +  unsigned long flags;
  12.113 +  
  12.114 +  /* Available memory from BIOS */
  12.115 +  unsigned long mem_lower;
  12.116 +  unsigned long mem_upper;
  12.117 +  
  12.118 +  /* "root" partition */
  12.119 +  unsigned long boot_device;
  12.120 +  
  12.121 +  /* Kernel command line */
  12.122 +  unsigned long cmdline;
  12.123 +  
  12.124 +  /* Boot-Module list */
  12.125 +  unsigned long mods_count;
  12.126 +  unsigned long mods_addr;
  12.127 +  
  12.128 +  union
  12.129 +  {
  12.130 +    struct
  12.131 +    {
  12.132 +      /* (a.out) Kernel symbol table info */
  12.133 +      unsigned long tabsize;
  12.134 +      unsigned long strsize;
  12.135 +      unsigned long addr;
  12.136 +      unsigned long pad;
  12.137 +    }
  12.138 +    a;
  12.139 +    
  12.140 +    struct
  12.141 +    {
  12.142 +      /* (ELF) Kernel section header table */
  12.143 +      unsigned long num;
  12.144 +      unsigned long size;
  12.145 +      unsigned long addr;
  12.146 +      unsigned long shndx;
  12.147 +    }
  12.148 +    e;
  12.149 +  }
  12.150 +  syms;
  12.151 +  
  12.152 +  /* Memory Mapping buffer */
  12.153 +  unsigned long mmap_length;
  12.154 +  unsigned long mmap_addr;
  12.155 +  
  12.156 +  /* Drive Info buffer */
  12.157 +  unsigned long drives_length;
  12.158 +  unsigned long drives_addr;
  12.159 +  
  12.160 +  /* ROM configuration table */
  12.161 +  unsigned long config_table;
  12.162 +  
  12.163 +  /* Boot Loader Name */
  12.164 +  unsigned long boot_loader_name;
  12.165 +
  12.166 +  /* APM table */
  12.167 +  unsigned long apm_table;
  12.168 +
  12.169 +  /* Video */
  12.170 +  unsigned long vbe_control_info;
  12.171 +  unsigned long vbe_mode_info;
  12.172 +  unsigned short vbe_mode;
  12.173 +  unsigned short vbe_interface_seg;
  12.174 +  unsigned short vbe_interface_off;
  12.175 +  unsigned short vbe_interface_len;
  12.176 +};
  12.177 +
  12.178 +/*
  12.179 + *  Flags to be set in the 'flags' parameter above
  12.180 + */
  12.181 +
  12.182 +/* is there basic lower/upper memory information? */
  12.183 +#define MB_INFO_MEMORY			0x00000001
  12.184 +/* is there a boot device set? */
  12.185 +#define MB_INFO_BOOTDEV			0x00000002
  12.186 +/* is the command-line defined? */
  12.187 +#define MB_INFO_CMDLINE			0x00000004
  12.188 +/* are there modules to do something with? */
  12.189 +#define MB_INFO_MODS			0x00000008
  12.190 +
  12.191 +/* These next two are mutually exclusive */
  12.192 +
  12.193 +/* is there a symbol table loaded? */
  12.194 +#define MB_INFO_AOUT_SYMS		0x00000010
  12.195 +/* is there an ELF section header table? */
  12.196 +#define MB_INFO_ELF_SHDR		0x00000020
  12.197 +
  12.198 +/* is there a full memory map? */
  12.199 +#define MB_INFO_MEM_MAP			0x00000040
  12.200 +
  12.201 +/* Is there drive info?  */
  12.202 +#define MB_INFO_DRIVE_INFO		0x00000080
  12.203 +
  12.204 +/* Is there a config table?  */
  12.205 +#define MB_INFO_CONFIG_TABLE		0x00000100
  12.206 +
  12.207 +/* Is there a boot loader name?  */
  12.208 +#define MB_INFO_BOOT_LOADER_NAME	0x00000200
  12.209 +
  12.210 +/* Is there a APM table?  */
  12.211 +#define MB_INFO_APM_TABLE		0x00000400
  12.212 +
  12.213 +/* Is there video information?  */
  12.214 +#define MB_INFO_VIDEO_INFO		0x00000800
  12.215 +
  12.216 +/*
  12.217 + *  The following value must be present in the EAX register.
  12.218 + */
  12.219 +
  12.220 +#define MULTIBOOT_VALID			0x2BADB002
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/tools/libfsimage/zfs/zfs-include/dmu.h	Thu May 01 16:38:56 2008 +0100
    13.3 @@ -0,0 +1,105 @@
    13.4 +/*
    13.5 + *  GRUB  --  GRand Unified Bootloader
    13.6 + *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
    13.7 + *
    13.8 + *  This program is free software; you can redistribute it and/or modify
    13.9 + *  it under the terms of the GNU General Public License as published by
   13.10 + *  the Free Software Foundation; either version 2 of the License, or
   13.11 + *  (at your option) any later version.
   13.12 + *
   13.13 + *  This program is distributed in the hope that it will be useful,
   13.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   13.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13.16 + *  GNU General Public License for more details.
   13.17 + *
   13.18 + *  You should have received a copy of the GNU General Public License
   13.19 + *  along with this program; if not, write to the Free Software
   13.20 + *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   13.21 + */
   13.22 +/*
   13.23 + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
   13.24 + * Use is subject to license terms.
   13.25 + */
   13.26 +
   13.27 +#ifndef	_SYS_DMU_H
   13.28 +#define	_SYS_DMU_H
   13.29 +
   13.30 +/*
   13.31 + * This file describes the interface that the DMU provides for its
   13.32 + * consumers.
   13.33 + *
   13.34 + * The DMU also interacts with the SPA.  That interface is described in
   13.35 + * dmu_spa.h.
   13.36 + */
   13.37 +typedef enum dmu_object_type {
   13.38 +	DMU_OT_NONE,
   13.39 +	/* general: */
   13.40 +	DMU_OT_OBJECT_DIRECTORY,	/* ZAP */
   13.41 +	DMU_OT_OBJECT_ARRAY,		/* UINT64 */
   13.42 +	DMU_OT_PACKED_NVLIST,		/* UINT8 (XDR by nvlist_pack/unpack) */
   13.43 +	DMU_OT_PACKED_NVLIST_SIZE,	/* UINT64 */
   13.44 +	DMU_OT_BPLIST,			/* UINT64 */
   13.45 +	DMU_OT_BPLIST_HDR,		/* UINT64 */
   13.46 +	/* spa: */
   13.47 +	DMU_OT_SPACE_MAP_HEADER,	/* UINT64 */
   13.48 +	DMU_OT_SPACE_MAP,		/* UINT64 */
   13.49 +	/* zil: */
   13.50 +	DMU_OT_INTENT_LOG,		/* UINT64 */
   13.51 +	/* dmu: */
   13.52 +	DMU_OT_DNODE,			/* DNODE */
   13.53 +	DMU_OT_OBJSET,			/* OBJSET */
   13.54 +	/* dsl: */
   13.55 +	DMU_OT_DSL_DIR,			/* UINT64 */
   13.56 +	DMU_OT_DSL_DIR_CHILD_MAP,	/* ZAP */
   13.57 +	DMU_OT_DSL_DS_SNAP_MAP,		/* ZAP */
   13.58 +	DMU_OT_DSL_PROPS,		/* ZAP */
   13.59 +	DMU_OT_DSL_DATASET,		/* UINT64 */
   13.60 +	/* zpl: */
   13.61 +	DMU_OT_ZNODE,			/* ZNODE */
   13.62 +	DMU_OT_ACL,			/* ACL */
   13.63 +	DMU_OT_PLAIN_FILE_CONTENTS,	/* UINT8 */
   13.64 +	DMU_OT_DIRECTORY_CONTENTS,	/* ZAP */
   13.65 +	DMU_OT_MASTER_NODE,		/* ZAP */
   13.66 +	DMU_OT_UNLINKED_SET,		/* ZAP */
   13.67 +	/* zvol: */
   13.68 +	DMU_OT_ZVOL,			/* UINT8 */
   13.69 +	DMU_OT_ZVOL_PROP,		/* ZAP */
   13.70 +	/* other; for testing only! */
   13.71 +	DMU_OT_PLAIN_OTHER,		/* UINT8 */
   13.72 +	DMU_OT_UINT64_OTHER,		/* UINT64 */
   13.73 +	DMU_OT_ZAP_OTHER,		/* ZAP */
   13.74 +	/* new object types: */
   13.75 +	DMU_OT_ERROR_LOG,		/* ZAP */
   13.76 +	DMU_OT_SPA_HISTORY,		/* UINT8 */
   13.77 +	DMU_OT_SPA_HISTORY_OFFSETS,	/* spa_his_phys_t */
   13.78 +	DMU_OT_POOL_PROPS,		/* ZAP */
   13.79 +
   13.80 +	DMU_OT_NUMTYPES
   13.81 +} dmu_object_type_t;
   13.82 +
   13.83 +typedef enum dmu_objset_type {
   13.84 +	DMU_OST_NONE,
   13.85 +	DMU_OST_META,
   13.86 +	DMU_OST_ZFS,
   13.87 +	DMU_OST_ZVOL,
   13.88 +	DMU_OST_OTHER,			/* For testing only! */
   13.89 +	DMU_OST_ANY,			/* Be careful! */
   13.90 +	DMU_OST_NUMTYPES
   13.91 +} dmu_objset_type_t;
   13.92 +
   13.93 +/*
   13.94 + * The names of zap entries in the DIRECTORY_OBJECT of the MOS.
   13.95 + */
   13.96 +#define	DMU_POOL_DIRECTORY_OBJECT	1
   13.97 +#define	DMU_POOL_CONFIG			"config"
   13.98 +#define	DMU_POOL_ROOT_DATASET		"root_dataset"
   13.99 +#define	DMU_POOL_SYNC_BPLIST		"sync_bplist"
  13.100 +#define	DMU_POOL_ERRLOG_SCRUB		"errlog_scrub"
  13.101 +#define	DMU_POOL_ERRLOG_LAST		"errlog_last"
  13.102 +#define	DMU_POOL_SPARES			"spares"
  13.103 +#define	DMU_POOL_DEFLATE		"deflate"
  13.104 +#define	DMU_POOL_HISTORY		"history"
  13.105 +#define	DMU_POOL_PROPS			"pool_props"
  13.106 +#define	DMU_POOL_L2CACHE		"l2cache"
  13.107 +
  13.108 +#endif	/* _SYS_DMU_H */
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/tools/libfsimage/zfs/zfs-include/dmu_objset.h	Thu May 01 16:38:56 2008 +0100
    14.3 @@ -0,0 +1,35 @@
    14.4 +/*
    14.5 + *  GRUB  --  GRand Unified Bootloader
    14.6 + *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
    14.7 + *
    14.8 + *  This program is free software; you can redistribute it and/or modify
    14.9 + *  it under the terms of the GNU General Public License as published by
   14.10 + *  the Free Software Foundation; either version 2 of the License, or
   14.11 + *  (at your option) any later version.
   14.12 + *
   14.13 + *  This program is distributed in the hope that it will be useful,
   14.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   14.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14.16 + *  GNU General Public License for more details.
   14.17 + *
   14.18 + *  You should have received a copy of the GNU General Public License
   14.19 + *  along with this program; if not, write to the Free Software
   14.20 + *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   14.21 + */
   14.22 +/*
   14.23 + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
   14.24 + * Use is subject to license terms.
   14.25 + */
   14.26 +
   14.27 +#ifndef	_SYS_DMU_OBJSET_H
   14.28 +#define	_SYS_DMU_OBJSET_H
   14.29 +
   14.30 +typedef struct objset_phys {
   14.31 +	dnode_phys_t os_meta_dnode;
   14.32 +	zil_header_t os_zil_header;
   14.33 +	uint64_t os_type;
   14.34 +	char os_pad[1024 - sizeof (dnode_phys_t) - sizeof (zil_header_t) -
   14.35 +	    sizeof (uint64_t)];
   14.36 +} objset_phys_t;
   14.37 +
   14.38 +#endif /* _SYS_DMU_OBJSET_H */
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/tools/libfsimage/zfs/zfs-include/dnode.h	Thu May 01 16:38:56 2008 +0100
    15.3 @@ -0,0 +1,76 @@
    15.4 +/*
    15.5 + *  GRUB  --  GRand Unified Bootloader
    15.6 + *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
    15.7 + *
    15.8 + *  This program is free software; you can redistribute it and/or modify
    15.9 + *  it under the terms of the GNU General Public License as published by
   15.10 + *  the Free Software Foundation; either version 2 of the License, or
   15.11 + *  (at your option) any later version.
   15.12 + *
   15.13 + *  This program is distributed in the hope that it will be useful,
   15.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   15.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15.16 + *  GNU General Public License for more details.
   15.17 + *
   15.18 + *  You should have received a copy of the GNU General Public License
   15.19 + *  along with this program; if not, write to the Free Software
   15.20 + *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   15.21 + */
   15.22 +/*
   15.23 + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
   15.24 + * Use is subject to license terms.
   15.25 + */
   15.26 +
   15.27 +#ifndef	_SYS_DNODE_H
   15.28 +#define	_SYS_DNODE_H
   15.29 +
   15.30 +/*
   15.31 + * Fixed constants.
   15.32 + */
   15.33 +#define	DNODE_SHIFT		9	/* 512 bytes */
   15.34 +#define	DN_MIN_INDBLKSHIFT	10	/* 1k */
   15.35 +#define	DN_MAX_INDBLKSHIFT	14	/* 16k */
   15.36 +#define	DNODE_BLOCK_SHIFT	14	/* 16k */
   15.37 +#define	DNODE_CORE_SIZE		64	/* 64 bytes for dnode sans blkptrs */
   15.38 +#define	DN_MAX_OBJECT_SHIFT	48	/* 256 trillion (zfs_fid_t limit) */
   15.39 +#define	DN_MAX_OFFSET_SHIFT	64	/* 2^64 bytes in a dnode */
   15.40 +
   15.41 +/*
   15.42 + * Derived constants.
   15.43 + */
   15.44 +#define	DNODE_SIZE	(1 << DNODE_SHIFT)
   15.45 +#define	DN_MAX_NBLKPTR	((DNODE_SIZE - DNODE_CORE_SIZE) >> SPA_BLKPTRSHIFT)
   15.46 +#define	DN_MAX_BONUSLEN	(DNODE_SIZE - DNODE_CORE_SIZE - (1 << SPA_BLKPTRSHIFT))
   15.47 +#define	DN_MAX_OBJECT	(1ULL << DN_MAX_OBJECT_SHIFT)
   15.48 +
   15.49 +#define	DNODES_PER_BLOCK_SHIFT	(DNODE_BLOCK_SHIFT - DNODE_SHIFT)
   15.50 +#define	DNODES_PER_BLOCK	(1ULL << DNODES_PER_BLOCK_SHIFT)
   15.51 +#define	DNODES_PER_LEVEL_SHIFT	(DN_MAX_INDBLKSHIFT - SPA_BLKPTRSHIFT)
   15.52 +
   15.53 +#define	DN_BONUS(dnp)	((void*)((dnp)->dn_bonus + \
   15.54 +	(((dnp)->dn_nblkptr - 1) * sizeof (blkptr_t))))
   15.55 +
   15.56 +typedef struct dnode_phys {
   15.57 +	uint8_t dn_type;		/* dmu_object_type_t */
   15.58 +	uint8_t dn_indblkshift;		/* ln2(indirect block size) */
   15.59 +	uint8_t dn_nlevels;		/* 1=dn_blkptr->data blocks */
   15.60 +	uint8_t dn_nblkptr;		/* length of dn_blkptr */
   15.61 +	uint8_t dn_bonustype;		/* type of data in bonus buffer */
   15.62 +	uint8_t	dn_checksum;		/* ZIO_CHECKSUM type */
   15.63 +	uint8_t	dn_compress;		/* ZIO_COMPRESS type */
   15.64 +	uint8_t dn_flags;		/* DNODE_FLAG_* */
   15.65 +	uint16_t dn_datablkszsec;	/* data block size in 512b sectors */
   15.66 +	uint16_t dn_bonuslen;		/* length of dn_bonus */
   15.67 +	uint8_t dn_pad2[4];
   15.68 +
   15.69 +	/* accounting is protected by dn_dirty_mtx */
   15.70 +	uint64_t dn_maxblkid;		/* largest allocated block ID */
   15.71 +	uint64_t dn_used;		/* bytes (or sectors) of disk space */
   15.72 +
   15.73 +	uint64_t dn_pad3[4];
   15.74 +
   15.75 +	blkptr_t dn_blkptr[1];
   15.76 +	uint8_t dn_bonus[DN_MAX_BONUSLEN];
   15.77 +} dnode_phys_t;
   15.78 +
   15.79 +#endif	/* _SYS_DNODE_H */
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/tools/libfsimage/zfs/zfs-include/dsl_dataset.h	Thu May 01 16:38:56 2008 +0100
    16.3 @@ -0,0 +1,53 @@
    16.4 +/*
    16.5 + *  GRUB  --  GRand Unified Bootloader
    16.6 + *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
    16.7 + *
    16.8 + *  This program is free software; you can redistribute it and/or modify
    16.9 + *  it under the terms of the GNU General Public License as published by
   16.10 + *  the Free Software Foundation; either version 2 of the License, or
   16.11 + *  (at your option) any later version.
   16.12 + *
   16.13 + *  This program is distributed in the hope that it will be useful,
   16.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   16.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16.16 + *  GNU General Public License for more details.
   16.17 + *
   16.18 + *  You should have received a copy of the GNU General Public License
   16.19 + *  along with this program; if not, write to the Free Software
   16.20 + *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   16.21 + */
   16.22 +/*
   16.23 + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
   16.24 + * Use is subject to license terms.
   16.25 + */
   16.26 +
   16.27 +#ifndef	_SYS_DSL_DATASET_H
   16.28 +#define	_SYS_DSL_DATASET_H
   16.29 +
   16.30 +typedef struct dsl_dataset_phys {
   16.31 +	uint64_t ds_dir_obj;
   16.32 +	uint64_t ds_prev_snap_obj;
   16.33 +	uint64_t ds_prev_snap_txg;
   16.34 +	uint64_t ds_next_snap_obj;
   16.35 +	uint64_t ds_snapnames_zapobj;	/* zap obj of snaps; ==0 for snaps */
   16.36 +	uint64_t ds_num_children;	/* clone/snap children; ==0 for head */
   16.37 +	uint64_t ds_creation_time;	/* seconds since 1970 */
   16.38 +	uint64_t ds_creation_txg;
   16.39 +	uint64_t ds_deadlist_obj;
   16.40 +	uint64_t ds_used_bytes;
   16.41 +	uint64_t ds_compressed_bytes;
   16.42 +	uint64_t ds_uncompressed_bytes;
   16.43 +	uint64_t ds_unique_bytes;	/* only relevant to snapshots */
   16.44 +	/*
   16.45 +	 * The ds_fsid_guid is a 56-bit ID that can change to avoid
   16.46 +	 * collisions.  The ds_guid is a 64-bit ID that will never
   16.47 +	 * change, so there is a small probability that it will collide.
   16.48 +	 */
   16.49 +	uint64_t ds_fsid_guid;
   16.50 +	uint64_t ds_guid;
   16.51 +	uint64_t ds_flags;
   16.52 +	blkptr_t ds_bp;
   16.53 +	uint64_t ds_pad[8]; /* pad out to 320 bytes for good measure */
   16.54 +} dsl_dataset_phys_t;
   16.55 +
   16.56 +#endif /* _SYS_DSL_DATASET_H */
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/tools/libfsimage/zfs/zfs-include/dsl_dir.h	Thu May 01 16:38:56 2008 +0100
    17.3 @@ -0,0 +1,49 @@
    17.4 +/*
    17.5 + *  GRUB  --  GRand Unified Bootloader
    17.6 + *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
    17.7 + *
    17.8 + *  This program is free software; you can redistribute it and/or modify
    17.9 + *  it under the terms of the GNU General Public License as published by
   17.10 + *  the Free Software Foundation; either version 2 of the License, or
   17.11 + *  (at your option) any later version.
   17.12 + *
   17.13 + *  This program is distributed in the hope that it will be useful,
   17.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   17.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   17.16 + *  GNU General Public License for more details.
   17.17 + *
   17.18 + *  You should have received a copy of the GNU General Public License
   17.19 + *  along with this program; if not, write to the Free Software
   17.20 + *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   17.21 + */
   17.22 +/*
   17.23 + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
   17.24 + * Use is subject to license terms.
   17.25 + */
   17.26 +
   17.27 +#ifndef	_SYS_DSL_DIR_H
   17.28 +#define	_SYS_DSL_DIR_H
   17.29 +
   17.30 +typedef struct dsl_dir_phys {
   17.31 +	uint64_t dd_creation_time; /* not actually used */
   17.32 +	uint64_t dd_head_dataset_obj;
   17.33 +	uint64_t dd_parent_obj;
   17.34 +	uint64_t dd_clone_parent_obj;
   17.35 +	uint64_t dd_child_dir_zapobj;
   17.36 +	/*
   17.37 +	 * how much space our children are accounting for; for leaf
   17.38 +	 * datasets, == physical space used by fs + snaps
   17.39 +	 */
   17.40 +	uint64_t dd_used_bytes;
   17.41 +	uint64_t dd_compressed_bytes;
   17.42 +	uint64_t dd_uncompressed_bytes;
   17.43 +	/* Administrative quota setting */
   17.44 +	uint64_t dd_quota;
   17.45 +	/* Administrative reservation setting */
   17.46 +	uint64_t dd_reserved;
   17.47 +	uint64_t dd_props_zapobj;
   17.48 +	uint64_t dd_deleg_zapobj;	/* dataset permissions */
   17.49 +	uint64_t dd_pad[20]; /* pad out to 256 bytes for good measure */
   17.50 +} dsl_dir_phys_t;
   17.51 +
   17.52 +#endif /* _SYS_DSL_DIR_H */
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/tools/libfsimage/zfs/zfs-include/spa.h	Thu May 01 16:38:56 2008 +0100
    18.3 @@ -0,0 +1,283 @@
    18.4 +/*
    18.5 + *  GRUB  --  GRand Unified Bootloader
    18.6 + *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
    18.7 + *
    18.8 + *  This program is free software; you can redistribute it and/or modify
    18.9 + *  it under the terms of the GNU General Public License as published by
   18.10 + *  the Free Software Foundation; either version 2 of the License, or
   18.11 + *  (at your option) any later version.
   18.12 + *
   18.13 + *  This program is distributed in the hope that it will be useful,
   18.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   18.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   18.16 + *  GNU General Public License for more details.
   18.17 + *
   18.18 + *  You should have received a copy of the GNU General Public License
   18.19 + *  along with this program; if not, write to the Free Software
   18.20 + *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   18.21 + */
   18.22 +/*
   18.23 + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
   18.24 + * Use is subject to license terms.
   18.25 + */
   18.26 +
   18.27 +#ifndef _SYS_SPA_H
   18.28 +#define	_SYS_SPA_H
   18.29 +
   18.30 +/*
   18.31 + * General-purpose 32-bit and 64-bit bitfield encodings.
   18.32 + */
   18.33 +#define	BF32_DECODE(x, low, len)	P2PHASE((x) >> (low), 1U << (len))
   18.34 +#define	BF64_DECODE(x, low, len)	P2PHASE((x) >> (low), 1ULL << (len))
   18.35 +#define	BF32_ENCODE(x, low, len)	(P2PHASE((x), 1U << (len)) << (low))
   18.36 +#define	BF64_ENCODE(x, low, len)	(P2PHASE((x), 1ULL << (len)) << (low))
   18.37 +
   18.38 +#define	BF32_GET(x, low, len)		BF32_DECODE(x, low, len)
   18.39 +#define	BF64_GET(x, low, len)		BF64_DECODE(x, low, len)
   18.40 +
   18.41 +#define	BF32_SET(x, low, len, val)	\
   18.42 +	((x) ^= BF32_ENCODE((x >> low) ^ (val), low, len))
   18.43 +#define	BF64_SET(x, low, len, val)	\
   18.44 +	((x) ^= BF64_ENCODE((x >> low) ^ (val), low, len))
   18.45 +
   18.46 +#define	BF32_GET_SB(x, low, len, shift, bias)	\
   18.47 +	((BF32_GET(x, low, len) + (bias)) << (shift))
   18.48 +#define	BF64_GET_SB(x, low, len, shift, bias)	\
   18.49 +	((BF64_GET(x, low, len) + (bias)) << (shift))
   18.50 +
   18.51 +#define	BF32_SET_SB(x, low, len, shift, bias, val)	\
   18.52 +	BF32_SET(x, low, len, ((val) >> (shift)) - (bias))
   18.53 +#define	BF64_SET_SB(x, low, len, shift, bias, val)	\
   18.54 +	BF64_SET(x, low, len, ((val) >> (shift)) - (bias))
   18.55 +
   18.56 +/*
   18.57 + * We currently support nine block sizes, from 512 bytes to 128K.
   18.58 + * We could go higher, but the benefits are near-zero and the cost
   18.59 + * of COWing a giant block to modify one byte would become excessive.
   18.60 + */
   18.61 +#define	SPA_MINBLOCKSHIFT	9
   18.62 +#define	SPA_MAXBLOCKSHIFT	17
   18.63 +#define	SPA_MINBLOCKSIZE	(1ULL << SPA_MINBLOCKSHIFT)
   18.64 +#define	SPA_MAXBLOCKSIZE	(1ULL << SPA_MAXBLOCKSHIFT)
   18.65 +
   18.66 +#define	SPA_BLOCKSIZES		(SPA_MAXBLOCKSHIFT - SPA_MINBLOCKSHIFT + 1)
   18.67 +
   18.68 +/*
   18.69 + * The DVA size encodings for LSIZE and PSIZE support blocks up to 32MB.
   18.70 + * The ASIZE encoding should be at least 64 times larger (6 more bits)
   18.71 + * to support up to 4-way RAID-Z mirror mode with worst-case gang block
   18.72 + * overhead, three DVAs per bp, plus one more bit in case we do anything
   18.73 + * else that expands the ASIZE.
   18.74 + */
   18.75 +#define	SPA_LSIZEBITS		16	/* LSIZE up to 32M (2^16 * 512)	*/
   18.76 +#define	SPA_PSIZEBITS		16	/* PSIZE up to 32M (2^16 * 512)	*/
   18.77 +#define	SPA_ASIZEBITS		24	/* ASIZE up to 64 times larger	*/
   18.78 +
   18.79 +/*
   18.80 + * All SPA data is represented by 128-bit data virtual addresses (DVAs).
   18.81 + * The members of the dva_t should be considered opaque outside the SPA.
   18.82 + */
   18.83 +typedef struct dva {
   18.84 +	uint64_t	dva_word[2];
   18.85 +} dva_t;
   18.86 +
   18.87 +/*
   18.88 + * Each block has a 256-bit checksum -- strong enough for cryptographic hashes.
   18.89 + */
   18.90 +typedef struct zio_cksum {
   18.91 +	uint64_t	zc_word[4];
   18.92 +} zio_cksum_t;
   18.93 +
   18.94 +/*
   18.95 + * Each block is described by its DVAs, time of birth, checksum, etc.
   18.96 + * The word-by-word, bit-by-bit layout of the blkptr is as follows:
   18.97 + *
   18.98 + *	64	56	48	40	32	24	16	8	0
   18.99 + *	+-------+-------+-------+-------+-------+-------+-------+-------+
  18.100 + * 0	|		vdev1		| GRID  |	  ASIZE		|
  18.101 + *	+-------+-------+-------+-------+-------+-------+-------+-------+
  18.102 + * 1	|G|			 offset1				|
  18.103 + *	+-------+-------+-------+-------+-------+-------+-------+-------+
  18.104 + * 2	|		vdev2		| GRID  |	  ASIZE		|
  18.105 + *	+-------+-------+-------+-------+-------+-------+-------+-------+
  18.106 + * 3	|G|			 offset2				|
  18.107 + *	+-------+-------+-------+-------+-------+-------+-------+-------+
  18.108 + * 4	|		vdev3		| GRID  |	  ASIZE		|
  18.109 + *	+-------+-------+-------+-------+-------+-------+-------+-------+
  18.110 + * 5	|G|			 offset3				|
  18.111 + *	+-------+-------+-------+-------+-------+-------+-------+-------+
  18.112 + * 6	|E| lvl | type	| cksum | comp	|     PSIZE	|     LSIZE	|
  18.113 + *	+-------+-------+-------+-------+-------+-------+-------+-------+
  18.114 + * 7	|			padding					|
  18.115 + *	+-------+-------+-------+-------+-------+-------+-------+-------+
  18.116 + * 8	|			padding					|
  18.117 + *	+-------+-------+-------+-------+-------+-------+-------+-------+
  18.118 + * 9	|			padding					|
  18.119 + *	+-------+-------+-------+-------+-------+-------+-------+-------+
  18.120 + * a	|			birth txg				|
  18.121 + *	+-------+-------+-------+-------+-------+-------+-------+-------+
  18.122 + * b	|			fill count				|
  18.123 + *	+-------+-------+-------+-------+-------+-------+-------+-------+
  18.124 + * c	|			checksum[0]				|
  18.125 + *	+-------+-------+-------+-------+-------+-------+-------+-------+
  18.126 + * d	|			checksum[1]				|
  18.127 + *	+-------+-------+-------+-------+-------+-------+-------+-------+
  18.128 + * e	|			checksum[2]				|
  18.129 + *	+-------+-------+-------+-------+-------+-------+-------+-------+
  18.130 + * f	|			checksum[3]				|
  18.131 + *	+-------+-------+-------+-------+-------+-------+-------+-------+
  18.132 + *
  18.133 + * Legend:
  18.134 + *
  18.135 + * vdev		virtual device ID
  18.136 + * offset	offset into virtual device
  18.137 + * LSIZE	logical size
  18.138 + * PSIZE	physical size (after compression)
  18.139 + * ASIZE	allocated size (including RAID-Z parity and gang block headers)
  18.140 + * GRID		RAID-Z layout information (reserved for future use)
  18.141 + * cksum	checksum function
  18.142 + * comp		compression function
  18.143 + * G		gang block indicator
  18.144 + * E		endianness
  18.145 + * type		DMU object type
  18.146 + * lvl		level of indirection
  18.147 + * birth txg	transaction group in which the block was born
  18.148 + * fill count	number of non-zero blocks under this bp
  18.149 + * checksum[4]	256-bit checksum of the data this bp describes
  18.150 + */
  18.151 +typedef struct blkptr {
  18.152 +	dva_t		blk_dva[3];	/* 128-bit Data Virtual Address	*/
  18.153 +	uint64_t	blk_prop;	/* size, compression, type, etc	*/
  18.154 +	uint64_t	blk_pad[3];	/* Extra space for the future	*/
  18.155 +	uint64_t	blk_birth;	/* transaction group at birth	*/
  18.156 +	uint64_t	blk_fill;	/* fill count			*/
  18.157 +	zio_cksum_t	blk_cksum;	/* 256-bit checksum		*/
  18.158 +} blkptr_t;
  18.159 +
  18.160 +#define	SPA_BLKPTRSHIFT	7		/* blkptr_t is 128 bytes	*/
  18.161 +#define	SPA_DVAS_PER_BP	3		/* Number of DVAs in a bp	*/
  18.162 +
  18.163 +/*
  18.164 + * Macros to get and set fields in a bp or DVA.
  18.165 + */
  18.166 +#define	DVA_GET_ASIZE(dva)	\
  18.167 +	BF64_GET_SB((dva)->dva_word[0], 0, 24, SPA_MINBLOCKSHIFT, 0)
  18.168 +#define	DVA_SET_ASIZE(dva, x)	\
  18.169 +	BF64_SET_SB((dva)->dva_word[0], 0, 24, SPA_MINBLOCKSHIFT, 0, x)
  18.170 +
  18.171 +#define	DVA_GET_GRID(dva)	BF64_GET((dva)->dva_word[0], 24, 8)
  18.172 +#define	DVA_SET_GRID(dva, x)	BF64_SET((dva)->dva_word[0], 24, 8, x)
  18.173 +
  18.174 +#define	DVA_GET_VDEV(dva)	BF64_GET((dva)->dva_word[0], 32, 32)
  18.175 +#define	DVA_SET_VDEV(dva, x)	BF64_SET((dva)->dva_word[0], 32, 32, x)
  18.176 +
  18.177 +#define	DVA_GET_OFFSET(dva)	\
  18.178 +	BF64_GET_SB((dva)->dva_word[1], 0, 63, SPA_MINBLOCKSHIFT, 0)
  18.179 +#define	DVA_SET_OFFSET(dva, x)	\
  18.180 +	BF64_SET_SB((dva)->dva_word[1], 0, 63, SPA_MINBLOCKSHIFT, 0, x)
  18.181 +
  18.182 +#define	DVA_GET_GANG(dva)	BF64_GET((dva)->dva_word[1], 63, 1)
  18.183 +#define	DVA_SET_GANG(dva, x)	BF64_SET((dva)->dva_word[1], 63, 1, x)
  18.184 +
  18.185 +#define	BP_GET_LSIZE(bp)	\
  18.186 +	(BP_IS_HOLE(bp) ? 0 : \
  18.187 +	BF64_GET_SB((bp)->blk_prop, 0, 16, SPA_MINBLOCKSHIFT, 1))
  18.188 +#define	BP_SET_LSIZE(bp, x)	\
  18.189 +	BF64_SET_SB((bp)->blk_prop, 0, 16, SPA_MINBLOCKSHIFT, 1, x)
  18.190 +
  18.191 +#define	BP_GET_PSIZE(bp)	\
  18.192 +	BF64_GET_SB((bp)->blk_prop, 16, 16, SPA_MINBLOCKSHIFT, 1)
  18.193 +#define	BP_SET_PSIZE(bp, x)	\
  18.194 +	BF64_SET_SB((bp)->blk_prop, 16, 16, SPA_MINBLOCKSHIFT, 1, x)
  18.195 +
  18.196 +#define	BP_GET_COMPRESS(bp)	BF64_GET((bp)->blk_prop, 32, 8)
  18.197 +#define	BP_SET_COMPRESS(bp, x)	BF64_SET((bp)->blk_prop, 32, 8, x)
  18.198 +
  18.199 +#define	BP_GET_CHECKSUM(bp)	BF64_GET((bp)->blk_prop, 40, 8)
  18.200 +#define	BP_SET_CHECKSUM(bp, x)	BF64_SET((bp)->blk_prop, 40, 8, x)
  18.201 +
  18.202 +#define	BP_GET_TYPE(bp)		BF64_GET((bp)->blk_prop, 48, 8)
  18.203 +#define	BP_SET_TYPE(bp, x)	BF64_SET((bp)->blk_prop, 48, 8, x)
  18.204 +
  18.205 +#define	BP_GET_LEVEL(bp)	BF64_GET((bp)->blk_prop, 56, 5)
  18.206 +#define	BP_SET_LEVEL(bp, x)	BF64_SET((bp)->blk_prop, 56, 5, x)
  18.207 +
  18.208 +#define	BP_GET_BYTEORDER(bp)	(0 - BF64_GET((bp)->blk_prop, 63, 1))
  18.209 +#define	BP_SET_BYTEORDER(bp, x)	BF64_SET((bp)->blk_prop, 63, 1, x)
  18.210 +
  18.211 +#define	BP_GET_ASIZE(bp)	\
  18.212 +	(DVA_GET_ASIZE(&(bp)->blk_dva[0]) + DVA_GET_ASIZE(&(bp)->blk_dva[1]) + \
  18.213 +		DVA_GET_ASIZE(&(bp)->blk_dva[2]))
  18.214 +
  18.215 +#define	BP_GET_UCSIZE(bp) \
  18.216 +	((BP_GET_LEVEL(bp) > 0 || dmu_ot[BP_GET_TYPE(bp)].ot_metadata) ? \
  18.217 +	BP_GET_PSIZE(bp) : BP_GET_LSIZE(bp));
  18.218 +
  18.219 +#define	BP_GET_NDVAS(bp)	\
  18.220 +	(!!DVA_GET_ASIZE(&(bp)->blk_dva[0]) + \
  18.221 +	!!DVA_GET_ASIZE(&(bp)->blk_dva[1]) + \
  18.222 +	!!DVA_GET_ASIZE(&(bp)->blk_dva[2]))
  18.223 +
  18.224 +#define	BP_COUNT_GANG(bp)	\
  18.225 +	(DVA_GET_GANG(&(bp)->blk_dva[0]) + \
  18.226 +	DVA_GET_GANG(&(bp)->blk_dva[1]) + \
  18.227 +	DVA_GET_GANG(&(bp)->blk_dva[2]))
  18.228 +
  18.229 +#define	DVA_EQUAL(dva1, dva2)	\
  18.230 +	((dva1)->dva_word[1] == (dva2)->dva_word[1] && \
  18.231 +	(dva1)->dva_word[0] == (dva2)->dva_word[0])
  18.232 +
  18.233 +#define	ZIO_CHECKSUM_EQUAL(zc1, zc2) \
  18.234 +	(0 == (((zc1).zc_word[0] - (zc2).zc_word[0]) | \
  18.235 +	((zc1).zc_word[1] - (zc2).zc_word[1]) | \
  18.236 +	((zc1).zc_word[2] - (zc2).zc_word[2]) | \
  18.237 +	((zc1).zc_word[3] - (zc2).zc_word[3])))
  18.238 +
  18.239 +
  18.240 +#define	DVA_IS_VALID(dva)	(DVA_GET_ASIZE(dva) != 0)
  18.241 +
  18.242 +#define	ZIO_SET_CHECKSUM(zcp, w0, w1, w2, w3)	\
  18.243 +{						\
  18.244 +	(zcp)->zc_word[0] = w0;			\
  18.245 +	(zcp)->zc_word[1] = w1;			\
  18.246 +	(zcp)->zc_word[2] = w2;			\
  18.247 +	(zcp)->zc_word[3] = w3;			\
  18.248 +}
  18.249 +
  18.250 +#define	BP_IDENTITY(bp)		(&(bp)->blk_dva[0])
  18.251 +#define	BP_IS_GANG(bp)		DVA_GET_GANG(BP_IDENTITY(bp))
  18.252 +#define	BP_IS_HOLE(bp)		((bp)->blk_birth == 0)
  18.253 +#define	BP_IS_OLDER(bp, txg)	(!BP_IS_HOLE(bp) && (bp)->blk_birth < (txg))
  18.254 +
  18.255 +#define	BP_ZERO(bp)				\
  18.256 +{						\
  18.257 +	(bp)->blk_dva[0].dva_word[0] = 0;	\
  18.258 +	(bp)->blk_dva[0].dva_word[1] = 0;	\
  18.259 +	(bp)->blk_dva[1].dva_word[0] = 0;	\
  18.260 +	(bp)->blk_dva[1].dva_word[1] = 0;	\
  18.261 +	(bp)->blk_dva[2].dva_word[0] = 0;	\
  18.262 +	(bp)->blk_dva[2].dva_word[1] = 0;	\
  18.263 +	(bp)->blk_prop = 0;			\
  18.264 +	(bp)->blk_pad[0] = 0;			\
  18.265 +	(bp)->blk_pad[1] = 0;			\
  18.266 +	(bp)->blk_pad[2] = 0;			\
  18.267 +	(bp)->blk_birth = 0;			\
  18.268 +	(bp)->blk_fill = 0;			\
  18.269 +	ZIO_SET_CHECKSUM(&(bp)->blk_cksum, 0, 0, 0, 0);	\
  18.270 +}
  18.271 +
  18.272 +/*
  18.273 + * Note: the byteorder is either 0 or -1, both of which are palindromes.
  18.274 + * This simplifies the endianness handling a bit.
  18.275 + */
  18.276 +#ifdef _BIG_ENDIAN
  18.277 +#define	ZFS_HOST_BYTEORDER	(0ULL)
  18.278 +#else
  18.279 +#define	ZFS_HOST_BYTEORDER	(-1ULL)
  18.280 +#endif
  18.281 +
  18.282 +#define	BP_SHOULD_BYTESWAP(bp)	(BP_GET_BYTEORDER(bp) != ZFS_HOST_BYTEORDER)
  18.283 +
  18.284 +#define	BP_SPRINTF_LEN	320
  18.285 +
  18.286 +#endif	/* _SYS_SPA_H */
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/tools/libfsimage/zfs/zfs-include/uberblock_impl.h	Thu May 01 16:38:56 2008 +0100
    19.3 @@ -0,0 +1,49 @@
    19.4 +/*
    19.5 + *  GRUB  --  GRand Unified Bootloader
    19.6 + *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
    19.7 + *
    19.8 + *  This program is free software; you can redistribute it and/or modify
    19.9 + *  it under the terms of the GNU General Public License as published by
   19.10 + *  the Free Software Foundation; either version 2 of the License, or
   19.11 + *  (at your option) any later version.
   19.12 + *
   19.13 + *  This program is distributed in the hope that it will be useful,
   19.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   19.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   19.16 + *  GNU General Public License for more details.
   19.17 + *
   19.18 + *  You should have received a copy of the GNU General Public License
   19.19 + *  along with this program; if not, write to the Free Software
   19.20 + *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   19.21 + */
   19.22 +/*
   19.23 + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
   19.24 + * Use is subject to license terms.
   19.25 + */
   19.26 +
   19.27 +#ifndef _SYS_UBERBLOCK_IMPL_H
   19.28 +#define	_SYS_UBERBLOCK_IMPL_H
   19.29 +
   19.30 +/*
   19.31 + * The uberblock version is incremented whenever an incompatible on-disk
   19.32 + * format change is made to the SPA, DMU, or ZAP.
   19.33 + *
   19.34 + * Note: the first two fields should never be moved.  When a storage pool
   19.35 + * is opened, the uberblock must be read off the disk before the version
   19.36 + * can be checked.  If the ub_version field is moved, we may not detect
   19.37 + * version mismatch.  If the ub_magic field is moved, applications that
   19.38 + * expect the magic number in the first word won't work.
   19.39 + */
   19.40 +#define	UBERBLOCK_MAGIC		0x00bab10c		/* oo-ba-bloc!	*/
   19.41 +#define	UBERBLOCK_SHIFT		10			/* up to 1K	*/
   19.42 +
   19.43 +struct uberblock {
   19.44 +	uint64_t	ub_magic;	/* UBERBLOCK_MAGIC		*/
   19.45 +	uint64_t	ub_version;	/* ZFS_VERSION			*/
   19.46 +	uint64_t	ub_txg;		/* txg of last sync		*/
   19.47 +	uint64_t	ub_guid_sum;	/* sum of all vdev guids	*/
   19.48 +	uint64_t	ub_timestamp;	/* UTC time of last sync	*/
   19.49 +	blkptr_t	ub_rootbp;	/* MOS objset_phys_t		*/
   19.50 +};
   19.51 +
   19.52 +#endif	/* _SYS_UBERBLOCK_IMPL_H */
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/tools/libfsimage/zfs/zfs-include/vdev_impl.h	Thu May 01 16:38:56 2008 +0100
    20.3 @@ -0,0 +1,70 @@
    20.4 +/*
    20.5 + *  GRUB  --  GRand Unified Bootloader
    20.6 + *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
    20.7 + *
    20.8 + *  This program is free software; you can redistribute it and/or modify
    20.9 + *  it under the terms of the GNU General Public License as published by
   20.10 + *  the Free Software Foundation; either version 2 of the License, or
   20.11 + *  (at your option) any later version.
   20.12 + *
   20.13 + *  This program is distributed in the hope that it will be useful,
   20.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   20.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   20.16 + *  GNU General Public License for more details.
   20.17 + *
   20.18 + *  You should have received a copy of the GNU General Public License
   20.19 + *  along with this program; if not, write to the Free Software
   20.20 + *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   20.21 + */
   20.22 +/*
   20.23 + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
   20.24 + * Use is subject to license terms.
   20.25 + */
   20.26 +
   20.27 +#ifndef _SYS_VDEV_IMPL_H
   20.28 +#define	_SYS_VDEV_IMPL_H
   20.29 +
   20.30 +#define	VDEV_SKIP_SIZE		(8 << 10)
   20.31 +#define	VDEV_BOOT_HEADER_SIZE	(8 << 10)
   20.32 +#define	VDEV_PHYS_SIZE		(112 << 10)
   20.33 +#define	VDEV_UBERBLOCK_RING	(128 << 10)
   20.34 +
   20.35 +/* ZFS boot block */
   20.36 +#define	VDEV_BOOT_MAGIC		0x2f5b007b10cULL
   20.37 +#define	VDEV_BOOT_VERSION	1		/* version number	*/
   20.38 +
   20.39 +typedef struct vdev_boot_header {
   20.40 +	uint64_t	vb_magic;		/* VDEV_BOOT_MAGIC	*/
   20.41 +	uint64_t	vb_version;		/* VDEV_BOOT_VERSION	*/
   20.42 +	uint64_t	vb_offset;		/* start offset	(bytes) */
   20.43 +	uint64_t	vb_size;		/* size (bytes)		*/
   20.44 +	char		vb_pad[VDEV_BOOT_HEADER_SIZE - 4 * sizeof (uint64_t)];
   20.45 +} vdev_boot_header_t;
   20.46 +
   20.47 +typedef struct vdev_phys {
   20.48 +	char		vp_nvlist[VDEV_PHYS_SIZE - sizeof (zio_block_tail_t)];
   20.49 +	zio_block_tail_t vp_zbt;
   20.50 +} vdev_phys_t;
   20.51 +
   20.52 +typedef struct vdev_label {
   20.53 +	char		vl_pad[VDEV_SKIP_SIZE];			/*   8K	*/
   20.54 +	vdev_boot_header_t vl_boot_header;			/*   8K	*/
   20.55 +	vdev_phys_t	vl_vdev_phys;				/* 112K	*/
   20.56 +	char		vl_uberblock[VDEV_UBERBLOCK_RING];	/* 128K	*/
   20.57 +} vdev_label_t;							/* 256K total */
   20.58 +
   20.59 +/*
   20.60 + * Size and offset of embedded boot loader region on each label.
   20.61 + * The total size of the first two labels plus the boot area is 4MB.
   20.62 + */
   20.63 +#define	VDEV_BOOT_OFFSET	(2 * sizeof (vdev_label_t))
   20.64 +#define	VDEV_BOOT_SIZE		(7ULL << 19)			/* 3.5M	*/
   20.65 +
   20.66 +/*
   20.67 + * Size of label regions at the start and end of each leaf device.
   20.68 + */
   20.69 +#define	VDEV_LABEL_START_SIZE	(2 * sizeof (vdev_label_t) + VDEV_BOOT_SIZE)
   20.70 +#define	VDEV_LABEL_END_SIZE	(2 * sizeof (vdev_label_t))
   20.71 +#define	VDEV_LABELS		4
   20.72 +
   20.73 +#endif	/* _SYS_VDEV_IMPL_H */
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/tools/libfsimage/zfs/zfs-include/zap_impl.h	Thu May 01 16:38:56 2008 +0100
    21.3 @@ -0,0 +1,110 @@
    21.4 +/*
    21.5 + *  GRUB  --  GRand Unified Bootloader
    21.6 + *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
    21.7 + *
    21.8 + *  This program is free software; you can redistribute it and/or modify
    21.9 + *  it under the terms of the GNU General Public License as published by
   21.10 + *  the Free Software Foundation; either version 2 of the License, or
   21.11 + *  (at your option) any later version.
   21.12 + *
   21.13 + *  This program is distributed in the hope that it will be useful,
   21.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   21.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   21.16 + *  GNU General Public License for more details.
   21.17 + *
   21.18 + *  You should have received a copy of the GNU General Public License
   21.19 + *  along with this program; if not, write to the Free Software
   21.20 + *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   21.21 + */
   21.22 +/*
   21.23 + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
   21.24 + * Use is subject to license terms.
   21.25 + */
   21.26 +
   21.27 +#ifndef	_SYS_ZAP_IMPL_H
   21.28 +#define	_SYS_ZAP_IMPL_H
   21.29 +
   21.30 +#define	ZAP_MAGIC 0x2F52AB2ABULL
   21.31 +
   21.32 +#define	ZAP_HASHBITS		28
   21.33 +#define	MZAP_ENT_LEN		64
   21.34 +#define	MZAP_NAME_LEN		(MZAP_ENT_LEN - 8 - 4 - 2)
   21.35 +#define	MZAP_MAX_BLKSHIFT	SPA_MAXBLOCKSHIFT
   21.36 +#define	MZAP_MAX_BLKSZ		(1 << MZAP_MAX_BLKSHIFT)
   21.37 +
   21.38 +typedef struct mzap_ent_phys {
   21.39 +	uint64_t mze_value;
   21.40 +	uint32_t mze_cd;
   21.41 +	uint16_t mze_pad;	/* in case we want to chain them someday */
   21.42 +	char mze_name[MZAP_NAME_LEN];
   21.43 +} mzap_ent_phys_t;
   21.44 +
   21.45 +typedef struct mzap_phys {
   21.46 +	uint64_t mz_block_type;	/* ZBT_MICRO */
   21.47 +	uint64_t mz_salt;
   21.48 +	uint64_t mz_pad[6];
   21.49 +	mzap_ent_phys_t mz_chunk[1];
   21.50 +	/* actually variable size depending on block size */
   21.51 +} mzap_phys_t;
   21.52 +
   21.53 +/*
   21.54 + * The (fat) zap is stored in one object. It is an array of
   21.55 + * 1<<FZAP_BLOCK_SHIFT byte blocks. The layout looks like one of:
   21.56 + *
   21.57 + * ptrtbl fits in first block:
   21.58 + * 	[zap_phys_t zap_ptrtbl_shift < 6] [zap_leaf_t] ...
   21.59 + *
   21.60 + * ptrtbl too big for first block:
   21.61 + * 	[zap_phys_t zap_ptrtbl_shift >= 6] [zap_leaf_t] [ptrtbl] ...
   21.62 + *
   21.63 + */
   21.64 +
   21.65 +#define	ZBT_LEAF		((1ULL << 63) + 0)
   21.66 +#define	ZBT_HEADER		((1ULL << 63) + 1)
   21.67 +#define	ZBT_MICRO		((1ULL << 63) + 3)
   21.68 +/* any other values are ptrtbl blocks */
   21.69 +
   21.70 +/*
   21.71 + * the embedded pointer table takes up half a block:
   21.72 + * block size / entry size (2^3) / 2
   21.73 + */
   21.74 +#define	ZAP_EMBEDDED_PTRTBL_SHIFT(zap) (FZAP_BLOCK_SHIFT(zap) - 3 - 1)
   21.75 +
   21.76 +/*
   21.77 + * The embedded pointer table starts half-way through the block.  Since
   21.78 + * the pointer table itself is half the block, it starts at (64-bit)
   21.79 + * word number (1<<ZAP_EMBEDDED_PTRTBL_SHIFT(zap)).
   21.80 + */
   21.81 +#define	ZAP_EMBEDDED_PTRTBL_ENT(zap, idx) \
   21.82 +	((uint64_t *)(zap)->zap_f.zap_phys) \
   21.83 +	[(idx) + (1<<ZAP_EMBEDDED_PTRTBL_SHIFT(zap))]
   21.84 +
   21.85 +/*
   21.86 + * TAKE NOTE:
   21.87 + * If zap_phys_t is modified, zap_byteswap() must be modified.
   21.88 + */
   21.89 +typedef struct zap_phys {
   21.90 +	uint64_t zap_block_type;	/* ZBT_HEADER */
   21.91 +	uint64_t zap_magic;		/* ZAP_MAGIC */
   21.92 +
   21.93 +	struct zap_table_phys {
   21.94 +		uint64_t zt_blk;	/* starting block number */
   21.95 +		uint64_t zt_numblks;	/* number of blocks */
   21.96 +		uint64_t zt_shift;	/* bits to index it */
   21.97 +		uint64_t zt_nextblk;	/* next (larger) copy start block */
   21.98 +		uint64_t zt_blks_copied; /* number source blocks copied */
   21.99 +	} zap_ptrtbl;
  21.100 +
  21.101 +	uint64_t zap_freeblk;		/* the next free block */
  21.102 +	uint64_t zap_num_leafs;		/* number of leafs */
  21.103 +	uint64_t zap_num_entries;	/* number of entries */
  21.104 +	uint64_t zap_salt;		/* salt to stir into hash function */
  21.105 +	/*
  21.106 +	 * This structure is followed by padding, and then the embedded
  21.107 +	 * pointer table.  The embedded pointer table takes up second
  21.108 +	 * half of the block.  It is accessed using the
  21.109 +	 * ZAP_EMBEDDED_PTRTBL_ENT() macro.
  21.110 +	 */
  21.111 +} zap_phys_t;
  21.112 +
  21.113 +#endif /* _SYS_ZAP_IMPL_H */
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/tools/libfsimage/zfs/zfs-include/zap_leaf.h	Thu May 01 16:38:56 2008 +0100
    22.3 @@ -0,0 +1,100 @@
    22.4 +/*
    22.5 + *  GRUB  --  GRand Unified Bootloader
    22.6 + *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
    22.7 + *
    22.8 + *  This program is free software; you can redistribute it and/or modify
    22.9 + *  it under the terms of the GNU General Public License as published by
   22.10 + *  the Free Software Foundation; either version 2 of the License, or
   22.11 + *  (at your option) any later version.
   22.12 + *
   22.13 + *  This program is distributed in the hope that it will be useful,
   22.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   22.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   22.16 + *  GNU General Public License for more details.
   22.17 + *
   22.18 + *  You should have received a copy of the GNU General Public License
   22.19 + *  along with this program; if not, write to the Free Software
   22.20 + *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   22.21 + */
   22.22 +/*
   22.23 + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
   22.24 + * Use is subject to license terms.
   22.25 + */
   22.26 +
   22.27 +#ifndef	_SYS_ZAP_LEAF_H
   22.28 +#define	_SYS_ZAP_LEAF_H
   22.29 +
   22.30 +#define	ZAP_LEAF_MAGIC 0x2AB1EAF
   22.31 +
   22.32 +/* chunk size = 24 bytes */
   22.33 +#define	ZAP_LEAF_CHUNKSIZE 24
   22.34 +
   22.35 +/*
   22.36 + * The amount of space within the chunk available for the array is:
   22.37 + * chunk size - space for type (1) - space for next pointer (2)
   22.38 + */
   22.39 +#define	ZAP_LEAF_ARRAY_BYTES (ZAP_LEAF_CHUNKSIZE - 3)
   22.40 +
   22.41 +typedef enum zap_chunk_type {
   22.42 +	ZAP_CHUNK_FREE = 253,
   22.43 +	ZAP_CHUNK_ENTRY = 252,
   22.44 +	ZAP_CHUNK_ARRAY = 251,
   22.45 +	ZAP_CHUNK_TYPE_MAX = 250
   22.46 +} zap_chunk_type_t;
   22.47 +
   22.48 +/*
   22.49 + * TAKE NOTE:
   22.50 + * If zap_leaf_phys_t is modified, zap_leaf_byteswap() must be modified.
   22.51 + */
   22.52 +typedef struct zap_leaf_phys {
   22.53 +	struct zap_leaf_header {
   22.54 +		uint64_t lh_block_type;		/* ZBT_LEAF */
   22.55 +		uint64_t lh_pad1;
   22.56 +		uint64_t lh_prefix;		/* hash prefix of this leaf */
   22.57 +		uint32_t lh_magic;		/* ZAP_LEAF_MAGIC */
   22.58 +		uint16_t lh_nfree;		/* number free chunks */
   22.59 +		uint16_t lh_nentries;		/* number of entries */
   22.60 +		uint16_t lh_prefix_len;		/* num bits used to id this */
   22.61 +
   22.62 +/* above is accessable to zap, below is zap_leaf private */
   22.63 +
   22.64 +		uint16_t lh_freelist;		/* chunk head of free list */
   22.65 +		uint8_t lh_pad2[12];
   22.66 +	} l_hdr; /* 2 24-byte chunks */
   22.67 +
   22.68 +	/*
   22.69 +	 * The header is followed by a hash table with
   22.70 +	 * ZAP_LEAF_HASH_NUMENTRIES(zap) entries.  The hash table is
   22.71 +	 * followed by an array of ZAP_LEAF_NUMCHUNKS(zap)
   22.72 +	 * zap_leaf_chunk structures.  These structures are accessed
   22.73 +	 * with the ZAP_LEAF_CHUNK() macro.
   22.74 +	 */
   22.75 +
   22.76 +	uint16_t l_hash[1];
   22.77 +} zap_leaf_phys_t;
   22.78 +
   22.79 +typedef union zap_leaf_chunk {
   22.80 +	struct zap_leaf_entry {
   22.81 +		uint8_t le_type; 		/* always ZAP_CHUNK_ENTRY */
   22.82 +		uint8_t le_int_size;		/* size of ints */
   22.83 +		uint16_t le_next;		/* next entry in hash chain */
   22.84 +		uint16_t le_name_chunk;		/* first chunk of the name */
   22.85 +		uint16_t le_name_length;	/* bytes in name, incl null */
   22.86 +		uint16_t le_value_chunk;	/* first chunk of the value */
   22.87 +		uint16_t le_value_length;	/* value length in ints */
   22.88 +		uint32_t le_cd;			/* collision differentiator */
   22.89 +		uint64_t le_hash;		/* hash value of the name */
   22.90 +	} l_entry;
   22.91 +	struct zap_leaf_array {
   22.92 +		uint8_t la_type;		/* always ZAP_CHUNK_ARRAY */
   22.93 +		uint8_t la_array[ZAP_LEAF_ARRAY_BYTES];
   22.94 +		uint16_t la_next;		/* next blk or CHAIN_END */
   22.95 +	} l_array;
   22.96 +	struct zap_leaf_free {
   22.97 +		uint8_t lf_type;		/* always ZAP_CHUNK_FREE */
   22.98 +		uint8_t lf_pad[ZAP_LEAF_ARRAY_BYTES];
   22.99 +		uint16_t lf_next;	/* next in free list, or CHAIN_END */
  22.100 +	} l_free;
  22.101 +} zap_leaf_chunk_t;
  22.102 +
  22.103 +#endif /* _SYS_ZAP_LEAF_H */
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/tools/libfsimage/zfs/zfs-include/zfs.h	Thu May 01 16:38:56 2008 +0100
    23.3 @@ -0,0 +1,112 @@
    23.4 +/*
    23.5 + *  GRUB  --  GRand Unified Bootloader
    23.6 + *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
    23.7 + *
    23.8 + *  This program is free software; you can redistribute it and/or modify
    23.9 + *  it under the terms of the GNU General Public License as published by
   23.10 + *  the Free Software Foundation; either version 2 of the License, or
   23.11 + *  (at your option) any later version.
   23.12 + *
   23.13 + *  This program is distributed in the hope that it will be useful,
   23.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   23.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   23.16 + *  GNU General Public License for more details.
   23.17 + *
   23.18 + *  You should have received a copy of the GNU General Public License
   23.19 + *  along with this program; if not, write to the Free Software
   23.20 + *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   23.21 + */
   23.22 +/*
   23.23 + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
   23.24 + * Use is subject to license terms.
   23.25 + */
   23.26 +
   23.27 +#ifndef	_SYS_FS_ZFS_H
   23.28 +#define	_SYS_FS_ZFS_H
   23.29 +
   23.30 +
   23.31 +/*
   23.32 + * On-disk version number.
   23.33 + */
   23.34 +#define	SPA_VERSION_1			1ULL
   23.35 +#define	SPA_VERSION_2			2ULL
   23.36 +#define	SPA_VERSION_3			3ULL
   23.37 +#define	SPA_VERSION_4			4ULL
   23.38 +#define	SPA_VERSION_5			5ULL
   23.39 +#define	SPA_VERSION_6			6ULL
   23.40 +#define	SPA_VERSION_7			7ULL
   23.41 +#define	SPA_VERSION_8			8ULL
   23.42 +#define	SPA_VERSION_9			9ULL
   23.43 +#define	SPA_VERSION_10			10ULL
   23.44 +#define	SPA_VERSION			SPA_VERSION_10
   23.45 +
   23.46 +/*
   23.47 + * The following are configuration names used in the nvlist describing a pool's
   23.48 + * configuration.
   23.49 + */
   23.50 +#define	ZPOOL_CONFIG_VERSION		"version"
   23.51 +#define	ZPOOL_CONFIG_POOL_NAME		"name"
   23.52 +#define	ZPOOL_CONFIG_POOL_STATE		"state"
   23.53 +#define	ZPOOL_CONFIG_POOL_TXG		"txg"
   23.54 +#define	ZPOOL_CONFIG_POOL_GUID		"pool_guid"
   23.55 +#define	ZPOOL_CONFIG_CREATE_TXG		"create_txg"
   23.56 +#define	ZPOOL_CONFIG_TOP_GUID		"top_guid"
   23.57 +#define	ZPOOL_CONFIG_VDEV_TREE		"vdev_tree"
   23.58 +#define	ZPOOL_CONFIG_TYPE		"type"
   23.59 +#define	ZPOOL_CONFIG_CHILDREN		"children"
   23.60 +#define	ZPOOL_CONFIG_ID			"id"
   23.61 +#define	ZPOOL_CONFIG_GUID		"guid"
   23.62 +#define	ZPOOL_CONFIG_PATH		"path"
   23.63 +#define	ZPOOL_CONFIG_DEVID		"devid"
   23.64 +#define	ZPOOL_CONFIG_METASLAB_ARRAY	"metaslab_array"
   23.65 +#define	ZPOOL_CONFIG_METASLAB_SHIFT	"metaslab_shift"
   23.66 +#define	ZPOOL_CONFIG_ASHIFT		"ashift"
   23.67 +#define	ZPOOL_CONFIG_ASIZE		"asize"
   23.68 +#define	ZPOOL_CONFIG_DTL		"DTL"
   23.69 +#define	ZPOOL_CONFIG_STATS		"stats"
   23.70 +#define	ZPOOL_CONFIG_WHOLE_DISK		"whole_disk"
   23.71 +#define	ZPOOL_CONFIG_ERRCOUNT		"error_count"
   23.72 +#define	ZPOOL_CONFIG_NOT_PRESENT	"not_present"
   23.73 +#define	ZPOOL_CONFIG_SPARES		"spares"
   23.74 +#define	ZPOOL_CONFIG_IS_SPARE		"is_spare"
   23.75 +#define	ZPOOL_CONFIG_NPARITY		"nparity"
   23.76 +#define	ZPOOL_CONFIG_PHYS_PATH		"phys_path"
   23.77 +#define	ZPOOL_CONFIG_L2CACHE		"l2cache"
   23.78 +/*
   23.79 + * The persistent vdev state is stored as separate values rather than a single
   23.80 + * 'vdev_state' entry.  This is because a device can be in multiple states, such
   23.81 + * as offline and degraded.
   23.82 + */
   23.83 +#define	ZPOOL_CONFIG_OFFLINE		"offline"
   23.84 +#define	ZPOOL_CONFIG_FAULTED		"faulted"
   23.85 +#define	ZPOOL_CONFIG_DEGRADED		"degraded"
   23.86 +#define	ZPOOL_CONFIG_REMOVED		"removed"
   23.87 +
   23.88 +#define	VDEV_TYPE_ROOT			"root"
   23.89 +#define	VDEV_TYPE_MIRROR		"mirror"
   23.90 +#define	VDEV_TYPE_REPLACING		"replacing"
   23.91 +#define	VDEV_TYPE_RAIDZ			"raidz"
   23.92 +#define	VDEV_TYPE_DISK			"disk"
   23.93 +#define	VDEV_TYPE_FILE			"file"
   23.94 +#define	VDEV_TYPE_MISSING		"missing"
   23.95 +#define	VDEV_TYPE_SPARE			"spare"
   23.96 +#define	VDEV_TYPE_L2CACHE		"l2cache"
   23.97 +
   23.98 +/*
   23.99 + * pool state.  The following states are written to disk as part of the normal
  23.100 + * SPA lifecycle: ACTIVE, EXPORTED, DESTROYED, SPARE, L2CACHE.  The remaining
  23.101 + * states are software abstractions used at various levels to communicate pool
  23.102 + * state.
  23.103 + */
  23.104 +typedef enum pool_state {
  23.105 +	POOL_STATE_ACTIVE = 0,		/* In active use		*/
  23.106 +	POOL_STATE_EXPORTED,		/* Explicitly exported		*/
  23.107 +	POOL_STATE_DESTROYED,		/* Explicitly destroyed		*/
  23.108 +	POOL_STATE_SPARE,		/* Reserved for hot spare use	*/
  23.109 +	POOL_STATE_L2CACHE,		/* Level 2 ARC device		*/
  23.110 +	POOL_STATE_UNINITIALIZED,	/* Internal spa_t state		*/
  23.111 +	POOL_STATE_UNAVAIL,		/* Internal libzfs state	*/
  23.112 +	POOL_STATE_POTENTIALLY_ACTIVE	/* Internal libzfs state	*/
  23.113 +} pool_state_t;
  23.114 +
  23.115 +#endif	/* _SYS_FS_ZFS_H */
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/tools/libfsimage/zfs/zfs-include/zfs_acl.h	Thu May 01 16:38:56 2008 +0100
    24.3 @@ -0,0 +1,60 @@
    24.4 +/*
    24.5 + *  GRUB  --  GRand Unified Bootloader
    24.6 + *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
    24.7 + *
    24.8 + *  This program is free software; you can redistribute it and/or modify
    24.9 + *  it under the terms of the GNU General Public License as published by
   24.10 + *  the Free Software Foundation; either version 2 of the License, or
   24.11 + *  (at your option) any later version.
   24.12 + *
   24.13 + *  This program is distributed in the hope that it will be useful,
   24.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   24.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   24.16 + *  GNU General Public License for more details.
   24.17 + *
   24.18 + *  You should have received a copy of the GNU General Public License
   24.19 + *  along with this program; if not, write to the Free Software
   24.20 + *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   24.21 + */
   24.22 +/*
   24.23 + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
   24.24 + * Use is subject to license terms.
   24.25 + */
   24.26 +
   24.27 +#ifndef	_SYS_FS_ZFS_ACL_H
   24.28 +#define	_SYS_FS_ZFS_ACL_H
   24.29 +
   24.30 +#ifndef _UID_T
   24.31 +#define	_UID_T
   24.32 +typedef	unsigned int uid_t;			/* UID type */
   24.33 +#endif /* _UID_T */
   24.34 +
   24.35 +typedef struct zfs_oldace {
   24.36 +	uint32_t	z_fuid;		/* "who" */
   24.37 +	uint32_t	z_access_mask;  /* access mask */
   24.38 +	uint16_t	z_flags;	/* flags, i.e inheritance */
   24.39 +	uint16_t	z_type;		/* type of entry allow/deny */
   24.40 +} zfs_oldace_t;
   24.41 +
   24.42 +#define	ACE_SLOT_CNT	6
   24.43 +
   24.44 +typedef struct zfs_znode_acl_v0 {
   24.45 +	uint64_t	z_acl_extern_obj;	  /* ext acl pieces */
   24.46 +	uint32_t	z_acl_count;		  /* Number of ACEs */
   24.47 +	uint16_t	z_acl_version;		  /* acl version */
   24.48 +	uint16_t	z_acl_pad;		  /* pad */
   24.49 +	zfs_oldace_t	z_ace_data[ACE_SLOT_CNT]; /* 6 standard ACEs */
   24.50 +} zfs_znode_acl_v0_t;
   24.51 +
   24.52 +#define	ZFS_ACE_SPACE	(sizeof (zfs_oldace_t) * ACE_SLOT_CNT)
   24.53 +
   24.54 +typedef struct zfs_znode_acl {
   24.55 +	uint64_t	z_acl_extern_obj;	  /* ext acl pieces */
   24.56 +	uint32_t	z_acl_size;		  /* Number of bytes in ACL */
   24.57 +	uint16_t	z_acl_version;		  /* acl version */
   24.58 +	uint16_t	z_acl_count;		  /* ace count */
   24.59 +	uint8_t		z_ace_data[ZFS_ACE_SPACE]; /* space for embedded ACEs */
   24.60 +} zfs_znode_acl_t;
   24.61 +
   24.62 +
   24.63 +#endif	/* _SYS_FS_ZFS_ACL_H */
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/tools/libfsimage/zfs/zfs-include/zfs_znode.h	Thu May 01 16:38:56 2008 +0100
    25.3 @@ -0,0 +1,68 @@
    25.4 +/*
    25.5 + *  GRUB  --  GRand Unified Bootloader
    25.6 + *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
    25.7 + *
    25.8 + *  This program is free software; you can redistribute it and/or modify
    25.9 + *  it under the terms of the GNU General Public License as published by
   25.10 + *  the Free Software Foundation; either version 2 of the License, or
   25.11 + *  (at your option) any later version.
   25.12 + *
   25.13 + *  This program is distributed in the hope that it will be useful,
   25.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   25.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   25.16 + *  GNU General Public License for more details.
   25.17 + *
   25.18 + *  You should have received a copy of the GNU General Public License
   25.19 + *  along with this program; if not, write to the Free Software
   25.20 + *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   25.21 + */
   25.22 +/*
   25.23 + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
   25.24 + * Use is subject to license terms.
   25.25 + */
   25.26 +
   25.27 +#ifndef	_SYS_FS_ZFS_ZNODE_H
   25.28 +#define	_SYS_FS_ZFS_ZNODE_H
   25.29 +
   25.30 +#define	MASTER_NODE_OBJ	1
   25.31 +#define	ZFS_ROOT_OBJ		"ROOT"
   25.32 +#define	ZPL_VERSION_STR		"VERSION"
   25.33 +
   25.34 +#define	ZPL_VERSION		3ULL
   25.35 +
   25.36 +#define	ZFS_DIRENT_OBJ(de) BF64_GET(de, 0, 48)
   25.37 +
   25.38 +/*
   25.39 + * This is the persistent portion of the znode.  It is stored
   25.40 + * in the "bonus buffer" of the file.  Short symbolic links
   25.41 + * are also stored in the bonus buffer.
   25.42 + */
   25.43 +typedef struct znode_phys {
   25.44 +	uint64_t zp_atime[2];		/*  0 - last file access time */
   25.45 +	uint64_t zp_mtime[2];		/* 16 - last file modification time */
   25.46 +	uint64_t zp_ctime[2];		/* 32 - last file change time */
   25.47 +	uint64_t zp_crtime[2];		/* 48 - creation time */
   25.48 +	uint64_t zp_gen;		/* 64 - generation (txg of creation) */
   25.49 +	uint64_t zp_mode;		/* 72 - file mode bits */
   25.50 +	uint64_t zp_size;		/* 80 - size of file */
   25.51 +	uint64_t zp_parent;		/* 88 - directory parent (`..') */
   25.52 +	uint64_t zp_links;		/* 96 - number of links to file */
   25.53 +	uint64_t zp_xattr;		/* 104 - DMU object for xattrs */
   25.54 +	uint64_t zp_rdev;		/* 112 - dev_t for VBLK & VCHR files */
   25.55 +	uint64_t zp_flags;		/* 120 - persistent flags */
   25.56 +	uint64_t zp_uid;		/* 128 - file owner */
   25.57 +	uint64_t zp_gid;		/* 136 - owning group */
   25.58 +	uint64_t zp_pad[4];		/* 144 - future */
   25.59 +	zfs_znode_acl_t zp_acl;		/* 176 - 263 ACL */
   25.60 +	/*
   25.61 +	 * Data may pad out any remaining bytes in the znode buffer, eg:
   25.62 +	 *
   25.63 +	 * |<---------------------- dnode_phys (512) ------------------------>|
   25.64 +	 * |<-- dnode (192) --->|<----------- "bonus" buffer (320) ---------->|
   25.65 +	 *			|<---- znode (264) ---->|<---- data (56) ---->|
   25.66 +	 *
   25.67 +	 * At present, we only use this space to store symbolic links.
   25.68 +	 */
   25.69 +} znode_phys_t;
   25.70 +
   25.71 +#endif	/* _SYS_FS_ZFS_ZNODE_H */
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/tools/libfsimage/zfs/zfs-include/zil.h	Thu May 01 16:38:56 2008 +0100
    26.3 @@ -0,0 +1,51 @@
    26.4 +/*
    26.5 + *  GRUB  --  GRand Unified Bootloader
    26.6 + *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
    26.7 + *
    26.8 + *  This program is free software; you can redistribute it and/or modify
    26.9 + *  it under the terms of the GNU General Public License as published by
   26.10 + *  the Free Software Foundation; either version 2 of the License, or
   26.11 + *  (at your option) any later version.
   26.12 + *
   26.13 + *  This program is distributed in the hope that it will be useful,
   26.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   26.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   26.16 + *  GNU General Public License for more details.
   26.17 + *
   26.18 + *  You should have received a copy of the GNU General Public License
   26.19 + *  along with this program; if not, write to the Free Software
   26.20 + *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   26.21 + */
   26.22 +/*
   26.23 + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
   26.24 + * Use is subject to license terms.
   26.25 + */
   26.26 +
   26.27 +#ifndef	_SYS_ZIL_H
   26.28 +#define	_SYS_ZIL_H
   26.29 +
   26.30 +/*
   26.31 + * Intent log format:
   26.32 + *
   26.33 + * Each objset has its own intent log.  The log header (zil_header_t)
   26.34 + * for objset N's intent log is kept in the Nth object of the SPA's
   26.35 + * intent_log objset.  The log header points to a chain of log blocks,
   26.36 + * each of which contains log records (i.e., transactions) followed by
   26.37 + * a log block trailer (zil_trailer_t).  The format of a log record
   26.38 + * depends on the record (or transaction) type, but all records begin
   26.39 + * with a common structure that defines the type, length, and txg.
   26.40 + */
   26.41 +
   26.42 +/*
   26.43 + * Intent log header - this on disk structure holds fields to manage
   26.44 + * the log.  All fields are 64 bit to easily handle cross architectures.
   26.45 + */
   26.46 +typedef struct zil_header {
   26.47 +	uint64_t zh_claim_txg;	/* txg in which log blocks were claimed */
   26.48 +	uint64_t zh_replay_seq;	/* highest replayed sequence number */
   26.49 +	blkptr_t zh_log;	/* log chain */
   26.50 +	uint64_t zh_claim_seq;	/* highest claimed sequence number */
   26.51 +	uint64_t zh_pad[5];
   26.52 +} zil_header_t;
   26.53 +
   26.54 +#endif	/* _SYS_ZIL_H */
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/tools/libfsimage/zfs/zfs-include/zio.h	Thu May 01 16:38:56 2008 +0100
    27.3 @@ -0,0 +1,81 @@
    27.4 +/*
    27.5 + *  GRUB  --  GRand Unified Bootloader
    27.6 + *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
    27.7 + *
    27.8 + *  This program is free software; you can redistribute it and/or modify
    27.9 + *  it under the terms of the GNU General Public License as published by
   27.10 + *  the Free Software Foundation; either version 2 of the License, or
   27.11 + *  (at your option) any later version.
   27.12 + *
   27.13 + *  This program is distributed in the hope that it will be useful,
   27.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   27.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   27.16 + *  GNU General Public License for more details.
   27.17 + *
   27.18 + *  You should have received a copy of the GNU General Public License
   27.19 + *  along with this program; if not, write to the Free Software
   27.20 + *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   27.21 + */
   27.22 +/*
   27.23 + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
   27.24 + * Use is subject to license terms.
   27.25 + */
   27.26 +
   27.27 +#ifndef _ZIO_H
   27.28 +#define	_ZIO_H
   27.29 +
   27.30 +#define	ZBT_MAGIC	0x210da7ab10c7a11ULL	/* zio data bloc tail */
   27.31 +
   27.32 +typedef struct zio_block_tail {
   27.33 +	uint64_t	zbt_magic;	/* for validation, endianness	*/
   27.34 +	zio_cksum_t	zbt_cksum;	/* 256-bit checksum		*/
   27.35 +} zio_block_tail_t;
   27.36 +
   27.37 +/*
   27.38 + * Gang block headers are self-checksumming and contain an array
   27.39 + * of block pointers.
   27.40 + */
   27.41 +#define	SPA_GANGBLOCKSIZE	SPA_MINBLOCKSIZE
   27.42 +#define	SPA_GBH_NBLKPTRS	((SPA_GANGBLOCKSIZE - \
   27.43 +	sizeof (zio_block_tail_t)) / sizeof (blkptr_t))
   27.44 +#define	SPA_GBH_FILLER		((SPA_GANGBLOCKSIZE - \
   27.45 +	sizeof (zio_block_tail_t) - \
   27.46 +	(SPA_GBH_NBLKPTRS * sizeof (blkptr_t))) /\
   27.47 +	sizeof (uint64_t))
   27.48 +
   27.49 +#define	ZIO_GET_IOSIZE(zio)	\
   27.50 +	(BP_IS_GANG((zio)->io_bp) ? \
   27.51 +	SPA_GANGBLOCKSIZE : BP_GET_PSIZE((zio)->io_bp))
   27.52 +
   27.53 +typedef struct zio_gbh {
   27.54 +	blkptr_t		zg_blkptr[SPA_GBH_NBLKPTRS];
   27.55 +	uint64_t		zg_filler[SPA_GBH_FILLER];
   27.56 +	zio_block_tail_t	zg_tail;
   27.57 +} zio_gbh_phys_t;
   27.58 +
   27.59 +enum zio_checksum {
   27.60 +	ZIO_CHECKSUM_INHERIT = 0,
   27.61 +	ZIO_CHECKSUM_ON,
   27.62 +	ZIO_CHECKSUM_OFF,
   27.63 +	ZIO_CHECKSUM_LABEL,
   27.64 +	ZIO_CHECKSUM_GANG_HEADER,
   27.65 +	ZIO_CHECKSUM_ZILOG,
   27.66 +	ZIO_CHECKSUM_FLETCHER_2,
   27.67 +	ZIO_CHECKSUM_FLETCHER_4,
   27.68 +	ZIO_CHECKSUM_SHA256,
   27.69 +	ZIO_CHECKSUM_FUNCTIONS
   27.70 +};
   27.71 +
   27.72 +#define	ZIO_CHECKSUM_ON_VALUE	ZIO_CHECKSUM_FLETCHER_2
   27.73 +#define	ZIO_CHECKSUM_DEFAULT	ZIO_CHECKSUM_ON
   27.74 +
   27.75 +enum zio_compress {
   27.76 +	ZIO_COMPRESS_INHERIT = 0,
   27.77 +	ZIO_COMPRESS_ON,
   27.78 +	ZIO_COMPRESS_OFF,
   27.79 +	ZIO_COMPRESS_LZJB,
   27.80 +	ZIO_COMPRESS_EMPTY,
   27.81 +	ZIO_COMPRESS_FUNCTIONS
   27.82 +};
   27.83 +
   27.84 +#endif	/* _ZIO_H */
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/tools/libfsimage/zfs/zfs-include/zio_checksum.h	Thu May 01 16:38:56 2008 +0100
    28.3 @@ -0,0 +1,42 @@
    28.4 +/*
    28.5 + *  GRUB  --  GRand Unified Bootloader
    28.6 + *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
    28.7 + *
    28.8 + *  This program is free software; you can redistribute it and/or modify
    28.9 + *  it under the terms of the GNU General Public License as published by
   28.10 + *  the Free Software Foundation; either version 2 of the License, or
   28.11 + *  (at your option) any later version.
   28.12 + *
   28.13 + *  This program is distributed in the hope that it will be useful,
   28.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   28.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   28.16 + *  GNU General Public License for more details.
   28.17 + *
   28.18 + *  You should have received a copy of the GNU General Public License
   28.19 + *  along with this program; if not, write to the Free Software
   28.20 + *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   28.21 + */
   28.22 +/*
   28.23 + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
   28.24 + * Use is subject to license terms.
   28.25 + */
   28.26 +
   28.27 +#ifndef _SYS_ZIO_CHECKSUM_H
   28.28 +#define	_SYS_ZIO_CHECKSUM_H
   28.29 +
   28.30 +/*
   28.31 + * Signature for checksum functions.
   28.32 + */
   28.33 +typedef void zio_checksum_t(const void *data, uint64_t size, zio_cksum_t *zcp);
   28.34 +
   28.35 +/*
   28.36 + * Information about each checksum function.
   28.37 + */
   28.38 +typedef struct zio_checksum_info {
   28.39 +	zio_checksum_t	*ci_func[2]; /* checksum function for each byteorder */
   28.40 +	int		ci_correctable;	/* number of correctable bits	*/
   28.41 +	int		ci_zbt;		/* uses zio block tail?	*/
   28.42 +	char		*ci_name;	/* descriptive name */
   28.43 +} zio_checksum_info_t;
   28.44 +
   28.45 +#endif	/* _SYS_ZIO_CHECKSUM_H */
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/tools/libfsimage/zfs/zfs_fletcher.c	Thu May 01 16:38:56 2008 +0100
    29.3 @@ -0,0 +1,93 @@
    29.4 +/*
    29.5 + *  GRUB  --  GRand Unified Bootloader
    29.6 + *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
    29.7 + *
    29.8 + *  This program is free software; you can redistribute it and/or modify
    29.9 + *  it under the terms of the GNU General Public License as published by
   29.10 + *  the Free Software Foundation; either version 2 of the License, or
   29.11 + *  (at your option) any later version.
   29.12 + *
   29.13 + *  This program is distributed in the hope that it will be useful,
   29.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   29.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   29.16 + *  GNU General Public License for more details.
   29.17 + *
   29.18 + *  You should have received a copy of the GNU General Public License
   29.19 + *  along with this program; if not, write to the Free Software
   29.20 + *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   29.21 + */
   29.22 +/*
   29.23 + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
   29.24 + * Use is subject to license terms.
   29.25 + */
   29.26 +
   29.27 +#include "fsys_zfs.h"
   29.28 +
   29.29 +
   29.30 +void
   29.31 +fletcher_2_native(const void *buf, uint64_t size, zio_cksum_t *zcp)
   29.32 +{
   29.33 +	const uint64_t *ip = buf;
   29.34 +	const uint64_t *ipend = ip + (size / sizeof (uint64_t));
   29.35 +	uint64_t a0, b0, a1, b1;
   29.36 +
   29.37 +	for (a0 = b0 = a1 = b1 = 0; ip < ipend; ip += 2) {
   29.38 +		a0 += ip[0];
   29.39 +		a1 += ip[1];
   29.40 +		b0 += a0;
   29.41 +		b1 += a1;
   29.42 +	}
   29.43 +
   29.44 +	ZIO_SET_CHECKSUM(zcp, a0, a1, b0, b1);
   29.45 +}
   29.46 +
   29.47 +void
   29.48 +fletcher_2_byteswap(const void *buf, uint64_t size, zio_cksum_t *zcp)
   29.49 +{
   29.50 +	const uint64_t *ip = buf;
   29.51 +	const uint64_t *ipend = ip + (size / sizeof (uint64_t));
   29.52 +	uint64_t a0, b0, a1, b1;
   29.53 +
   29.54 +	for (a0 = b0 = a1 = b1 = 0; ip < ipend; ip += 2) {
   29.55 +		a0 += BSWAP_64(ip[0]);
   29.56 +		a1 += BSWAP_64(ip[1]);
   29.57 +		b0 += a0;
   29.58 +		b1 += a1;
   29.59 +	}
   29.60 +
   29.61 +	ZIO_SET_CHECKSUM(zcp, a0, a1, b0, b1);
   29.62 +}
   29.63 +
   29.64 +void
   29.65 +fletcher_4_native(const void *buf, uint64_t size, zio_cksum_t *zcp)
   29.66 +{
   29.67 +	const uint32_t *ip = buf;
   29.68 +	const uint32_t *ipend = ip + (size / sizeof (uint32_t));
   29.69 +	uint64_t a, b, c, d;
   29.70 +
   29.71 +	for (a = b = c = d = 0; ip < ipend; ip++) {
   29.72 +		a += ip[0];
   29.73 +		b += a;
   29.74 +		c += b;
   29.75 +		d += c;
   29.76 +	}
   29.77 +
   29.78 +	ZIO_SET_CHECKSUM(zcp, a, b, c, d);
   29.79 +}
   29.80 +
   29.81 +void
   29.82 +fletcher_4_byteswap(const void *buf, uint64_t size, zio_cksum_t *zcp)
   29.83 +{
   29.84 +	const uint32_t *ip = buf;
   29.85 +	const uint32_t *ipend = ip + (size / sizeof (uint32_t));
   29.86 +	uint64_t a, b, c, d;
   29.87 +
   29.88 +	for (a = b = c = d = 0; ip < ipend; ip++) {
   29.89 +		a += BSWAP_32(ip[0]);
   29.90 +		b += a;
   29.91 +		c += b;
   29.92 +		d += c;
   29.93 +	}
   29.94 +
   29.95 +	ZIO_SET_CHECKSUM(zcp, a, b, c, d);
   29.96 +}
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/tools/libfsimage/zfs/zfs_lzjb.c	Thu May 01 16:38:56 2008 +0100
    30.3 @@ -0,0 +1,60 @@
    30.4 +/*
    30.5 + *  GRUB  --  GRand Unified Bootloader
    30.6 + *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
    30.7 + *
    30.8 + *  This program is free software; you can redistribute it and/or modify
    30.9 + *  it under the terms of the GNU General Public License as published by
   30.10 + *  the Free Software Foundation; either version 2 of the License, or
   30.11 + *  (at your option) any later version.
   30.12 + *
   30.13 + *  This program is distributed in the hope that it will be useful,
   30.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   30.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   30.16 + *  GNU General Public License for more details.
   30.17 + *
   30.18 + *  You should have received a copy of the GNU General Public License
   30.19 + *  along with this program; if not, write to the Free Software
   30.20 + *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   30.21 + */
   30.22 +/*
   30.23 + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
   30.24 + * Use is subject to license terms.
   30.25 + */
   30.26 +
   30.27 +#include "fsys_zfs.h"
   30.28 +
   30.29 +#define	MATCH_BITS	6
   30.30 +#define	MATCH_MIN	3
   30.31 +#define	OFFSET_MASK	((1 << (16 - MATCH_BITS)) - 1)
   30.32 +
   30.33 +
   30.34 +/*ARGSUSED*/
   30.35 +int
   30.36 +lzjb_decompress(void *s_start, void *d_start, size_t s_len, size_t d_len)
   30.37 +{
   30.38 +	unsigned char *src = s_start;
   30.39 +	unsigned char *dst = d_start;
   30.40 +	unsigned char *d_end = (unsigned char *)d_start + d_len;
   30.41 +	unsigned char *cpy;
   30.42 +	unsigned char copymap = '\0';
   30.43 +	int copymask = 1 << (NBBY - 1);
   30.44 +
   30.45 +	while (dst < d_end) {
   30.46 +		if ((copymask <<= 1) == (1 << NBBY)) {
   30.47 +			copymask = 1;
   30.48 +			copymap = *src++;
   30.49 +		}
   30.50 +		if (copymap & (unsigned char)copymask) {
   30.51 +			int mlen = (src[0] >> (NBBY - MATCH_BITS)) + MATCH_MIN;
   30.52 +			int offset = ((src[0] << NBBY) | src[1]) & OFFSET_MASK;
   30.53 +			src += 2;
   30.54 +			if ((cpy = dst - offset) < (unsigned char *)d_start)
   30.55 +				return (-1);
   30.56 +			while (--mlen >= 0 && dst < d_end)
   30.57 +				*dst++ = *cpy++;
   30.58 +		} else {
   30.59 +			*dst++ = *src++;
   30.60 +		}
   30.61 +	}
   30.62 +	return (0);
   30.63 +}
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/tools/libfsimage/zfs/zfs_sha256.c	Thu May 01 16:38:56 2008 +0100
    31.3 @@ -0,0 +1,124 @@
    31.4 +/*
    31.5 + *  GRUB  --  GRand Unified Bootloader
    31.6 + *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
    31.7 + *
    31.8 + *  This program is free software; you can redistribute it and/or modify
    31.9 + *  it under the terms of the GNU General Public License as published by
   31.10 + *  the Free Software Foundation; either version 2 of the License, or
   31.11 + *  (at your option) any later version.
   31.12 + *
   31.13 + *  This program is distributed in the hope that it will be useful,
   31.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   31.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   31.16 + *  GNU General Public License for more details.
   31.17 + *
   31.18 + *  You should have received a copy of the GNU General Public License
   31.19 + *  along with this program; if not, write to the Free Software
   31.20 + *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   31.21 + */
   31.22 +/*
   31.23 + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
   31.24 + * Use is subject to license terms.
   31.25 + */
   31.26 +
   31.27 +#include "fsys_zfs.h"
   31.28 +
   31.29 +/*
   31.30 + * SHA-256 checksum, as specified in FIPS 180-2, available at:
   31.31 + * http://csrc.nist.gov/cryptval
   31.32 + *
   31.33 + * This is a very compact implementation of SHA-256.
   31.34 + * It is designed to be simple and portable, not to be fast.
   31.35 + */
   31.36 +
   31.37 +/*
   31.38 + * The literal definitions according to FIPS180-2 would be:
   31.39 + *
   31.40 + * 	Ch(x, y, z)     (((x) & (y)) ^ ((~(x)) & (z)))
   31.41 + * 	Maj(x, y, z)    (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
   31.42 + *
   31.43 + * We use logical equivalents which require one less op.
   31.44 + */
   31.45 +#define	Ch(x, y, z)	((z) ^ ((x) & ((y) ^ (z))))
   31.46 +#define	Maj(x, y, z)	(((x) & (y)) ^ ((z) & ((x) ^ (y))))
   31.47 +#define	Rot32(x, s)	(((x) >> s) | ((x) << (32 - s)))
   31.48 +#define	SIGMA0(x)	(Rot32(x, 2) ^ Rot32(x, 13) ^ Rot32(x, 22))
   31.49 +#define	SIGMA1(x)	(Rot32(x, 6) ^ Rot32(x, 11) ^ Rot32(x, 25))
   31.50 +#define	sigma0(x)	(Rot32(x, 7) ^ Rot32(x, 18) ^ ((x) >> 3))
   31.51 +#define	sigma1(x)	(Rot32(x, 17) ^ Rot32(x, 19) ^ ((x) >> 10))
   31.52 +
   31.53 +static const uint32_t SHA256_K[64] = {
   31.54 +	0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
   31.55 +	0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
   31.56 +	0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
   31.57 +	0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
   31.58 +	0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
   31.59 +	0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
   31.60 +	0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
   31.61 +	0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
   31.62 +	0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
   31.63 +	0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
   31.64 +	0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
   31.65 +	0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
   31.66 +	0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
   31.67 +	0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
   31.68 +	0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
   31.69 +	0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
   31.70 +};
   31.71 +
   31.72 +static void
   31.73 +SHA256Transform(uint32_t *H, const uint8_t *cp)
   31.74 +{
   31.75 +	uint32_t a, b, c, d, e, f, g, h, t, T1, T2, W[64];
   31.76 +
   31.77 +	for (t = 0; t < 16; t++, cp += 4)
   31.78 +		W[t] = (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | cp[3];
   31.79 +
   31.80 +	for (t = 16; t < 64; t++)
   31.81 +		W[t] = sigma1(W[t - 2]) + W[t - 7] +
   31.82 +		    sigma0(W[t - 15]) + W[t - 16];
   31.83 +
   31.84 +	a = H[0]; b = H[1]; c = H[2]; d = H[3];
   31.85 +	e = H[4]; f = H[5]; g = H[6]; h = H[7];
   31.86 +
   31.87 +	for (t = 0; t < 64; t++) {
   31.88 +		T1 = h + SIGMA1(e) + Ch(e, f, g) + SHA256_K[t] + W[t];
   31.89 +		T2 = SIGMA0(a) + Maj(a, b, c);
   31.90 +		h = g; g = f; f = e; e = d + T1;
   31.91 +		d = c; c = b; b = a; a = T1 + T2;
   31.92 +	}
   31.93 +
   31.94 +	H[0] += a; H[1] += b; H[2] += c; H[3] += d;
   31.95 +	H[4] += e; H[5] += f; H[6] += g; H[7] += h;
   31.96 +}
   31.97 +
   31.98 +void
   31.99 +zio_checksum_SHA256(const void *buf, uint64_t size, zio_cksum_t *zcp)
  31.100 +{
  31.101 +	uint32_t H[8] = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
  31.102 +	    0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 };
  31.103 +	uint8_t pad[128];
  31.104 +	int padsize = size & 63;
  31.105 +	int i;
  31.106 +
  31.107 +	for (i = 0; i < size - padsize; i += 64)
  31.108 +		SHA256Transform(H, (uint8_t *)buf + i);
  31.109 +
  31.110 +	for (i = 0; i < padsize; i++)
  31.111 +		pad[i] = ((uint8_t *)buf)[i];
  31.112 +
  31.113 +	for (pad[padsize++] = 0x80; (padsize & 63) != 56; padsize++)
  31.114 +		pad[padsize] = 0;
  31.115 +
  31.116 +	for (i = 0; i < 8; i++)
  31.117 +		pad[padsize++] = (size << 3) >> (56 - 8 * i);
  31.118 +
  31.119 +	for (i = 0; i < padsize; i += 64)
  31.120 +		SHA256Transform(H, pad + i);
  31.121 +
  31.122 +	ZIO_SET_CHECKSUM(zcp,
  31.123 +	    (uint64_t)H[0] << 32 | H[1],
  31.124 +	    (uint64_t)H[2] << 32 | H[3],
  31.125 +	    (uint64_t)H[4] << 32 | H[5],
  31.126 +	    (uint64_t)H[6] << 32 | H[7]);
  31.127 +}
    32.1 --- a/tools/pygrub/src/fsimage/fsimage.c	Thu May 01 16:37:46 2008 +0100
    32.2 +++ b/tools/pygrub/src/fsimage/fsimage.c	Thu May 01 16:38:56 2008 +0100
    32.3 @@ -17,7 +17,7 @@
    32.4   * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    32.5   * DEALINGS IN THE SOFTWARE.
    32.6   *
    32.7 - * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
    32.8 + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
    32.9   * Use is subject to license terms.
   32.10   */
   32.11  
   32.12 @@ -281,6 +281,22 @@ fsimage_open(PyObject *o, PyObject *args
   32.13  	return (PyObject *)fs;
   32.14  }
   32.15  
   32.16 +static PyObject *
   32.17 +fsimage_getbootstring(PyObject *o, PyObject *args)
   32.18 +{
   32.19 +	PyObject *fs;
   32.20 +	char	*bootstring;
   32.21 +	fsi_t	*fsi;
   32.22 +
   32.23 +	if (!PyArg_ParseTuple(args, "O", &fs))
   32.24 +		return (NULL);
   32.25 +
   32.26 +	fsi = ((fsimage_fs_t *)fs)->fs;
   32.27 +	bootstring = fsi_fs_bootstring(fsi);
   32.28 +
   32.29 +	return Py_BuildValue("s", bootstring);
   32.30 +}
   32.31 +
   32.32  PyDoc_STRVAR(fsimage_open__doc__,
   32.33      "open(name, [offset=off]) - Open the given file as a filesystem image.\n"
   32.34      "\n"
   32.35 @@ -288,9 +304,15 @@ PyDoc_STRVAR(fsimage_open__doc__,
   32.36      "offset - offset of file system within file image.\n"
   32.37      "options - mount options string.\n");
   32.38  
   32.39 +PyDoc_STRVAR(fsimage_getbootstring__doc__,
   32.40 +    "getbootstring(fs) - Return the boot string needed for this file system "
   32.41 +    "or NULL if none is needed.\n");
   32.42 +
   32.43  static struct PyMethodDef fsimage_module_methods[] = {
   32.44  	{ "open", (PyCFunction)fsimage_open,
   32.45  	    METH_VARARGS|METH_KEYWORDS, fsimage_open__doc__ },
   32.46 +	{ "getbootstring", (PyCFunction)fsimage_getbootstring,
   32.47 +	    METH_VARARGS, fsimage_getbootstring__doc__ },
   32.48  	{ NULL, NULL, 0, NULL }
   32.49  };
   32.50  
    33.1 --- a/tools/pygrub/src/pygrub	Thu May 01 16:37:46 2008 +0100
    33.2 +++ b/tools/pygrub/src/pygrub	Thu May 01 16:38:56 2008 +0100
    33.3 @@ -646,7 +646,13 @@ if __name__ == "__main__":
    33.4          print "  args: %s" % chosencfg["args"]
    33.5          sys.exit(0)
    33.6  
    33.7 -    fs = fsimage.open(file, get_fs_offset(file))
    33.8 +    # if boot filesystem is set then pass to fsimage.open
    33.9 +    bootfsargs = '"%s"' % incfg["args"]
   33.10 +    bootfsgroup = re.findall('zfs-bootfs=(.*?)[\s\,\"]', bootfsargs)
   33.11 +    if bootfsgroup:
   33.12 +        fs = fsimage.open(file, get_fs_offset(file), bootfsgroup[0])
   33.13 +    else:
   33.14 +        fs = fsimage.open(file, get_fs_offset(file))
   33.15  
   33.16      chosencfg = sniff_solaris(fs, incfg)
   33.17  
   33.18 @@ -672,7 +678,15 @@ if __name__ == "__main__":
   33.19      if bootcfg["ramdisk"]:
   33.20          sxp += "(ramdisk %s)" % bootcfg["ramdisk"]
   33.21      if chosencfg["args"]:
   33.22 -        sxp += "(args \"%s\")" % chosencfg["args"]
   33.23 +        zfsinfo = fsimage.getbootstring(fs)
   33.24 +        if zfsinfo is None:
   33.25 +            sxp += "(args \"%s\")" % chosencfg["args"]
   33.26 +        else:
   33.27 +            e = re.compile("zfs-bootfs=[\w\-\.\:@/]+" )
   33.28 +            (chosencfg["args"],count) = e.subn(zfsinfo, chosencfg["args"])
   33.29 +            if count == 0:
   33.30 +               chosencfg["args"] += " -B %s" % zfsinfo
   33.31 +            sxp += "(args \"%s\")" % (chosencfg["args"])
   33.32  
   33.33      sys.stdout.flush()
   33.34      os.write(fd, sxp)