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>
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>
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 + ¤t_bootfs_obj, stack))) 10.1323 + return (0); 10.1324 + if ((errnum = get_objset_mdn(ffi, MOS, NULL, 10.1325 + ¤t_bootfs_obj, mdn, stack))) 10.1326 + return (0); 10.1327 + } else { 10.1328 + if ((errnum = get_objset_mdn(ffi, MOS, 10.1329 + current_bootfs, ¤t_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)