7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 /*
21 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
22 * Use is subject to license terms.
23 */
24
25 /*
26 * Copyright (c) 2012 by Delphix. All rights reserved.
27 */
28
29 /*
30 * The zfs plug-in routines for GRUB are:
31 *
32 * zfs_mount() - locates a valid uberblock of the root pool and reads
33 * in its MOS at the memory address MOS.
34 *
35 * zfs_open() - locates a plain file object by following the MOS
36 * and places its dnode at the memory address DNODE.
37 *
38 * zfs_read() - read in the data blocks pointed by the DNODE.
39 *
40 * ZFS_SCRATCH is used as a working area.
41 *
42 * (memory addr) MOS DNODE ZFS_SCRATCH
43 * | | |
44 * +-------V---------V----------V---------------+
45 * memory | | dnode | dnode | scratch |
46 * | | 512B | 512B | area |
57 static void *file_buf = NULL;
58 static uint64_t file_start = 0;
59 static uint64_t file_end = 0;
60
61 /* cache for a dnode block */
62 static dnode_phys_t *dnode_buf = NULL;
63 static dnode_phys_t *dnode_mdn = NULL;
64 static uint64_t dnode_start = 0;
65 static uint64_t dnode_end = 0;
66
67 static uint64_t pool_guid = 0;
68 static uberblock_t current_uberblock;
69 static char *stackbase;
70
71 decomp_entry_t decomp_table[ZIO_COMPRESS_FUNCTIONS] =
72 {
73 {"inherit", 0}, /* ZIO_COMPRESS_INHERIT */
74 {"on", lzjb_decompress}, /* ZIO_COMPRESS_ON */
75 {"off", 0}, /* ZIO_COMPRESS_OFF */
76 {"lzjb", lzjb_decompress}, /* ZIO_COMPRESS_LZJB */
77 {"empty", 0} /* ZIO_COMPRESS_EMPTY */
78 };
79
80 static int zio_read_data(blkptr_t *bp, void *buf, char *stack);
81
82 /*
83 * Our own version of bcmp().
84 */
85 static int
86 zfs_bcmp(const void *s1, const void *s2, size_t n)
87 {
88 const uchar_t *ps1 = s1;
89 const uchar_t *ps2 = s2;
90
91 if (s1 != s2 && n != 0) {
92 do {
93 if (*ps1++ != *ps2++)
94 return (1);
95 } while (--n != 0);
96 }
97
395 grub_printf("not enough memory allocated\n");
396 return (ERR_WONT_FIT);
397 }
398
399 retbuf = buf;
400 if (comp != ZIO_COMPRESS_OFF) {
401 buf = stack;
402 stack += psize;
403 }
404
405 if (zio_read_data(bp, buf, stack) != 0) {
406 grub_printf("zio_read_data failed\n");
407 return (ERR_FSYS_CORRUPT);
408 }
409
410 if (zio_checksum_verify(bp, buf, psize) != 0) {
411 grub_printf("checksum verification failed\n");
412 return (ERR_FSYS_CORRUPT);
413 }
414
415 if (comp != ZIO_COMPRESS_OFF)
416 decomp_table[comp].decomp_func(buf, retbuf, psize, lsize);
417
418 return (0);
419 }
420
421 /*
422 * Get the block from a block id.
423 * push the block onto the stack.
424 *
425 * Return:
426 * 0 - success
427 * errnum - failure
428 */
429 static int
430 dmu_read(dnode_phys_t *dn, uint64_t blkid, void *buf, char *stack)
431 {
432 int idx, level;
433 blkptr_t *bp_array = dn->dn_blkptr;
434 int epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
435 blkptr_t *bp, *tmpbuf;
436
928
929 if (errnum = dnode_get(mosmdn, objnum, DMU_OT_POOL_PROPS, dn, stack))
930 return (errnum);
931
932 if (zap_lookup(dn, ZPOOL_PROP_BOOTFS, &objnum, stack))
933 return (ERR_FILESYSTEM_NOT_FOUND);
934
935 if (!objnum)
936 return (ERR_FILESYSTEM_NOT_FOUND);
937
938 *obj = objnum;
939 return (0);
940 }
941
942 /*
943 * List of pool features that the grub implementation of ZFS supports for
944 * read. Note that features that are only required for write do not need
945 * to be listed here since grub opens pools in read-only mode.
946 */
947 static const char *spa_feature_names[] = {
948 NULL
949 };
950
951 /*
952 * Checks whether the MOS features that are active are supported by this
953 * (GRUB's) implementation of ZFS.
954 *
955 * Return:
956 * 0: Success.
957 * errnum: Failure.
958 */
959 static int
960 check_mos_features(dnode_phys_t *mosmdn, char *stack)
961 {
962 uint64_t objnum;
963 dnode_phys_t *dn;
964 uint8_t error = 0;
965
966 dn = (dnode_phys_t *)stack;
967 stack += DNODE_SIZE;
|
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 /*
21 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
22 * Use is subject to license terms.
23 */
24
25 /*
26 * Copyright (c) 2012 by Delphix. All rights reserved.
27 * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
28 */
29
30 /*
31 * The zfs plug-in routines for GRUB are:
32 *
33 * zfs_mount() - locates a valid uberblock of the root pool and reads
34 * in its MOS at the memory address MOS.
35 *
36 * zfs_open() - locates a plain file object by following the MOS
37 * and places its dnode at the memory address DNODE.
38 *
39 * zfs_read() - read in the data blocks pointed by the DNODE.
40 *
41 * ZFS_SCRATCH is used as a working area.
42 *
43 * (memory addr) MOS DNODE ZFS_SCRATCH
44 * | | |
45 * +-------V---------V----------V---------------+
46 * memory | | dnode | dnode | scratch |
47 * | | 512B | 512B | area |
58 static void *file_buf = NULL;
59 static uint64_t file_start = 0;
60 static uint64_t file_end = 0;
61
62 /* cache for a dnode block */
63 static dnode_phys_t *dnode_buf = NULL;
64 static dnode_phys_t *dnode_mdn = NULL;
65 static uint64_t dnode_start = 0;
66 static uint64_t dnode_end = 0;
67
68 static uint64_t pool_guid = 0;
69 static uberblock_t current_uberblock;
70 static char *stackbase;
71
72 decomp_entry_t decomp_table[ZIO_COMPRESS_FUNCTIONS] =
73 {
74 {"inherit", 0}, /* ZIO_COMPRESS_INHERIT */
75 {"on", lzjb_decompress}, /* ZIO_COMPRESS_ON */
76 {"off", 0}, /* ZIO_COMPRESS_OFF */
77 {"lzjb", lzjb_decompress}, /* ZIO_COMPRESS_LZJB */
78 {"empty", 0}, /* ZIO_COMPRESS_EMPTY */
79 {"gzip-1", 0}, /* ZIO_COMPRESS_GZIP_1 */
80 {"gzip-2", 0}, /* ZIO_COMPRESS_GZIP_2 */
81 {"gzip-3", 0}, /* ZIO_COMPRESS_GZIP_3 */
82 {"gzip-4", 0}, /* ZIO_COMPRESS_GZIP_4 */
83 {"gzip-5", 0}, /* ZIO_COMPRESS_GZIP_5 */
84 {"gzip-6", 0}, /* ZIO_COMPRESS_GZIP_6 */
85 {"gzip-7", 0}, /* ZIO_COMPRESS_GZIP_7 */
86 {"gzip-8", 0}, /* ZIO_COMPRESS_GZIP_8 */
87 {"gzip-9", 0}, /* ZIO_COMPRESS_GZIP_9 */
88 {"zle", 0}, /* ZIO_COMPRESS_ZLE */
89 {"lz4", lz4_decompress} /* ZIO_COMPRESS_LZ4 */
90 };
91
92 static int zio_read_data(blkptr_t *bp, void *buf, char *stack);
93
94 /*
95 * Our own version of bcmp().
96 */
97 static int
98 zfs_bcmp(const void *s1, const void *s2, size_t n)
99 {
100 const uchar_t *ps1 = s1;
101 const uchar_t *ps2 = s2;
102
103 if (s1 != s2 && n != 0) {
104 do {
105 if (*ps1++ != *ps2++)
106 return (1);
107 } while (--n != 0);
108 }
109
407 grub_printf("not enough memory allocated\n");
408 return (ERR_WONT_FIT);
409 }
410
411 retbuf = buf;
412 if (comp != ZIO_COMPRESS_OFF) {
413 buf = stack;
414 stack += psize;
415 }
416
417 if (zio_read_data(bp, buf, stack) != 0) {
418 grub_printf("zio_read_data failed\n");
419 return (ERR_FSYS_CORRUPT);
420 }
421
422 if (zio_checksum_verify(bp, buf, psize) != 0) {
423 grub_printf("checksum verification failed\n");
424 return (ERR_FSYS_CORRUPT);
425 }
426
427 if (comp != ZIO_COMPRESS_OFF) {
428 if (decomp_table[comp].decomp_func(buf, retbuf, psize,
429 lsize) != 0) {
430 grub_printf("zio_read decompression failed\n");
431 return (ERR_FSYS_CORRUPT);
432 }
433 }
434
435 return (0);
436 }
437
438 /*
439 * Get the block from a block id.
440 * push the block onto the stack.
441 *
442 * Return:
443 * 0 - success
444 * errnum - failure
445 */
446 static int
447 dmu_read(dnode_phys_t *dn, uint64_t blkid, void *buf, char *stack)
448 {
449 int idx, level;
450 blkptr_t *bp_array = dn->dn_blkptr;
451 int epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
452 blkptr_t *bp, *tmpbuf;
453
945
946 if (errnum = dnode_get(mosmdn, objnum, DMU_OT_POOL_PROPS, dn, stack))
947 return (errnum);
948
949 if (zap_lookup(dn, ZPOOL_PROP_BOOTFS, &objnum, stack))
950 return (ERR_FILESYSTEM_NOT_FOUND);
951
952 if (!objnum)
953 return (ERR_FILESYSTEM_NOT_FOUND);
954
955 *obj = objnum;
956 return (0);
957 }
958
959 /*
960 * List of pool features that the grub implementation of ZFS supports for
961 * read. Note that features that are only required for write do not need
962 * to be listed here since grub opens pools in read-only mode.
963 */
964 static const char *spa_feature_names[] = {
965 "org.illumos:lz4_compress",
966 NULL
967 };
968
969 /*
970 * Checks whether the MOS features that are active are supported by this
971 * (GRUB's) implementation of ZFS.
972 *
973 * Return:
974 * 0: Success.
975 * errnum: Failure.
976 */
977 static int
978 check_mos_features(dnode_phys_t *mosmdn, char *stack)
979 {
980 uint64_t objnum;
981 dnode_phys_t *dn;
982 uint8_t error = 0;
983
984 dn = (dnode_phys_t *)stack;
985 stack += DNODE_SIZE;
|