Signed-off-by: Vladimir Serbinenko <[email protected]>
---
grub-core/fs/zfs/zfs.c | 917 ++++++++++++++++++--------------
grub-core/fs/zfs/zfs_fletcher.c | 18 +-
grub-core/fs/zfs/zfs_sha256.c | 14 +-
grub-core/fs/zfs/zfscrypt.c | 2 +-
include/grub/zfs/sa_impl.h | 1 +
include/grub/zfs/spa.h | 9 +
include/grub/zfs/zfs.h | 10 +-
7 files changed, 551 insertions(+), 420 deletions(-)
diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c
index afe821f9b..b88a2b032 100644
--- a/grub-core/fs/zfs/zfs.c
+++ b/grub-core/fs/zfs/zfs.c
@@ -193,12 +193,6 @@ typedef struct zio_checksum_info {
const char *ci_name; /* descriptive name */
} zio_checksum_info_t;
-typedef struct dnode_end
-{
- dnode_phys_t dn;
- grub_zfs_endian_t endian;
-} dnode_end_t;
-
struct grub_zfs_device_desc
{
enum { DEVICE_LEAF, DEVICE_MIRROR, DEVICE_RAIDZ } type;
@@ -223,7 +217,7 @@ struct grub_zfs_device_desc
struct subvolume
{
- dnode_end_t mdn;
+ dnode_phys_t mdn;
grub_uint64_t obj;
grub_uint64_t case_insensitive;
grub_size_t nkeys;
@@ -247,10 +241,9 @@ struct grub_zfs_data
dnode_phys_t *dnode_mdn;
grub_uint64_t dnode_start;
grub_uint64_t dnode_end;
- grub_zfs_endian_t dnode_endian;
- dnode_end_t mos;
- dnode_end_t dnode;
+ dnode_phys_t mos;
+ dnode_phys_t dnode;
struct subvolume subvol;
struct grub_zfs_device_desc *devices_attached;
@@ -273,7 +266,7 @@ struct grub_zfs_dir_ctx
grub_err_t (*grub_zfs_decrypt) (grub_crypto_cipher_handle_t cipher,
grub_uint64_t algo,
- void *nonce,
+ const void *nonce,
char *buf, grub_size_t size,
const grub_uint32_t *expected_mac,
grub_zfs_endian_t endian) = NULL;
@@ -302,7 +295,7 @@ static const char *spa_feature_names[] = {
static int
check_feature(const char *name, grub_uint64_t val, struct grub_zfs_dir_ctx
*ctx);
static grub_err_t
-check_mos_features(dnode_phys_t *mosmdn_phys,grub_zfs_endian_t endian,struct
grub_zfs_data* data );
+check_mos_features(dnode_phys_t *mosmdn_phys, struct grub_zfs_data* data );
static grub_err_t
zlib_decompress (void *s, void *d,
@@ -404,7 +397,7 @@ static decomp_entry_t decomp_table[ZIO_COMPRESS_FUNCTIONS]
= {
{"zstd", zstd_decompress}, /* ZIO_COMPRESS_ZSTD */
};
-static grub_err_t zio_read_data (blkptr_t * bp, grub_zfs_endian_t endian,
+static grub_err_t zio_read_data (const blkptr_t * bp,
void *buf, struct grub_zfs_data *data);
/*
@@ -449,6 +442,245 @@ static zio_checksum_info_t
zio_checksum_table[ZIO_CHECKSUM_FUNCTIONS] = {
{zio_checksum_SHA256, 1, 0, "SHA256+MAC"},
};
+static inline void
+grub_zfs_byteswap_u64(grub_uint64_t *val)
+{
+ *val = grub_swap_bytes64(*val);
+}
+
+static inline void
+grub_zfs_byteswap_u32(grub_uint32_t *val)
+{
+ *val = grub_swap_bytes32(*val);
+}
+
+static inline void
+grub_zfs_byteswap_u16(grub_uint16_t *val)
+{
+ *val = grub_swap_bytes16(*val);
+}
+
+static void
+grub_zfs_byteswap_checksum(zio_cksum_t *csum)
+{
+ for (int i = 0; i < 4; i++)
+ grub_zfs_byteswap_u64(&csum->zc_word[i]);
+}
+
+static void
+grub_zfs_byteswap_blkptr(blkptr_t *bp)
+{
+ for (int i = 0; i < SPA_DVAS_PER_BP; i++)
+ {
+ grub_zfs_byteswap_u64(&bp->blk_dva[i].dva_word[0]);
+ grub_zfs_byteswap_u64(&bp->blk_dva[i].dva_word[1]);
+ }
+ grub_zfs_byteswap_u64(&bp->blk_prop);
+ grub_zfs_byteswap_u64(&bp->blk_pad[0]);
+ grub_zfs_byteswap_u64(&bp->blk_pad[1]);
+ grub_zfs_byteswap_u64(&bp->blk_phys_birth);
+ grub_zfs_byteswap_u64(&bp->blk_birth);
+ grub_zfs_byteswap_u64(&bp->blk_fill);
+
+ grub_zfs_byteswap_checksum(&bp->blk_cksum);
+}
+
+static void
+grub_zfs_byteswap_uberblock(uberblock_t *ub)
+{
+ grub_zfs_byteswap_u64(&ub->ub_magic);
+ grub_zfs_byteswap_u64(&ub->ub_version);
+ grub_zfs_byteswap_u64(&ub->ub_txg);
+ grub_zfs_byteswap_u64(&ub->ub_guid_sum);
+ grub_zfs_byteswap_u64(&ub->ub_timestamp);
+ grub_zfs_byteswap_blkptr(&ub->ub_rootbp);
+}
+
+static void
+grub_zfs_byteswap_type(void *buf, grub_size_t len, grub_uint8_t type);
+
+static void
+grub_zfs_byteswap_dnode_proper(dnode_phys_t *dn)
+{
+ grub_zfs_byteswap_u16(&dn->dn_datablkszsec);
+ grub_zfs_byteswap_u16(&dn->dn_bonuslen);
+ grub_zfs_byteswap_u64(&dn->dn_maxblkid);
+ grub_zfs_byteswap_u64(&dn->dn_used);
+ grub_zfs_byteswap_u64(&dn->dn_pad3[0]);
+ grub_zfs_byteswap_u64(&dn->dn_pad3[1]);
+ grub_zfs_byteswap_u64(&dn->dn_pad3[2]);
+ grub_zfs_byteswap_u64(&dn->dn_pad3[3]);
+
+ for (unsigned i = 0; i < dn->dn_nblkptr; i++)
+ grub_zfs_byteswap_blkptr(&dn->dn_blkptr[i]);
+
+ if (dn->dn_flags & DNODE_FLAG_SPILL_BLKPTR)
+ grub_zfs_byteswap_blkptr(&dn->dn_spill);
+}
+
+static void
+grub_zfs_byteswap_dnode(dnode_phys_t *dn)
+{
+ grub_zfs_byteswap_dnode_proper(dn);
+ grub_zfs_byteswap_type(dn->dn_bonus, dn->dn_bonuslen, dn->dn_bonustype);
+}
+
+static void
+grub_zfs_byteswap_objset(objset_phys_t *os)
+{
+ grub_zfs_byteswap_dnode(&os->os_meta_dnode);
+ /* We ignore ZIL header. */
+ grub_zfs_byteswap_u64(&os->os_type);
+ grub_zfs_byteswap_u64(&os->os_flags);
+ grub_zfs_byteswap_dnode(&os->os_userused_dnode);
+ grub_zfs_byteswap_dnode(&os->os_groupused_dnode);
+}
+
+static void
+grub_zfs_byteswap_u64_array(grub_uint64_t *arr, grub_size_t len)
+{
+ for (unsigned i = 0; i < len / 8; i++)
+ grub_zfs_byteswap_u64(arr + i);
+}
+
+static void
+grub_zfs_byteswap_mzap(mzap_phys_t *mz, grub_size_t objsize)
+{
+ grub_zfs_byteswap_u64(&mz->mz_block_type);
+ grub_zfs_byteswap_u64(&mz->mz_salt);
+ for (unsigned i = 0; i < 6; i++)
+ grub_zfs_byteswap_u64(&mz->mz_pad[i]);
+ for (unsigned i = 0; i < objsize / MZAP_ENT_LEN - 1; i++)
+ {
+ grub_zfs_byteswap_u64(&mz->mz_chunk[i].mze_value);
+ grub_zfs_byteswap_u32(&mz->mz_chunk[i].mze_cd);
+ grub_zfs_byteswap_u16(&mz->mz_chunk[i].mze_pad);
+ }
+}
+
+static void
+grub_zfs_byteswap_zap_leaf(zap_leaf_phys_t *lf, grub_size_t len)
+{
+ int blksft = zfs_log2 (len);
+
+ grub_zfs_byteswap_u64(&lf->l_hdr.lh_block_type);
+ grub_zfs_byteswap_u64(&lf->l_hdr.lh_prefix);
+ grub_zfs_byteswap_u32(&lf->l_hdr.lh_magic);
+ grub_zfs_byteswap_u16(&lf->l_hdr.lh_nfree);
+ grub_zfs_byteswap_u16(&lf->l_hdr.lh_nentries);
+ grub_zfs_byteswap_u16(&lf->l_hdr.lh_prefix_len);
+ grub_zfs_byteswap_u16(&lf->l_hdr.lh_freelist);
+
+ for (int i = 0; i < ZAP_LEAF_HASH_NUMENTRIES(blksft); i++)
+ grub_zfs_byteswap_u16(&lf->l_hash[i]);
+
+ for (int i = 0; i < ZAP_LEAF_NUMCHUNKS (blksft); i++) {
+ zap_leaf_chunk_t *lc = ZAP_LEAF_CHUNK(lf, blksft, i);
+ struct zap_leaf_entry *le;
+
+ switch (lc->l_free.lf_type) {
+ case ZAP_CHUNK_ENTRY:
+ le = &lc->l_entry;
+
+ grub_zfs_byteswap_u16(&le->le_next);
+ grub_zfs_byteswap_u16(&le->le_name_chunk);
+ grub_zfs_byteswap_u16(&le->le_name_length);
+ grub_zfs_byteswap_u16(&le->le_value_chunk);
+ grub_zfs_byteswap_u16(&le->le_value_length);
+ grub_zfs_byteswap_u32(&le->le_cd);
+ grub_zfs_byteswap_u64(&le->le_hash);
+ break;
+ case ZAP_CHUNK_FREE:
+ grub_zfs_byteswap_u16(&lc->l_free.lf_next);
+ break;
+ case ZAP_CHUNK_ARRAY:
+ grub_zfs_byteswap_u16(&lc->l_array.la_next);
+ break;
+ default:
+ grub_dprintf("zfs", "Unknown leaf type %d\n", lc->l_free.lf_type);
+ }
+ }
+}
+
+static void
+grub_zfs_byteswap_zap(void *zp, grub_size_t len)
+{
+ grub_uint64_t block_type = *(grub_uint64_t *) zp;
+ if (block_type == grub_swap_bytes64_compile_time(ZBT_MICRO))
+ grub_zfs_byteswap_mzap(zp, len);
+ else if (block_type == grub_swap_bytes64_compile_time(ZBT_HEADER))
+ grub_zfs_byteswap_u64_array(zp, len);
+ else if (block_type == grub_swap_bytes64_compile_time(ZBT_LEAF))
+ grub_zfs_byteswap_zap_leaf(zp, len);
+ else
+ grub_dprintf ("zfs", "unknown ZAP type");
+}
+
+static const dmu_object_byteswap_t byteswap_table[] = {
+ DMU_BSWAP_UINT8, DMU_BSWAP_ZAP, DMU_BSWAP_UINT64, DMU_BSWAP_UINT8,
+ DMU_BSWAP_UINT64, DMU_BSWAP_UINT64, DMU_BSWAP_UINT64, DMU_BSWAP_UINT64,
+ DMU_BSWAP_UINT64, DMU_BSWAP_UINT64, DMU_BSWAP_DNODE, DMU_BSWAP_OBJSET,
+ DMU_BSWAP_UINT64, DMU_BSWAP_ZAP, DMU_BSWAP_ZAP, DMU_BSWAP_ZAP,
+
+ DMU_BSWAP_UINT64, DMU_BSWAP_ZNODE, DMU_BSWAP_OLDACL, DMU_BSWAP_UINT8,
+ DMU_BSWAP_ZAP, DMU_BSWAP_ZAP, DMU_BSWAP_ZAP, DMU_BSWAP_UINT8,
+ DMU_BSWAP_ZAP, DMU_BSWAP_UINT8, DMU_BSWAP_UINT64, DMU_BSWAP_ZAP,
+ DMU_BSWAP_ZAP, DMU_BSWAP_UINT8, DMU_BSWAP_UINT64, DMU_BSWAP_ZAP,
+
+ DMU_BSWAP_ZAP, DMU_BSWAP_ACL, DMU_BSWAP_UINT8, DMU_BSWAP_UINT8,
+ DMU_BSWAP_UINT64, DMU_BSWAP_ZAP, DMU_BSWAP_ZAP, DMU_BSWAP_ZAP,
+ DMU_BSWAP_ZAP, DMU_BSWAP_ZAP, DMU_BSWAP_ZAP, DMU_BSWAP_ZAP,
+ DMU_BSWAP_UINT8, DMU_BSWAP_ZAP, DMU_BSWAP_ZAP, DMU_BSWAP_ZAP,
+
+ DMU_BSWAP_ZAP, DMU_BSWAP_UINT8, DMU_BSWAP_ZAP, DMU_BSWAP_UINT64,
+ DMU_BSWAP_ZAP, DMU_BSWAP_UINT64,
+};
+
+static dmu_object_byteswap_t
+get_byteswap_type(grub_uint8_t type)
+{
+ if (type & 0x80)
+ return type & DMU_OT_BYTESWAP_MASK;
+
+ if (type < ARRAY_SIZE (byteswap_table))
+ return byteswap_table[type];
+ grub_fatal("Unknown type %d", type);
+}
+
+static void
+grub_zfs_byteswap_type(void *buf, grub_size_t len, grub_uint8_t type)
+{
+ /*
+ DMU_BSWAP_UINT16,
+ DMU_BSWAP_UINT32,
+ DMU_BSWAP_ZNODE,
+ DMU_BSWAP_OLDACL,
+ DMU_BSWAP_ACL,
+
+ */
+ switch (get_byteswap_type(type))
+ {
+ case DMU_BSWAP_UINT8:
+ break;
+ case DMU_BSWAP_DNODE:
+ for (unsigned i = 0; i < len / sizeof(dnode_phys_t); i++)
+ grub_zfs_byteswap_dnode((dnode_phys_t *)buf + i);
+ break;
+ case DMU_BSWAP_OBJSET:
+ for (unsigned i = 0; i < len / sizeof(objset_phys_t); i++)
+ grub_zfs_byteswap_objset((objset_phys_t *)buf + i);
+ break;
+ case DMU_BSWAP_ZAP:
+ grub_zfs_byteswap_zap(buf, len);
+ break;
+ case DMU_BSWAP_UINT64:
+ grub_zfs_byteswap_u64_array(buf, len);
+ break;
+ default:
+ grub_fatal("Unknown type %d", type);
+ }
+}
+
/*
* zio_checksum_verify: Provides support for checksum verification.
*
@@ -482,8 +714,12 @@ zio_checksum_verify (zio_cksum_t zc, grub_uint32_t
checksum,
else
ci->ci_func (buf, size, endian, &actual_cksum);
- if (grub_memcmp (&actual_cksum, &zc,
- checksum != ZIO_CHECKSUM_SHA256_MAC ? 32 : 20) != 0)
+ int cksumlen = checksum != ZIO_CHECKSUM_SHA256_MAC ? 32 : 20;
+
+ if (ci->ci_eck && !GRUB_ZFS_IS_NATIVE_BYTEORDER(endian))
+ grub_zfs_byteswap_checksum(&actual_cksum);
+
+ if (grub_memcmp (&actual_cksum, &zc, cksumlen) != 0)
{
grub_dprintf ("zfs", "checksum %s verification failed\n", ci->ci_name);
grub_dprintf ("zfs", "actual checksum %016llx %016llx %016llx %016llx\n",
@@ -515,30 +751,14 @@ zio_checksum_verify (zio_cksum_t zc, grub_uint32_t
checksum,
static int
vdev_uberblock_compare (uberblock_t * ub1, uberblock_t * ub2)
{
- grub_zfs_endian_t ub1_endian, ub2_endian;
- if (grub_zfs_to_cpu64 (ub1->ub_magic, GRUB_ZFS_LITTLE_ENDIAN)
- == UBERBLOCK_MAGIC)
- ub1_endian = GRUB_ZFS_LITTLE_ENDIAN;
- else
- ub1_endian = GRUB_ZFS_BIG_ENDIAN;
- if (grub_zfs_to_cpu64 (ub2->ub_magic, GRUB_ZFS_LITTLE_ENDIAN)
- == UBERBLOCK_MAGIC)
- ub2_endian = GRUB_ZFS_LITTLE_ENDIAN;
- else
- ub2_endian = GRUB_ZFS_BIG_ENDIAN;
-
- if (grub_zfs_to_cpu64 (ub1->ub_txg, ub1_endian)
- < grub_zfs_to_cpu64 (ub2->ub_txg, ub2_endian))
+ if (ub1->ub_txg < ub2->ub_txg)
return -1;
- if (grub_zfs_to_cpu64 (ub1->ub_txg, ub1_endian)
- > grub_zfs_to_cpu64 (ub2->ub_txg, ub2_endian))
+ if (ub1->ub_txg > ub2->ub_txg)
return 1;
- if (grub_zfs_to_cpu64 (ub1->ub_timestamp, ub1_endian)
- < grub_zfs_to_cpu64 (ub2->ub_timestamp, ub2_endian))
+ if (ub1->ub_timestamp < ub2->ub_timestamp)
return -1;
- if (grub_zfs_to_cpu64 (ub1->ub_timestamp, ub1_endian)
- > grub_zfs_to_cpu64 (ub2->ub_timestamp, ub2_endian))
+ if (ub1->ub_timestamp > ub2->ub_timestamp)
return 1;
return 0;
@@ -615,34 +835,27 @@ find_bestub (uberblock_phys_t * ub_array,
grub_errno = GRUB_ERR_NONE;
continue;
}
+
+ if (ubptr->ubp_uberblock.ub_magic ==
grub_swap_bytes64_compile_time(UBERBLOCK_MAGIC))
+ grub_zfs_byteswap_uberblock(&ubptr->ubp_uberblock);
+
if (ubbest == NULL
|| vdev_uberblock_compare (&(ubptr->ubp_uberblock),
&(ubbest->ubp_uberblock)) > 0)
ubbest = ubptr;
}
- if (!ubbest)
+ if (!ubbest) {
grub_errno = err;
+ grub_dprintf("zfs", "no valid ub found. vdev_pys_sector=%lld\n",
+ (long long)desc->vdev_phys_sector);
+ } else {
+ grub_dprintf("zfs", "valid ub found. vdev_pys_sector=%lld\n",
+ (long long)desc->vdev_phys_sector);
+ }
return ubbest;
}
-static inline grub_size_t
-get_psize (blkptr_t * bp, grub_zfs_endian_t endian)
-{
- return ((((grub_zfs_to_cpu64 ((bp)->blk_prop, endian) >> 16) & 0xffff) + 1)
- << SPA_MINBLOCKSHIFT);
-}
-
-static grub_uint64_t
-dva_get_offset (const dva_t *dva, grub_zfs_endian_t endian)
-{
- grub_dprintf ("zfs", "dva=%llx, %llx\n",
- (unsigned long long) dva->dva_word[0],
- (unsigned long long) dva->dva_word[1]);
- return grub_zfs_to_cpu64 ((dva)->dva_word[1],
- endian) << SPA_MINBLOCKSHIFT;
-}
-
static grub_err_t
zfs_fetch_nvlist (struct grub_zfs_device_desc *diskdesc, char **nvlist)
{
@@ -1054,7 +1267,7 @@ check_pool_label (struct grub_zfs_data *data,
"bad vdev_phys_t.vp_zbt.zec_magic number");
}
/* Now check the integrity of the vdev_phys_t structure though checksum. */
- ZIO_SET_CHECKSUM(&emptycksum, diskdesc->vdev_phys_sector << 9, 0, 0, 0);
+ ZIO_SET_CHECKSUM(&emptycksum, grub_cpu_to_zfs64(diskdesc->vdev_phys_sector
<< 9, endian), 0, 0, 0);
err = zio_checksum_verify (emptycksum, ZIO_CHECKSUM_LABEL, endian,
nvlist, VDEV_PHYS_SIZE);
if (err) {
@@ -1743,14 +1956,14 @@ read_device (grub_uint64_t offset, struct
grub_zfs_device_desc *desc,
static grub_err_t
read_dva (const dva_t *dva,
- grub_zfs_endian_t endian, struct grub_zfs_data *data,
+ struct grub_zfs_data *data,
void *buf, grub_size_t len)
{
grub_uint64_t offset;
unsigned i;
grub_err_t err = 0;
int try = 0;
- offset = dva_get_offset (dva, endian);
+ offset = DVA_GET_OFFSET(dva);
for (try = 0; try < 2; try++)
{
@@ -1780,7 +1993,7 @@ read_dva (const dva_t *dva,
*
*/
static grub_err_t
-zio_read_gang (blkptr_t * bp, grub_zfs_endian_t endian, dva_t * dva, void *buf,
+zio_read_gang (const blkptr_t * bp, const dva_t * dva, void *buf,
struct grub_zfs_data *data)
{
zio_gbh_phys_t *zio_gb;
@@ -1793,10 +2006,8 @@ zio_read_gang (blkptr_t * bp, grub_zfs_endian_t endian,
dva_t * dva, void *buf,
zio_gb = grub_malloc (SPA_GANGBLOCKSIZE);
if (!zio_gb)
return grub_errno;
- grub_dprintf ("zfs", endian == GRUB_ZFS_LITTLE_ENDIAN ? "little-endian
gang\n"
- :"big-endian gang\n");
- err = read_dva (dva, endian, data, zio_gb, SPA_GANGBLOCKSIZE);
+ err = read_dva (dva, data, zio_gb, SPA_GANGBLOCKSIZE);
if (err)
{
grub_free (zio_gb);
@@ -1806,8 +2017,8 @@ zio_read_gang (blkptr_t * bp, grub_zfs_endian_t endian,
dva_t * dva, void *buf,
/* XXX */
/* self checksuming the gang block header */
ZIO_SET_CHECKSUM (&zc, DVA_GET_VDEV (dva),
- dva_get_offset (dva, endian), bp->blk_birth, 0);
- err = zio_checksum_verify (zc, ZIO_CHECKSUM_GANG_HEADER, endian,
+ DVA_GET_OFFSET (dva), bp->blk_birth, 0);
+ err = zio_checksum_verify (zc, ZIO_CHECKSUM_GANG_HEADER,
BP_GET_BYTEORDER(bp),
(char *) zio_gb, SPA_GANGBLOCKSIZE);
if (err)
{
@@ -1815,20 +2026,22 @@ zio_read_gang (blkptr_t * bp, grub_zfs_endian_t endian,
dva_t * dva, void *buf,
return err;
}
- endian = (grub_zfs_to_cpu64 (bp->blk_prop, endian) >> 63) & 1;
+ if (!GRUB_ZFS_IS_NATIVE_BYTEORDER(BP_GET_BYTEORDER(bp)))
+ for (i = 0; i < SPA_GBH_NBLKPTRS; i++)
+ grub_zfs_byteswap_blkptr(&zio_gb->zg_blkptr[i]);
for (i = 0; i < SPA_GBH_NBLKPTRS; i++)
{
if (BP_IS_HOLE(&zio_gb->zg_blkptr[i]))
continue;
- err = zio_read_data (&zio_gb->zg_blkptr[i], endian, buf, data);
+ err = zio_read_data (&zio_gb->zg_blkptr[i], buf, data);
if (err)
{
grub_free (zio_gb);
return err;
}
- buf = (char *) buf + get_psize (&zio_gb->zg_blkptr[i], endian);
+ buf = (char *) buf + BP_GET_PSIZE(&zio_gb->zg_blkptr[i]);
}
grub_free (zio_gb);
return GRUB_ERR_NONE;
@@ -1838,13 +2051,12 @@ zio_read_gang (blkptr_t * bp, grub_zfs_endian_t endian,
dva_t * dva, void *buf,
* Read in a block of raw data to buf.
*/
static grub_err_t
-zio_read_data (blkptr_t * bp, grub_zfs_endian_t endian, void *buf,
- struct grub_zfs_data *data)
+zio_read_data (const blkptr_t * bp, void *buf, struct grub_zfs_data *data)
{
int i, psize;
grub_err_t err = GRUB_ERR_NONE;
- psize = get_psize (bp, endian);
+ psize = BP_GET_PSIZE (bp);
/* pick a good dva from the block pointer */
for (i = 0; i < SPA_DVAS_PER_BP; i++)
@@ -1852,10 +2064,10 @@ zio_read_data (blkptr_t * bp, grub_zfs_endian_t endian,
void *buf,
if (bp->blk_dva[i].dva_word[0] == 0 && bp->blk_dva[i].dva_word[1] == 0)
continue;
- if ((grub_zfs_to_cpu64 (bp->blk_dva[i].dva_word[1], endian)>>63) & 1)
- err = zio_read_gang (bp, endian, &bp->blk_dva[i], buf, data);
+ if (DVA_GET_GANG(&bp->blk_dva[i]))
+ err = zio_read_gang (bp, &bp->blk_dva[i], buf, data);
else
- err = read_dva (&bp->blk_dva[i], endian, data, buf, psize);
+ err = read_dva (&bp->blk_dva[i], data, buf, psize);
if (!err)
return GRUB_ERR_NONE;
grub_errno = GRUB_ERR_NONE;
@@ -1906,7 +2118,7 @@ decode_embedded_bp_compressed(const blkptr_t *bp, void
*buf)
* and put the uncompressed data in buf.
*/
static grub_err_t
-zio_read (blkptr_t *bp, grub_zfs_endian_t endian, void **buf,
+zio_read (const blkptr_t *bp, void **buf,
grub_size_t *size, struct grub_zfs_data *data)
{
grub_size_t lsize, psize;
@@ -1918,9 +2130,9 @@ zio_read (blkptr_t *bp, grub_zfs_endian_t endian, void
**buf,
*buf = NULL;
- checksum = (grub_zfs_to_cpu64((bp)->blk_prop, endian) >> 40) & 0xff;
- comp = (grub_zfs_to_cpu64((bp)->blk_prop, endian)>>32) & 0x7f;
- encrypted = ((grub_zfs_to_cpu64((bp)->blk_prop, endian) >> 60) & 3);
+ checksum = BP_GET_CHECKSUM(bp);
+ comp = BP_GET_COMPRESS(bp);
+ encrypted = BP_GET_PROP_BIT_61(bp);
if (BP_IS_EMBEDDED(bp))
{
if (BPE_GET_ETYPE(bp) != BP_EMBEDDED_TYPE_DATA)
@@ -1929,14 +2141,12 @@ zio_read (blkptr_t *bp, grub_zfs_endian_t endian, void
**buf,
PRIuGRUB_UINT64_T ")\n",
BPE_GET_ETYPE (bp));
lsize = BPE_GET_LSIZE(bp);
- psize = BF64_GET_SB(grub_zfs_to_cpu64 ((bp)->blk_prop, endian), 25, 7,
0, 1);
+ psize = BPE_GET_PSIZE(bp);
}
else
{
- lsize = (BP_IS_HOLE(bp) ? 0 :
- (((grub_zfs_to_cpu64 ((bp)->blk_prop, endian) & 0xffff) + 1)
- << SPA_MINBLOCKSHIFT));
- psize = get_psize (bp, endian);
+ lsize = (BP_IS_HOLE(bp) ? 0 : BP_GET_LSIZE(bp));
+ psize = BP_GET_PSIZE(bp);
}
grub_dprintf("zfs", "zio_read: E %d: size %" PRIdGRUB_SSIZE "/%"
PRIdGRUB_SSIZE "\n", (int)BP_IS_EMBEDDED(bp), lsize, psize);
@@ -1960,12 +2170,11 @@ zio_read (blkptr_t *bp, grub_zfs_endian_t endian, void
**buf,
if (! compbuf)
return grub_errno;
- grub_dprintf ("zfs", "endian = %d\n", endian);
if (BP_IS_EMBEDDED(bp))
err = decode_embedded_bp_compressed(bp, compbuf);
else
{
- err = zio_read_data (bp, endian, compbuf, data);
+ err = zio_read_data (bp, compbuf, data);
/* FIXME is it really necessary? */
if (comp != ZIO_COMPRESS_OFF)
grub_memset (compbuf + psize, 0, ALIGN_UP (psize, 16) - psize);
@@ -1979,7 +2188,7 @@ zio_read (blkptr_t *bp, grub_zfs_endian_t endian, void
**buf,
if (!BP_IS_EMBEDDED(bp))
{
- err = zio_checksum_verify (zc, checksum, endian,
+ err = zio_checksum_verify (zc, checksum, BP_GET_BYTEORDER(bp),
compbuf, psize);
if (err)
{
@@ -2001,8 +2210,7 @@ zio_read (blkptr_t *bp, grub_zfs_endian_t endian, void
**buf,
unsigned i, besti = 0;
grub_uint64_t bestval = 0;
for (i = 0; i < data->subvol.nkeys; i++)
- if (data->subvol.keyring[i].txg <= grub_zfs_to_cpu64 (bp->blk_birth,
- endian)
+ if (data->subvol.keyring[i].txg <= bp->blk_birth
&& data->subvol.keyring[i].txg > bestval)
{
besti = i;
@@ -2013,21 +2221,19 @@ zio_read (blkptr_t *bp, grub_zfs_endian_t endian, void
**buf,
grub_free (compbuf);
*buf = NULL;
grub_dprintf ("zfs", "no key for txg %" PRIxGRUB_UINT64_T "\n",
- grub_zfs_to_cpu64 (bp->blk_birth,
- endian));
+ bp->blk_birth);
return grub_error (GRUB_ERR_BAD_FS, "no key found in keychain");
}
grub_dprintf ("zfs", "using key %u (%" PRIxGRUB_UINT64_T
", %p) for txg %" PRIxGRUB_UINT64_T "\n",
besti, data->subvol.keyring[besti].txg,
data->subvol.keyring[besti].cipher,
- grub_zfs_to_cpu64 (bp->blk_birth,
- endian));
+ bp->blk_birth);
err = grub_zfs_decrypt (data->subvol.keyring[besti].cipher,
data->subvol.keyring[besti].algo,
- &(bp)->blk_dva[encrypted],
+ &(bp)->blk_dva[2],
compbuf, psize, zc.zc_mac,
- endian);
+ BP_GET_BYTEORDER(bp));
}
if (err)
{
@@ -2056,6 +2262,17 @@ zio_read (blkptr_t *bp, grub_zfs_endian_t endian, void
**buf,
}
}
+ if (!GRUB_ZFS_IS_NATIVE_BYTEORDER(BP_GET_BYTEORDER(bp)))
+ {
+ if (BP_GET_LEVEL(bp) > 0)
+ {
+ for (unsigned i = 0; i < lsize / sizeof(blkptr_t); i++)
+ grub_zfs_byteswap_blkptr((blkptr_t *)*buf + i);
+ }
+ else
+ grub_zfs_byteswap_type(*buf, lsize, BP_GET_TYPE(bp));
+ }
+
return GRUB_ERR_NONE;
}
@@ -2065,29 +2282,28 @@ zio_read (blkptr_t *bp, grub_zfs_endian_t endian, void
**buf,
*
*/
static grub_err_t
-dmu_read (dnode_end_t * dn, grub_uint64_t blkid, void **buf,
- grub_zfs_endian_t *endian_out, struct grub_zfs_data *data)
+dmu_read (dnode_phys_t * dn, grub_uint64_t blkid, void **buf,
+ struct grub_zfs_data *data)
{
int level;
grub_off_t idx;
- blkptr_t *bp_array = dn->dn.dn_blkptr;
- int epbs = dn->dn.dn_indblkshift - SPA_BLKPTRSHIFT;
+ blkptr_t *bp_array = dn->dn_blkptr;
+ int epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
blkptr_t *bp;
void *tmpbuf = 0;
- grub_zfs_endian_t endian;
grub_err_t err = GRUB_ERR_NONE;
bp = grub_malloc (sizeof (blkptr_t));
if (!bp)
return grub_errno;
- endian = dn->endian;
- for (level = dn->dn.dn_nlevels - 1; level >= 0; level--)
+ *buf = NULL;
+
+ for (level = dn->dn_nlevels - 1; level >= 0; level--)
{
- grub_dprintf ("zfs", "endian = %d\n", endian);
idx = (blkid >> (epbs * level)) & ((1 << epbs) - 1);
*bp = bp_array[idx];
- if (bp_array != dn->dn.dn_blkptr)
+ if (bp_array != dn->dn_blkptr)
{
grub_free (bp_array);
bp_array = 0;
@@ -2095,8 +2311,7 @@ dmu_read (dnode_end_t * dn, grub_uint64_t blkid, void
**buf,
if (BP_IS_HOLE (bp))
{
- grub_size_t size = grub_zfs_to_cpu16 (dn->dn.dn_datablkszsec,
- dn->endian)
+ grub_size_t size = dn->dn_datablkszsec
<< SPA_MINBLOCKSHIFT;
*buf = grub_malloc (size);
if (!*buf)
@@ -2105,27 +2320,20 @@ dmu_read (dnode_end_t * dn, grub_uint64_t blkid, void
**buf,
break;
}
grub_memset (*buf, 0, size);
- endian = (grub_zfs_to_cpu64 (bp->blk_prop, endian) >> 63) & 1;
break;
}
if (level == 0)
{
- grub_dprintf ("zfs", "endian = %d\n", endian);
- err = zio_read (bp, endian, buf, 0, data);
- endian = (grub_zfs_to_cpu64 (bp->blk_prop, endian) >> 63) & 1;
+ err = zio_read (bp, buf, 0, data);
break;
}
- grub_dprintf ("zfs", "endian = %d\n", endian);
- err = zio_read (bp, endian, &tmpbuf, 0, data);
- endian = (grub_zfs_to_cpu64 (bp->blk_prop, endian) >> 63) & 1;
+ err = zio_read (bp, &tmpbuf, 0, data);
if (err)
break;
bp_array = tmpbuf;
}
- if (bp_array != dn->dn.dn_blkptr)
+ if (bp_array != dn->dn_blkptr)
grub_free (bp_array);
- if (endian_out)
- *endian_out = endian;
grub_free (bp);
return err;
@@ -2136,7 +2344,7 @@ dmu_read (dnode_end_t * dn, grub_uint64_t blkid, void
**buf,
* in "value".
*/
static grub_err_t
-mzap_lookup (mzap_phys_t * zapobj, grub_zfs_endian_t endian,
+mzap_lookup (mzap_phys_t * zapobj,
grub_uint32_t objsize, const char *name, grub_uint64_t * value,
int case_insensitive)
{
@@ -2151,7 +2359,7 @@ mzap_lookup (mzap_phys_t * zapobj, grub_zfs_endian_t
endian,
if (case_insensitive ? (grub_strcasecmp (mzap_ent[i].mze_name, name) ==
0)
: (grub_strcmp (mzap_ent[i].mze_name, name) == 0))
{
- *value = grub_zfs_to_cpu64 (mzap_ent[i].mze_value, endian);
+ *value = mzap_ent[i].mze_value;
return GRUB_ERR_NONE;
}
}
@@ -2160,7 +2368,7 @@ mzap_lookup (mzap_phys_t * zapobj, grub_zfs_endian_t
endian,
}
static int
-mzap_iterate (mzap_phys_t * zapobj, grub_zfs_endian_t endian, int objsize,
+mzap_iterate (mzap_phys_t * zapobj, int objsize,
int (*hook) (const char *name, grub_uint64_t val,
struct grub_zfs_dir_ctx *ctx),
struct grub_zfs_dir_ctx *ctx)
@@ -2174,8 +2382,7 @@ mzap_iterate (mzap_phys_t * zapobj, grub_zfs_endian_t
endian, int objsize,
grub_dprintf ("zfs", "zap: name = %s, value = %llx, cd = %x\n",
mzap_ent[i].mze_name, (long long)mzap_ent[i].mze_value,
(int)mzap_ent[i].mze_cd);
- if (hook (mzap_ent[i].mze_name,
- grub_zfs_to_cpu64 (mzap_ent[i].mze_value, endian), ctx))
+ if (hook (mzap_ent[i].mze_name, mzap_ent[i].mze_value, ctx))
return 1;
}
@@ -2250,7 +2457,7 @@ name_cmp (const char *s1, const char *s2, grub_size_t n,
/* XXX */
static int
-zap_leaf_array_equal (zap_leaf_phys_t * l, grub_zfs_endian_t endian,
+zap_leaf_array_equal (zap_leaf_phys_t * l,
int blksft, int chunk, grub_size_t array_len,
const char *buf, int case_insensitive)
{
@@ -2270,7 +2477,7 @@ zap_leaf_array_equal (zap_leaf_phys_t * l,
grub_zfs_endian_t endian,
if (name_cmp ((char *) la->la_array, buf + bseen, toread,
case_insensitive) != 0)
break;
- chunk = grub_zfs_to_cpu16 (la->la_next, endian);
+ chunk = la->la_next;
bseen += toread;
}
return (bseen == array_len);
@@ -2278,7 +2485,7 @@ zap_leaf_array_equal (zap_leaf_phys_t * l,
grub_zfs_endian_t endian,
/* XXX */
static grub_err_t
-zap_leaf_array_get (zap_leaf_phys_t * l, grub_zfs_endian_t endian, int blksft,
+zap_leaf_array_get (zap_leaf_phys_t * l, int blksft,
int chunk, grub_size_t array_len, char *buf)
{
grub_size_t bseen = 0;
@@ -2297,7 +2504,7 @@ zap_leaf_array_get (zap_leaf_phys_t * l,
grub_zfs_endian_t endian, int blksft,
la = &ZAP_LEAF_CHUNK (l, blksft, chunk)->l_array;
grub_memcpy (buf + bseen,la->la_array, toread);
- chunk = grub_zfs_to_cpu16 (la->la_next, endian);
+ chunk = la->la_next;
bseen += toread;
}
return GRUB_ERR_NONE;
@@ -2311,7 +2518,7 @@ zap_leaf_array_get (zap_leaf_phys_t * l,
grub_zfs_endian_t endian, int blksft,
*/
/* XXX */
static grub_err_t
-zap_leaf_lookup (zap_leaf_phys_t * l, grub_zfs_endian_t endian,
+zap_leaf_lookup (zap_leaf_phys_t * l,
int blksft, grub_uint64_t h,
const char *name, grub_uint64_t * value,
int case_insensitive)
@@ -2320,13 +2527,13 @@ zap_leaf_lookup (zap_leaf_phys_t * l, grub_zfs_endian_t
endian,
struct zap_leaf_entry *le;
/* Verify if this is a valid leaf block */
- if (grub_zfs_to_cpu64 (l->l_hdr.lh_block_type, endian) != ZBT_LEAF)
+ if (l->l_hdr.lh_block_type != ZBT_LEAF)
return grub_error (GRUB_ERR_BAD_FS, "invalid leaf type");
- if (grub_zfs_to_cpu32 (l->l_hdr.lh_magic, endian) != ZAP_LEAF_MAGIC)
+ if (l->l_hdr.lh_magic != ZAP_LEAF_MAGIC)
return grub_error (GRUB_ERR_BAD_FS, "invalid leaf magic");
- for (chunk = grub_zfs_to_cpu16 (l->l_hash[LEAF_HASH (blksft, h, l)], endian);
- chunk != CHAIN_END; chunk = grub_zfs_to_cpu16 (le->le_next, endian))
+ for (chunk = l->l_hash[LEAF_HASH (blksft, h, l)];
+ chunk != CHAIN_END; chunk = le->le_next)
{
if (chunk >= ZAP_LEAF_NUMCHUNKS (blksft))
@@ -2338,20 +2545,19 @@ zap_leaf_lookup (zap_leaf_phys_t * l, grub_zfs_endian_t
endian,
if (le->le_type != ZAP_CHUNK_ENTRY)
return grub_error (GRUB_ERR_BAD_FS, "invalid chunk entry");
- if (grub_zfs_to_cpu64 (le->le_hash,endian) != h)
+ if (le->le_hash != h)
continue;
grub_dprintf ("zfs", "fzap: length %d\n", (int) le->le_name_length);
- if (zap_leaf_array_equal (l, endian, blksft,
- grub_zfs_to_cpu16 (le->le_name_chunk,endian),
- grub_zfs_to_cpu16 (le->le_name_length, endian),
+ if (zap_leaf_array_equal (l, blksft,
+ le->le_name_chunk,
+ le->le_name_length,
name, case_insensitive))
{
struct zap_leaf_array *la;
- if (le->le_int_size != 8 || grub_zfs_to_cpu16 (le->le_value_length,
- endian) != 1)
+ if (le->le_int_size != 8 || le->le_value_length != 1)
return grub_error (GRUB_ERR_BAD_FS, "invalid leaf chunk entry");
/* get the uint64_t property value */
@@ -2369,9 +2575,9 @@ zap_leaf_lookup (zap_leaf_phys_t * l, grub_zfs_endian_t
endian,
/* Verify if this is a fat zap header block */
static grub_err_t
-zap_verify (zap_phys_t *zap, grub_zfs_endian_t endian)
+zap_verify (zap_phys_t *zap)
{
- if (grub_zfs_to_cpu64 (zap->zap_magic, endian) != (grub_uint64_t) ZAP_MAGIC)
+ if (zap->zap_magic != (grub_uint64_t) ZAP_MAGIC)
return grub_error (GRUB_ERR_BAD_FS, "bad ZAP magic");
if (zap->zap_salt == 0)
@@ -2386,18 +2592,16 @@ zap_verify (zap_phys_t *zap, grub_zfs_endian_t endian)
*/
/* XXX */
static grub_err_t
-fzap_lookup (dnode_end_t * zap_dnode, zap_phys_t * zap,
+fzap_lookup (dnode_phys_t * zap_dnode, zap_phys_t * zap,
const char *name, grub_uint64_t * value,
struct grub_zfs_data *data, int case_insensitive)
{
void *l;
grub_uint64_t hash, idx, blkid;
- int blksft = zfs_log2 (grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec,
- zap_dnode->endian) << DNODE_SHIFT);
+ int blksft = zfs_log2 (zap_dnode->dn_datablkszsec) + DNODE_SHIFT;
grub_err_t err;
- grub_zfs_endian_t leafendian;
- err = zap_verify (zap, zap_dnode->endian);
+ err = zap_verify (zap);
if (err)
return err;
@@ -2408,16 +2612,16 @@ fzap_lookup (dnode_end_t * zap_dnode, zap_phys_t * zap,
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"external pointer tables not supported");
idx = ZAP_HASH_IDX (hash, zap->zap_ptrtbl.zt_shift);
- blkid = grub_zfs_to_cpu64 (((grub_uint64_t *) zap)[idx + (1 << (blksft - 3 -
1))], zap_dnode->endian);
+ blkid = ((grub_uint64_t *) zap)[idx + (1 << (blksft - 3 - 1))];
/* Get the leaf block */
if ((1U << blksft) < sizeof (zap_leaf_phys_t))
return grub_error (GRUB_ERR_BAD_FS, "ZAP leaf is too small");
- err = dmu_read (zap_dnode, blkid, &l, &leafendian, data);
+ err = dmu_read (zap_dnode, blkid, &l, data);
if (err)
return err;
- err = zap_leaf_lookup (l, leafendian, blksft, hash, name, value,
+ err = zap_leaf_lookup (l, blksft, hash, name, value,
case_insensitive);
grub_free (l);
return err;
@@ -2425,7 +2629,7 @@ fzap_lookup (dnode_end_t * zap_dnode, zap_phys_t * zap,
/* XXX */
static int
-fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap,
+fzap_iterate (dnode_phys_t * zap_dnode, zap_phys_t * zap,
grub_size_t name_elem_length,
int (*hook) (const void *name, grub_size_t name_length,
const void *val_in,
@@ -2437,13 +2641,11 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap,
void *l_in;
grub_uint64_t idx, idx2, blkid;
grub_uint16_t chunk;
- int blksft = zfs_log2 (grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec,
- zap_dnode->endian) << DNODE_SHIFT);
+ int blksft = zfs_log2 (zap_dnode->dn_datablkszsec) + DNODE_SHIFT;
grub_err_t err;
- grub_zfs_endian_t endian;
grub_size_t sz;
- if (zap_verify (zap, zap_dnode->endian))
+ if (zap_verify (zap))
return 0;
/* get block id from index */
@@ -2461,17 +2663,15 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap,
}
for (idx = 0; idx < (1ULL << zap->zap_ptrtbl.zt_shift); idx++)
{
- blkid = grub_zfs_to_cpu64 (((grub_uint64_t *) zap)[idx + (1 << (blksft -
3 - 1))],
- zap_dnode->endian);
+ blkid = ((grub_uint64_t *) zap)[idx + (1 << (blksft - 3 - 1))];
for (idx2 = 0; idx2 < idx; idx2++)
- if (blkid == grub_zfs_to_cpu64 (((grub_uint64_t *) zap)[idx2 + (1 <<
(blksft - 3 - 1))],
- zap_dnode->endian))
+ if (blkid == ((grub_uint64_t *) zap)[idx2 + (1 << (blksft - 3 - 1))])
break;
if (idx2 != idx)
continue;
- err = dmu_read (zap_dnode, blkid, &l_in, &endian, data);
+ err = dmu_read (zap_dnode, blkid, &l_in, data);
l = l_in;
if (err)
{
@@ -2480,12 +2680,12 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap,
}
/* Verify if this is a valid leaf block */
- if (grub_zfs_to_cpu64 (l->l_hdr.lh_block_type, endian) != ZBT_LEAF)
+ if (l->l_hdr.lh_block_type != ZBT_LEAF)
{
grub_free (l);
continue;
}
- if (grub_zfs_to_cpu32 (l->l_hdr.lh_magic, endian) != ZAP_LEAF_MAGIC)
+ if (l->l_hdr.lh_magic != ZAP_LEAF_MAGIC)
{
grub_free (l);
continue;
@@ -2503,7 +2703,7 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap,
if (le->le_type != ZAP_CHUNK_ENTRY)
continue;
- if (grub_mul (grub_zfs_to_cpu16 (le->le_name_length, endian),
name_elem_length, &sz) ||
+ if (grub_mul (le->le_name_length, name_elem_length, &sz) ||
grub_add (sz, 1, &sz))
{
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("buffer size overflow"));
@@ -2516,11 +2716,9 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap,
grub_free (l);
return grub_errno;
}
- if (zap_leaf_array_get (l, endian, blksft,
- grub_zfs_to_cpu16 (le->le_name_chunk,
- endian),
- grub_zfs_to_cpu16 (le->le_name_length,
- endian)
+ if (zap_leaf_array_get (l, blksft,
+ le->le_name_chunk,
+ le->le_name_length
* name_elem_length, buf))
{
grub_free (buf);
@@ -2530,16 +2728,15 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap,
val_length = ((int) le->le_value_length
* (int) le->le_int_size);
- val = grub_malloc (grub_zfs_to_cpu16 (val_length, endian));
+ val = grub_malloc (val_length);
if (!val)
{
grub_free (l);
grub_free (buf);
return grub_errno;
}
- if (zap_leaf_array_get (l, endian, blksft,
- grub_zfs_to_cpu16 (le->le_value_chunk,
- endian),
+ if (zap_leaf_array_get (l, blksft,
+ le->le_value_chunk,
val_length, val))
{
grub_free (buf);
@@ -2567,32 +2764,29 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap,
*
*/
static grub_err_t
-zap_lookup (dnode_end_t * zap_dnode, const char *name, grub_uint64_t *val,
+zap_lookup (dnode_phys_t * zap_dnode, const char *name, grub_uint64_t *val,
struct grub_zfs_data *data, int case_insensitive)
{
grub_uint64_t block_type;
grub_uint32_t size;
void *zapbuf;
grub_err_t err;
- grub_zfs_endian_t endian;
grub_dprintf ("zfs", "looking for '%s'\n", name);
/* Read in the first block of the zap object data. */
- size = (grub_uint32_t) grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec,
- zap_dnode->endian) << SPA_MINBLOCKSHIFT;
- err = dmu_read (zap_dnode, 0, &zapbuf, &endian, data);
+ size = (grub_uint32_t) zap_dnode->dn_datablkszsec << SPA_MINBLOCKSHIFT;
+ err = dmu_read (zap_dnode, 0, &zapbuf, data);
if (err)
return err;
- block_type = grub_zfs_to_cpu64 (*((grub_uint64_t *) zapbuf), endian);
+ block_type = *((grub_uint64_t *) zapbuf);
grub_dprintf ("zfs", "zap read\n");
if (block_type == ZBT_MICRO)
{
grub_dprintf ("zfs", "micro zap\n");
- err = mzap_lookup (zapbuf, endian, size, name, val,
- case_insensitive);
+ err = mzap_lookup (zapbuf, size, name, val, case_insensitive);
grub_dprintf ("zfs", "returned %d\n", err);
grub_free (zapbuf);
return err;
@@ -2637,7 +2831,7 @@ zap_iterate_u64_transform (const void *name,
}
static int
-zap_iterate_u64 (dnode_end_t * zap_dnode,
+zap_iterate_u64 (dnode_phys_t * zap_dnode,
int (*hook) (const char *name, grub_uint64_t val,
struct grub_zfs_dir_ctx *ctx),
struct grub_zfs_data *data, struct grub_zfs_dir_ctx *ctx)
@@ -2647,21 +2841,20 @@ zap_iterate_u64 (dnode_end_t * zap_dnode,
void *zapbuf;
grub_err_t err;
int ret;
- grub_zfs_endian_t endian;
/* Read in the first block of the zap object data. */
- size = grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec, zap_dnode->endian)
<< SPA_MINBLOCKSHIFT;
- err = dmu_read (zap_dnode, 0, &zapbuf, &endian, data);
+ size = zap_dnode->dn_datablkszsec << SPA_MINBLOCKSHIFT;
+ err = dmu_read (zap_dnode, 0, &zapbuf, data);
if (err)
return 0;
- block_type = grub_zfs_to_cpu64 (*((grub_uint64_t *) zapbuf), endian);
+ block_type = *((grub_uint64_t *) zapbuf);
grub_dprintf ("zfs", "zap iterate\n");
if (block_type == ZBT_MICRO)
{
grub_dprintf ("zfs", "micro zap\n");
- ret = mzap_iterate (zapbuf, endian, size, hook, ctx);
+ ret = mzap_iterate (zapbuf, size, hook, ctx);
grub_free (zapbuf);
return ret;
}
@@ -2685,7 +2878,7 @@ zap_iterate_u64 (dnode_end_t * zap_dnode,
}
static int
-zap_iterate (dnode_end_t * zap_dnode,
+zap_iterate (dnode_phys_t * zap_dnode,
grub_size_t nameelemlen,
int (*hook) (const void *name, grub_size_t namelen,
const void *val_in,
@@ -2697,13 +2890,12 @@ zap_iterate (dnode_end_t * zap_dnode,
void *zapbuf;
grub_err_t err;
int ret;
- grub_zfs_endian_t endian;
/* Read in the first block of the zap object data. */
- err = dmu_read (zap_dnode, 0, &zapbuf, &endian, data);
+ err = dmu_read (zap_dnode, 0, &zapbuf, data);
if (err)
return 0;
- block_type = grub_zfs_to_cpu64 (*((grub_uint64_t *) zapbuf), endian);
+ block_type = *((grub_uint64_t *) zapbuf);
grub_dprintf ("zfs", "zap iterate\n");
@@ -2737,20 +2929,18 @@ zap_iterate (dnode_end_t * zap_dnode,
* buf - data buffer that holds the returning dnode
*/
static grub_err_t
-dnode_get (dnode_end_t * mdn, grub_uint64_t objnum, grub_uint8_t type,
- dnode_end_t * buf, struct grub_zfs_data *data)
+dnode_get (dnode_phys_t * mdn, grub_uint64_t objnum, grub_uint8_t type,
+ dnode_phys_t * buf, struct grub_zfs_data *data)
{
grub_uint64_t blkid, blksz; /* the block id this object dnode is in */
int epbs; /* shift of number of dnodes in a block */
int idx; /* index within a block */
void *dnbuf;
grub_err_t err;
- grub_zfs_endian_t endian;
objnum &= DNODE_NUM_MASK;
- blksz = grub_zfs_to_cpu16 (mdn->dn.dn_datablkszsec,
- mdn->endian) << SPA_MINBLOCKSHIFT;
+ blksz = mdn->dn_datablkszsec << SPA_MINBLOCKSHIFT;
epbs = zfs_log2 (blksz) - DNODE_SHIFT;
/* While this should never happen, we should check that epbs is not
negative. */
@@ -2760,22 +2950,23 @@ dnode_get (dnode_end_t * mdn, grub_uint64_t objnum,
grub_uint8_t type,
blkid = objnum >> epbs;
idx = objnum & ((1 << epbs) - 1);
- if (data->dnode_buf != NULL && grub_memcmp (data->dnode_mdn, &mdn->dn,
- sizeof (mdn->dn)) == 0
+ if (data->dnode_buf != NULL && grub_memcmp (data->dnode_mdn, mdn,
+ sizeof (*mdn)) == 0
&& objnum >= data->dnode_start && objnum < data->dnode_end)
{
- grub_memmove (&(buf->dn), &(data->dnode_buf)[idx], DNODE_SIZE);
- buf->endian = data->dnode_endian;
- if (type && buf->dn.dn_type != type)
+ *buf = (data->dnode_buf)[idx];
+ if (type && buf->dn_type != type)
return grub_error(GRUB_ERR_BAD_FS, "incorrect dnode type");
return GRUB_ERR_NONE;
}
- grub_dprintf ("zfs", "endian = %d, blkid=%llx\n", mdn->endian,
+ grub_dprintf ("zfs", "blkid=%llx\n",
(unsigned long long) blkid);
- err = dmu_read (mdn, blkid, &dnbuf, &endian, data);
+ err = dmu_read (mdn, blkid, &dnbuf, data);
if (err)
return err;
+ if (dnbuf == NULL)
+ return grub_error(GRUB_ERR_BAD_FS, "invalid or unavailable dnode");
grub_dprintf ("zfs", "alive\n");
grub_free (data->dnode_buf);
@@ -2792,15 +2983,10 @@ dnode_get (dnode_end_t * mdn, grub_uint64_t objnum,
grub_uint8_t type,
data->dnode_buf = dnbuf;
data->dnode_start = blkid << epbs;
data->dnode_end = (blkid + 1) << epbs;
- data->dnode_endian = endian;
}
- grub_memmove (&(buf->dn), (dnode_phys_t *) dnbuf + idx, DNODE_SIZE);
- if (data->dnode_buf == 0)
- /* dnbuf not used anymore if data->dnode_mdn malloc failed */
- grub_free (dnbuf);
- buf->endian = endian;
- if (type && buf->dn.dn_type != type)
+ *buf = ((dnode_phys_t *) dnbuf)[idx];
+ if (type && buf->dn_type != type)
return grub_error(GRUB_ERR_BAD_FS, "incorrect dnode type");
return GRUB_ERR_NONE;
@@ -2815,7 +3001,7 @@ dnode_get (dnode_end_t * mdn, grub_uint64_t objnum,
grub_uint8_t type,
*
*/
static grub_err_t
-dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn,
+dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_phys_t
*dn,
struct grub_zfs_data *data)
{
grub_uint64_t objnum, version;
@@ -2825,7 +3011,7 @@ dnode_get_path (struct subvolume *subvol, const char
*path_in, dnode_end_t *dn,
struct dnode_chain
{
struct dnode_chain *next;
- dnode_end_t dn;
+ dnode_phys_t dn;
};
struct dnode_chain *dnode_path = 0, *dn_new, *root;
@@ -2922,7 +3108,7 @@ dnode_get_path (struct subvolume *subvol, const char
*path_in, dnode_end_t *dn,
ch = *path;
*path = 0; /* ensure null termination */
- if (dnode_path->dn.dn.dn_type != DMU_OT_DIRECTORY_CONTENTS)
+ if (dnode_path->dn.dn_type != DMU_OT_DIRECTORY_CONTENTS)
{
err = grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
break;
@@ -2947,25 +3133,23 @@ dnode_get_path (struct subvolume *subvol, const char
*path_in, dnode_end_t *dn,
break;
*path = ch;
- if (dnode_path->dn.dn.dn_bonustype == DMU_OT_ZNODE
- && ((grub_zfs_to_cpu64(((znode_phys_t *) DN_BONUS
(&dnode_path->dn.dn))->zp_mode, dnode_path->dn.endian) >> 12) & 0xf) == 0xa)
+ if (dnode_path->dn.dn_bonustype == DMU_OT_ZNODE
+ && (((((znode_phys_t *) DN_BONUS (&dnode_path->dn))->zp_mode) >> 12)
& 0xf) == 0xa)
{
char *sym_value;
grub_size_t sz;
grub_size_t sym_sz;
int free_symval = 0;
char *oldpath = path, *oldpathbuf = path_buf;
- sym_value = ((char *) DN_BONUS (&dnode_path->dn.dn) + sizeof (struct
znode_phys));
+ sym_value = ((char *) DN_BONUS (&dnode_path->dn) + sizeof (struct
znode_phys));
- sym_sz = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS
(&dnode_path->dn.dn))->zp_size, dnode_path->dn.endian);
+ sym_sz = ((znode_phys_t *) DN_BONUS (&dnode_path->dn))->zp_size;
- if (dnode_path->dn.dn.dn_flags & 1)
+ if (dnode_path->dn.dn_flags & 1)
{
grub_size_t block;
grub_size_t blksz;
- blksz = (grub_zfs_to_cpu16 (dnode_path->dn.dn.dn_datablkszsec,
- dnode_path->dn.endian)
- << SPA_MINBLOCKSHIFT);
+ blksz = dnode_path->dn.dn_datablkszsec << SPA_MINBLOCKSHIFT;
if (blksz == 0)
{
@@ -2985,7 +3169,7 @@ dnode_get_path (struct subvolume *subvol, const char
*path_in, dnode_end_t *dn,
void *t;
grub_size_t movesize;
- err = dmu_read (&(dnode_path->dn), block, &t, 0, data);
+ err = dmu_read (&(dnode_path->dn), block, &t, data);
if (err)
{
grub_free (sym_value);
@@ -3047,22 +3231,22 @@ dnode_get_path (struct subvolume *subvol, const char
*path_in, dnode_end_t *dn,
}
dn_new = dnode_path;
}
- if (dnode_path->dn.dn.dn_bonustype == DMU_OT_SA)
+ if (dnode_path->dn.dn_bonustype == DMU_OT_SA)
{
void *sahdrp;
int hdrsize;
grub_size_t sz;
bool free_sahdrp = false;
- if (dnode_path->dn.dn.dn_bonuslen != 0)
+ if (dnode_path->dn.dn_bonuslen != 0)
{
- sahdrp = DN_BONUS (&dnode_path->dn.dn);
+ sahdrp = DN_BONUS (&dnode_path->dn);
}
- else if (dnode_path->dn.dn.dn_flags & DNODE_FLAG_SPILL_BLKPTR)
+ else if (dnode_path->dn.dn_flags & DNODE_FLAG_SPILL_BLKPTR)
{
- blkptr_t *bp = &dnode_path->dn.dn.dn_spill;
+ blkptr_t *bp = &dnode_path->dn.dn_spill;
- err = zio_read (bp, dnode_path->dn.endian, &sahdrp, NULL, data);
+ err = zio_read (bp, &sahdrp, NULL, data);
if (err)
break;
free_sahdrp = true;
@@ -3075,17 +3259,14 @@ dnode_get_path (struct subvolume *subvol, const char
*path_in, dnode_end_t *dn,
hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp));
- if (((grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp
- + hdrsize
- + SA_TYPE_OFFSET),
- dnode_path->dn.endian) >> 12) & 0xf) == 0xa)
+ if (((grub_get_unaligned64 ((char *) sahdrp
+ + hdrsize
+ + SA_TYPE_OFFSET) >> 12) & 0xf) == 0xa)
{
char *sym_value = (char *) sahdrp + hdrsize + SA_SYMLINK_OFFSET;
- grub_size_t sym_sz =
- grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp
+ grub_size_t sym_sz = grub_get_unaligned64 ((char *) sahdrp
+ hdrsize
- + SA_SIZE_OFFSET),
- dnode_path->dn.endian);
+ + SA_SIZE_OFFSET);
char *oldpath = path, *oldpathbuf = path_buf;
if (grub_add (sym_sz, grub_strlen (oldpath), &sz) ||
grub_add (sz, 1, &sz))
@@ -3205,14 +3386,12 @@ get_default_bootfsobj (dnode_phys_t * mosmdn,
grub_uint64_t * obj,
*
*/
static grub_err_t
-get_filesystem_dnode (dnode_end_t * mosmdn, char *fsname,
- dnode_end_t * mdn, struct grub_zfs_data *data)
+get_filesystem_dnode (dnode_phys_t * mosmdn, char *fsname,
+ dnode_phys_t * mdn, struct grub_zfs_data *data)
{
grub_uint64_t objnum;
grub_err_t err;
- grub_dprintf ("zfs", "endian = %d\n", mosmdn->endian);
-
err = dnode_get (mosmdn, DMU_POOL_DIRECTORY_OBJECT,
DMU_OT_OBJECT_DIRECTORY, mdn, data);
if (err)
@@ -3249,7 +3428,7 @@ get_filesystem_dnode (dnode_end_t * mosmdn, char *fsname,
ch = *fsname;
*fsname = 0;
- childobj = grub_zfs_to_cpu64 ((((dsl_dir_phys_t *) DN_BONUS
(&mdn->dn)))->dd_child_dir_zapobj, mdn->endian);
+ childobj = (((dsl_dir_phys_t *) DN_BONUS (mdn)))->dd_child_dir_zapobj;
err = dnode_get (mosmdn, childobj,
DMU_OT_DSL_DIR_CHILD_MAP, mdn, data);
if (err)
@@ -3269,17 +3448,15 @@ get_filesystem_dnode (dnode_end_t * mosmdn, char
*fsname,
}
static grub_err_t
-make_mdn (dnode_end_t * mdn, struct grub_zfs_data *data)
+make_mdn (dnode_phys_t * mdn, struct grub_zfs_data *data)
{
objset_phys_t *osp;
blkptr_t *bp;
grub_size_t ospsize = 0;
grub_err_t err;
- grub_dprintf ("zfs", "endian = %d\n", mdn->endian);
-
- bp = &(((dsl_dataset_phys_t *) DN_BONUS (&mdn->dn))->ds_bp);
- err = zio_read (bp, mdn->endian, (void **) &osp, &ospsize, data);
+ bp = &(((dsl_dataset_phys_t *) DN_BONUS (mdn))->ds_bp);
+ err = zio_read (bp, (void **) &osp, &ospsize, data);
if (err)
return err;
if (ospsize < OBJSET_PHYS_SIZE_V14)
@@ -3288,9 +3465,7 @@ make_mdn (dnode_end_t * mdn, struct grub_zfs_data *data)
return grub_error (GRUB_ERR_BAD_FS, "too small osp");
}
- mdn->endian = (grub_zfs_to_cpu64 (bp->blk_prop, mdn->endian)>>63) & 1;
- grub_memmove ((char *) &(mdn->dn),
- (char *) &(osp)->os_meta_dnode, DNODE_SIZE);
+ *mdn = (osp)->os_meta_dnode;
grub_free (osp);
return GRUB_ERR_NONE;
}
@@ -3352,7 +3527,7 @@ load_zap_key (const void *name, grub_size_t namelen,
const void *val_in,
static grub_err_t
dnode_get_fullpath (const char *fullpath, struct subvolume *subvol,
- dnode_end_t * dn, int *isfs,
+ dnode_phys_t * dn, int *isfs,
struct grub_zfs_data *data)
{
char *fsname, *snapname;
@@ -3412,9 +3587,7 @@ dnode_get_fullpath (const char *fullpath, struct
subvolume *subvol,
grub_dprintf ("zfs", "alive\n");
- headobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS
(&dn->dn))->dd_head_dataset_obj, dn->endian);
-
- grub_dprintf ("zfs", "endian = %d\n", subvol->mdn.endian);
+ headobj = ((dsl_dir_phys_t *) DN_BONUS (dn))->dd_head_dataset_obj;
err = dnode_get (&(data->mos), headobj, 0, &subvol->mdn, data);
if (err)
@@ -3423,18 +3596,19 @@ dnode_get_fullpath (const char *fullpath, struct
subvolume *subvol,
grub_free (snapname);
return err;
}
- grub_dprintf ("zfs", "endian = %d\n", subvol->mdn.endian);
+ keychainobj = ((dsl_dir_phys_t *) DN_BONUS (dn))->keychain;
+
+ grub_dprintf("zfs", "keychain obj = %lld\n", (long long) keychainobj);
- keychainobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS
(&dn->dn))->keychain, dn->endian);
- if (grub_zfs_load_key && keychainobj)
+ if (grub_zfs_decrypt && keychainobj)
{
struct dnode_get_fullpath_ctx ctx = {
.subvol = subvol,
.keyn = 0
};
- dnode_end_t keychain_dn, props_dn;
+ dnode_phys_t keychain_dn, props_dn;
grub_uint64_t propsobj;
- propsobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS
(&dn->dn))->dd_props_zapobj, dn->endian);
+ propsobj = ((dsl_dir_phys_t *) DN_BONUS (dn))->dd_props_zapobj;
err = dnode_get (&(data->mos), propsobj, DMU_OT_DSL_PROPS,
&props_dn, data);
@@ -3484,7 +3658,7 @@ dnode_get_fullpath (const char *fullpath, struct
subvolume *subvol,
{
grub_uint64_t snapobj;
- snapobj = grub_zfs_to_cpu64 (((dsl_dataset_phys_t *) DN_BONUS
(&subvol->mdn.dn))->ds_snapnames_zapobj, subvol->mdn.endian);
+ snapobj = ((dsl_dataset_phys_t *) DN_BONUS
(&subvol->mdn))->ds_snapnames_zapobj;
err = dnode_get (&(data->mos), snapobj,
DMU_OT_DSL_DS_SNAP_MAP, &subvol->mdn, data);
@@ -3493,7 +3667,7 @@ dnode_get_fullpath (const char *fullpath, struct
subvolume *subvol,
if (!err)
err = dnode_get (&(data->mos), headobj, 0,
&subvol->mdn, data);
- if (!err && subvol->mdn.dn.dn_type != DMU_OT_DSL_DATASET &&
subvol->mdn.dn.dn_bonustype != DMU_OT_DSL_DATASET) {
+ if (!err && subvol->mdn.dn_type != DMU_OT_DSL_DATASET &&
subvol->mdn.dn_bonustype != DMU_OT_DSL_DATASET) {
grub_free (fsname);
grub_free (snapname);
return grub_error(GRUB_ERR_BAD_FS, "incorrect dataset dnode type");
@@ -3511,8 +3685,6 @@ dnode_get_fullpath (const char *fullpath, struct
subvolume *subvol,
make_mdn (&subvol->mdn, data);
- grub_dprintf ("zfs", "endian = %d\n", subvol->mdn.endian);
-
if (*isfs)
{
grub_free (fsname);
@@ -3776,7 +3948,6 @@ zfs_mount (grub_device_t dev)
grub_err_t err;
objset_phys_t *osp = 0;
grub_size_t ospsize;
- grub_zfs_endian_t ub_endian = GRUB_ZFS_UNKNOWN_ENDIAN;
uberblock_t *ub;
int inserted;
@@ -3812,11 +3983,8 @@ zfs_mount (grub_device_t dev)
}
ub = &(data->current_uberblock);
- ub_endian = (grub_zfs_to_cpu64 (ub->ub_magic,
- GRUB_ZFS_LITTLE_ENDIAN) == UBERBLOCK_MAGIC
- ? GRUB_ZFS_LITTLE_ENDIAN : GRUB_ZFS_BIG_ENDIAN);
- err = zio_read (&ub->ub_rootbp, ub_endian,
+ err = zio_read (&ub->ub_rootbp,
(void **) &osp, &ospsize, data);
if (err)
{
@@ -3833,7 +4001,7 @@ zfs_mount (grub_device_t dev)
}
if (ub->ub_version >= SPA_VERSION_FEATURES &&
- check_mos_features(&osp->os_meta_dnode, ub_endian, data) != 0)
+ check_mos_features(&osp->os_meta_dnode, data) != 0)
{
grub_error (GRUB_ERR_BAD_FS, "Unsupported features in pool");
grub_free (osp);
@@ -3842,9 +4010,7 @@ zfs_mount (grub_device_t dev)
}
/* Got the MOS. Save it at the memory addr MOS. */
- grub_memmove (&(data->mos.dn), &osp->os_meta_dnode, DNODE_SIZE);
- data->mos.endian = (grub_zfs_to_cpu64 (ub->ub_rootbp.blk_prop,
- ub_endian) >> 63) & 1;
+ grub_memmove (&(data->mos), &osp->os_meta_dnode, DNODE_SIZE);
grub_free (osp);
return data;
@@ -3910,8 +4076,6 @@ static grub_err_t
zfs_mtime (grub_device_t device, grub_int64_t *mt)
{
struct grub_zfs_data *data;
- grub_zfs_endian_t ub_endian = GRUB_ZFS_UNKNOWN_ENDIAN;
- uberblock_t *ub;
*mt = 0;
@@ -3919,16 +4083,48 @@ zfs_mtime (grub_device_t device, grub_int64_t *mt)
if (! data)
return grub_errno;
- ub = &(data->current_uberblock);
- ub_endian = (grub_zfs_to_cpu64 (ub->ub_magic,
- GRUB_ZFS_LITTLE_ENDIAN) == UBERBLOCK_MAGIC
- ? GRUB_ZFS_LITTLE_ENDIAN : GRUB_ZFS_BIG_ENDIAN);
-
- *mt = grub_zfs_to_cpu64 (ub->ub_timestamp, ub_endian);
+ *mt = data->current_uberblock.ub_timestamp;
zfs_unmount (data);
return GRUB_ERR_NONE;
}
+static grub_err_t
+parse_sa(const dnode_phys_t *dn, grub_int64_t *mtime, grub_uint64_t *sz,
+ struct grub_zfs_data *data)
+{
+ void *sahdrp;
+ int hdrsize;
+ grub_zfs_endian_t sa_endian;
+
+ if (dn->dn_bonuslen != 0)
+ sahdrp = (sa_hdr_phys_t *) DN_BONUS (dn);
+ else if (dn->dn_flags & DNODE_FLAG_SPILL_BLKPTR)
+ {
+ const blkptr_t *bp = &dn->dn_spill;
+
+ grub_err_t err = zio_read (bp, &sahdrp, NULL, data);
+ if (err)
+ return err;
+ }
+ else
+ return GRUB_ERR_NONE;
+
+ if (grub_zfs_to_cpu32(((sa_hdr_phys_t *) sahdrp)->sa_magic,
GRUB_ZFS_LITTLE_ENDIAN) == SA_MAGIC)
+ sa_endian = GRUB_ZFS_LITTLE_ENDIAN;
+ else if (grub_zfs_to_cpu32(((sa_hdr_phys_t *) sahdrp)->sa_magic,
GRUB_ZFS_BIG_ENDIAN) == SA_MAGIC)
+ sa_endian = GRUB_ZFS_BIG_ENDIAN;
+ else
+ return GRUB_ERR_NONE;
+
+ hdrsize = (grub_zfs_to_cpu16(((sa_hdr_phys_t *) sahdrp)->sa_layout_info,
sa_endian) >> 10) << 3;
+ if (mtime)
+ *mtime = grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp +
hdrsize + SA_MTIME_OFFSET), sa_endian);
+ if (sz)
+ *sz = grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp + hdrsize +
SA_SIZE_OFFSET), sa_endian);
+
+ return GRUB_ERR_NONE;
+}
+
/*
* zfs_open() locates a file in the rootpool by following the
* MOS and places the dnode of the file in the memory address DNODE.
@@ -3959,7 +4155,7 @@ grub_zfs_open (struct grub_file *file, const char
*fsfilename)
}
/* We found the dnode for this file. Verify if it is a plain file. */
- if (data->dnode.dn.dn_type != DMU_OT_PLAIN_FILE_CONTENTS)
+ if (data->dnode.dn_type != DMU_OT_PLAIN_FILE_CONTENTS)
{
zfs_unmount (data);
return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a regular file"));
@@ -3972,38 +4168,17 @@ grub_zfs_open (struct grub_file *file, const char
*fsfilename)
* attribute, which could be either in the bonus buffer
* or the "spill" block.
*/
- if (data->dnode.dn.dn_bonustype == DMU_OT_SA)
+ if (data->dnode.dn_bonustype == DMU_OT_SA)
{
- void *sahdrp;
- int hdrsize;
- bool free_sahdrp = false;
-
- if (data->dnode.dn.dn_bonuslen != 0)
- {
- sahdrp = (sa_hdr_phys_t *) DN_BONUS (&data->dnode.dn);
- }
- else if (data->dnode.dn.dn_flags & DNODE_FLAG_SPILL_BLKPTR)
- {
- blkptr_t *bp = &data->dnode.dn.dn_spill;
-
- err = zio_read (bp, data->dnode.endian, &sahdrp, NULL, data);
- if (err)
- return err;
- free_sahdrp = true;
- }
- else
- {
- return grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt");
- }
-
- hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp));
- file->size = grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp +
hdrsize + SA_SIZE_OFFSET), data->dnode.endian);
- if (free_sahdrp)
- grub_free(sahdrp);
+ grub_uint64_t fsize;
+ err = parse_sa(&data->dnode, NULL, &fsize, data);
+ if (err)
+ return err;
+ file->size = fsize;
}
- else if (data->dnode.dn.dn_bonustype == DMU_OT_ZNODE)
+ else if (data->dnode.dn_bonustype == DMU_OT_ZNODE)
{
- file->size = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS
(&data->dnode.dn))->zp_size, data->dnode.endian);
+ file->size = ((znode_phys_t *) DN_BONUS (&data->dnode))->zp_size;
}
else
return grub_error (GRUB_ERR_BAD_FS, "bad bonus type");
@@ -4038,8 +4213,7 @@ grub_zfs_read (grub_file_t file, char *buf, grub_size_t
len)
return len;
}
- blksz = grub_zfs_to_cpu16 (data->dnode.dn.dn_datablkszsec,
- data->dnode.endian) << SPA_MINBLOCKSHIFT;
+ blksz = data->dnode.dn_datablkszsec << SPA_MINBLOCKSHIFT;
if (blksz == 0)
{
@@ -4065,8 +4239,7 @@ grub_zfs_read (grub_file_t file, char *buf, grub_size_t
len)
grub_free (data->file_buf);
data->file_buf = 0;
- err = dmu_read (&(data->dnode), blkid, &t,
- 0, data);
+ err = dmu_read (&(data->dnode), blkid, &t, data);
data->file_buf = t;
if (err)
{
@@ -4125,19 +4298,19 @@ grub_zfs_getmdnobj (grub_device_t dev, const char
*fsfilename,
/*
* Note: fill_fs_info() uses functions such as make_mdn() that modify
- * the input dnode_end_t parameter. However, we should not allow it.
+ * the input dnode_phys_t parameter. However, we should not allow it.
* Therefore, we are making mdn_in constant - fill_fs_info() makes
* a local copy of it.
*/
static grub_err_t
fill_fs_info (struct grub_dirhook_info *info,
- const dnode_end_t *mdn_in, struct grub_zfs_data *data)
+ const dnode_phys_t *mdn_in, struct grub_zfs_data *data)
{
grub_err_t err;
- dnode_end_t dn;
+ dnode_phys_t dn;
grub_uint64_t objnum;
grub_uint64_t headobj;
- dnode_end_t mdn;
+ dnode_phys_t mdn;
grub_memcpy (&mdn, mdn_in, sizeof (*mdn_in));
@@ -4145,9 +4318,9 @@ fill_fs_info (struct grub_dirhook_info *info,
info->dir = 1;
- if (mdn.dn.dn_type == DMU_OT_DSL_DIR || mdn.dn.dn_bonustype ==
DMU_OT_DSL_DIR)
+ if (mdn.dn_type == DMU_OT_DSL_DIR || mdn.dn_bonustype == DMU_OT_DSL_DIR)
{
- headobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS
(&mdn.dn))->dd_head_dataset_obj, mdn.endian);
+ headobj = ((dsl_dir_phys_t *) DN_BONUS (&mdn))->dd_head_dataset_obj;
err = dnode_get (&(data->mos), headobj, 0, &mdn, data);
if (err)
@@ -4181,42 +4354,18 @@ fill_fs_info (struct grub_dirhook_info *info,
return err;
}
- if (dn.dn.dn_bonustype == DMU_OT_SA)
+ if (dn.dn_bonustype == DMU_OT_SA)
{
- void *sahdrp;
- int hdrsize;
- bool free_sahdrp = false;
-
- if (dn.dn.dn_bonuslen != 0)
- {
- sahdrp = (sa_hdr_phys_t *) DN_BONUS (&dn.dn);
- }
- else if (dn.dn.dn_flags & DNODE_FLAG_SPILL_BLKPTR)
- {
- blkptr_t *bp = &dn.dn.dn_spill;
-
- err = zio_read (bp, dn.endian, &sahdrp, NULL, data);
- if (err)
- return err;
- free_sahdrp = true;
- }
- else
- {
- grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt");
- return grub_errno;
- }
-
- hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp));
+ err = parse_sa(&dn, &info->mtime, NULL, data);
+ if (err)
+ return err;
info->mtimeset = 1;
- info->mtime = grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp +
hdrsize + SA_MTIME_OFFSET), dn.endian);
- if (free_sahdrp)
- grub_free (sahdrp);
}
- if (dn.dn.dn_bonustype == DMU_OT_ZNODE)
+ if (dn.dn_bonustype == DMU_OT_ZNODE)
{
info->mtimeset = 1;
- info->mtime = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS
(&dn.dn))->zp_mtime[0], dn.endian);
+ info->mtime = ((znode_phys_t *) DN_BONUS (&dn))->zp_mtime[0];
}
return 0;
}
@@ -4228,7 +4377,7 @@ iterate_zap (const char *name, grub_uint64_t val, struct
grub_zfs_dir_ctx *ctx)
grub_err_t err;
struct grub_dirhook_info info;
- dnode_end_t dn;
+ dnode_phys_t dn;
grub_memset (&info, 0, sizeof (info));
err = dnode_get (&(ctx->data->subvol.mdn), val, 0, &dn, ctx->data);
@@ -4238,52 +4387,22 @@ iterate_zap (const char *name, grub_uint64_t val,
struct grub_zfs_dir_ctx *ctx)
return 0;
}
- if (dn.dn.dn_bonustype == DMU_OT_SA)
+ if (dn.dn_bonustype == DMU_OT_SA)
{
- void *sahdrp;
- int hdrsize;
- bool free_sahdrp = false;
-
- if (dn.dn.dn_bonuslen != 0)
- {
- sahdrp = (sa_hdr_phys_t *) DN_BONUS (&ctx->data->dnode.dn);
- }
- else if (dn.dn.dn_flags & DNODE_FLAG_SPILL_BLKPTR)
- {
- blkptr_t *bp = &dn.dn.dn_spill;
-
- err = zio_read (bp, dn.endian, &sahdrp, NULL, ctx->data);
- if (err)
- {
- grub_print_error ();
- return 0;
- }
- free_sahdrp = true;
- }
- else
- {
- grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt");
- grub_print_error ();
- return 0;
- }
-
- hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp));
+ err = parse_sa(&dn, &info.mtime, NULL, ctx->data);
+ if (err)
+ return err;
info.mtimeset = 1;
- info.mtime = grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp +
hdrsize + SA_MTIME_OFFSET), dn.endian);
- info.case_insensitive = ctx->data->subvol.case_insensitive;
- if (free_sahdrp)
- grub_free (sahdrp);
}
- if (dn.dn.dn_bonustype == DMU_OT_ZNODE)
+ if (dn.dn_bonustype == DMU_OT_ZNODE)
{
info.mtimeset = 1;
- info.mtime = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS
(&dn.dn))->zp_mtime[0],
- dn.endian);
+ info.mtime = ((znode_phys_t *) DN_BONUS (&dn))->zp_mtime[0];
}
- info.dir = (dn.dn.dn_type == DMU_OT_DIRECTORY_CONTENTS);
+ info.dir = (dn.dn_type == DMU_OT_DIRECTORY_CONTENTS);
grub_dprintf ("zfs", "type=%d, name=%s\n",
- (int)dn.dn.dn_type, (char *)name);
+ (int)dn.dn_type, (char *)name);
return ctx->hook (name, &info, ctx->hook_data);
}
@@ -4298,15 +4417,15 @@ iterate_zap_fs (const char *name, grub_uint64_t val,
if (name[0] == 0 && val == 0)
return 0;
- dnode_end_t mdn;
+ dnode_phys_t mdn;
err = dnode_get (&(ctx->data->mos), val, 0, &mdn, ctx->data);
if (err)
{
grub_errno = 0;
return 0;
}
- if (mdn.dn.dn_type != DMU_OT_DSL_DIR && mdn.dn.dn_bonustype !=
DMU_OT_DSL_DIR) {
- grub_dprintf ("zfs", "type = 0x%x, val = 0x%llx\n", mdn.dn.dn_type, (long
long)val);
+ if (mdn.dn_type != DMU_OT_DSL_DIR && mdn.dn_bonustype != DMU_OT_DSL_DIR) {
+ grub_dprintf ("zfs", "type = 0x%x, val = 0x%llx\n", mdn.dn_type, (long
long)val);
return 0;
}
@@ -4330,7 +4449,7 @@ iterate_zap_snap (const char *name, grub_uint64_t val,
int ret;
grub_size_t sz;
- dnode_end_t mdn;
+ dnode_phys_t mdn;
err = dnode_get (&(ctx->data->mos), val, 0, &mdn, ctx->data);
if (err)
@@ -4339,7 +4458,7 @@ iterate_zap_snap (const char *name, grub_uint64_t val,
return 0;
}
- if (mdn.dn.dn_type != DMU_OT_DSL_DATASET && mdn.dn.dn_bonustype !=
DMU_OT_DSL_DATASET)
+ if (mdn.dn_type != DMU_OT_DSL_DATASET && mdn.dn_bonustype !=
DMU_OT_DSL_DATASET)
return 0;
err = fill_fs_info (&info, &mdn, ctx->data);
@@ -4390,7 +4509,7 @@ grub_zfs_dir (grub_device_t device, const char *path,
{
grub_uint64_t childobj, headobj;
grub_uint64_t snapobj;
- dnode_end_t dn;
+ dnode_phys_t dn;
struct grub_dirhook_info info;
err = fill_fs_info (&info, &data->dnode, data);
@@ -4405,8 +4524,8 @@ grub_zfs_dir (grub_device_t device, const char *path,
return GRUB_ERR_NONE;
}
- childobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS
(&data->dnode.dn))->dd_child_dir_zapobj, data->dnode.endian);
- headobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS
(&data->dnode.dn))->dd_head_dataset_obj, data->dnode.endian);
+ childobj = ((dsl_dir_phys_t *) DN_BONUS
(&data->dnode))->dd_child_dir_zapobj;
+ headobj = ((dsl_dir_phys_t *) DN_BONUS
(&data->dnode))->dd_head_dataset_obj;
err = dnode_get (&(data->mos), childobj,
DMU_OT_DSL_DIR_CHILD_MAP, &dn, data);
if (err)
@@ -4418,7 +4537,7 @@ grub_zfs_dir (grub_device_t device, const char *path,
zap_iterate_u64 (&dn, iterate_zap_fs, data, &ctx);
err = dnode_get (&(data->mos), headobj, 0, &dn, data);
- if (!err && dn.dn.dn_type != DMU_OT_DSL_DATASET && dn.dn.dn_bonustype !=
DMU_OT_DSL_DATASET)
+ if (!err && dn.dn_type != DMU_OT_DSL_DATASET && dn.dn_bonustype !=
DMU_OT_DSL_DATASET)
return grub_error(GRUB_ERR_BAD_FS, "incorrect dataset dnode type");
if (err)
@@ -4427,7 +4546,7 @@ grub_zfs_dir (grub_device_t device, const char *path,
return err;
}
- snapobj = grub_zfs_to_cpu64 (((dsl_dataset_phys_t *) DN_BONUS
(&dn.dn))->ds_snapnames_zapobj, dn.endian);
+ snapobj = ((dsl_dataset_phys_t *) DN_BONUS (&dn))->ds_snapnames_zapobj;
err = dnode_get (&(data->mos), snapobj,
DMU_OT_DSL_DS_SNAP_MAP, &dn, data);
@@ -4441,7 +4560,7 @@ grub_zfs_dir (grub_device_t device, const char *path,
}
else
{
- if (data->dnode.dn.dn_type != DMU_OT_DIRECTORY_CONTENTS)
+ if (data->dnode.dn_type != DMU_OT_DIRECTORY_CONTENTS)
{
zfs_unmount (data);
return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
@@ -4477,16 +4596,14 @@ check_feature (const char *name, grub_uint64_t val,
*/
static grub_err_t
-check_mos_features(dnode_phys_t *mosmdn_phys,grub_zfs_endian_t endian,struct
grub_zfs_data* data )
+check_mos_features(dnode_phys_t *mosmdn_phys, struct grub_zfs_data* data )
{
grub_uint64_t objnum;
- grub_err_t errnum = 0;
- dnode_end_t dn,mosmdn;
+ grub_err_t errnum = 0, ret = 0;
+ dnode_phys_t dn,mosmdn;
mzap_phys_t* mzp;
- grub_zfs_endian_t endianzap;
- int size, ret;
- grub_memmove(&(mosmdn.dn),mosmdn_phys,sizeof(dnode_phys_t));
- mosmdn.endian=endian;
+ int size;
+ grub_memmove(&mosmdn,mosmdn_phys,sizeof(dnode_phys_t));
errnum = dnode_get(&mosmdn, DMU_POOL_DIRECTORY_OBJECT,
DMU_OT_OBJECT_DIRECTORY, &dn,data);
if (errnum != 0)
@@ -4505,12 +4622,12 @@ check_mos_features(dnode_phys_t
*mosmdn_phys,grub_zfs_endian_t endian,struct gru
if (errnum != 0)
return errnum;
- errnum = dmu_read(&dn, 0, (void**)&mzp, &endianzap,data);
+ errnum = dmu_read(&dn, 0, (void**)&mzp, data);
if (errnum != 0)
return errnum;
- size = grub_zfs_to_cpu16 (dn.dn.dn_datablkszsec, dn.endian) <<
SPA_MINBLOCKSHIFT;
- ret = mzap_iterate (mzp,endianzap, size, check_feature,NULL);
+ size = dn.dn_datablkszsec << SPA_MINBLOCKSHIFT;
+ ret = mzap_iterate (mzp, size, check_feature,NULL);
grub_free(mzp);
return ret;
}
diff --git a/grub-core/fs/zfs/zfs_fletcher.c b/grub-core/fs/zfs/zfs_fletcher.c
index ad3be6705..deac0b45b 100644
--- a/grub-core/fs/zfs/zfs_fletcher.c
+++ b/grub-core/fs/zfs/zfs_fletcher.c
@@ -54,10 +54,10 @@ fletcher_2(const void *buf, grub_uint64_t size,
grub_zfs_endian_t endian,
b1 += a1;
}
- zcp->zc_word[0] = grub_cpu_to_zfs64 (a0, endian);
- zcp->zc_word[1] = grub_cpu_to_zfs64 (a1, endian);
- zcp->zc_word[2] = grub_cpu_to_zfs64 (b0, endian);
- zcp->zc_word[3] = grub_cpu_to_zfs64 (b1, endian);
+ zcp->zc_word[0] = a0;
+ zcp->zc_word[1] = a1;
+ zcp->zc_word[2] = b0;
+ zcp->zc_word[3] = b1;
}
void
@@ -70,15 +70,15 @@ fletcher_4 (const void *buf, grub_uint64_t size,
grub_zfs_endian_t endian,
for (a = b = c = d = 0; ip < ipend; ip++)
{
- a += grub_zfs_to_cpu32 (ip[0], endian);;
+ a += grub_zfs_to_cpu32 (ip[0], endian);
b += a;
c += b;
d += c;
}
- zcp->zc_word[0] = grub_cpu_to_zfs64 (a, endian);
- zcp->zc_word[1] = grub_cpu_to_zfs64 (b, endian);
- zcp->zc_word[2] = grub_cpu_to_zfs64 (c, endian);
- zcp->zc_word[3] = grub_cpu_to_zfs64 (d, endian);
+ zcp->zc_word[0] = a;
+ zcp->zc_word[1] = b;
+ zcp->zc_word[2] = c;
+ zcp->zc_word[3] = d;
}
diff --git a/grub-core/fs/zfs/zfs_sha256.c b/grub-core/fs/zfs/zfs_sha256.c
index f042fa61a..69f1bd9d9 100644
--- a/grub-core/fs/zfs/zfs_sha256.c
+++ b/grub-core/fs/zfs/zfs_sha256.c
@@ -109,7 +109,7 @@ SHA256Transform(grub_uint32_t *H, const grub_uint8_t *cp)
void
zio_checksum_SHA256(const void *buf, grub_uint64_t size,
- grub_zfs_endian_t endian, zio_cksum_t *zcp)
+ grub_zfs_endian_t endian __attribute__((unused)),
zio_cksum_t *zcp)
{
grub_uint32_t H[8] = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 };
@@ -132,12 +132,8 @@ zio_checksum_SHA256(const void *buf, grub_uint64_t size,
for (i = 0; i < padsize && i <= 64; i += 64)
SHA256Transform(H, pad + i);
- zcp->zc_word[0] = grub_cpu_to_zfs64 ((grub_uint64_t)H[0] << 32 | H[1],
- endian);
- zcp->zc_word[1] = grub_cpu_to_zfs64 ((grub_uint64_t)H[2] << 32 | H[3],
- endian);
- zcp->zc_word[2] = grub_cpu_to_zfs64 ((grub_uint64_t)H[4] << 32 | H[5],
- endian);
- zcp->zc_word[3] = grub_cpu_to_zfs64 ((grub_uint64_t)H[6] << 32 | H[7],
- endian);
+ zcp->zc_word[0] = (grub_uint64_t)H[0] << 32 | H[1];
+ zcp->zc_word[1] = (grub_uint64_t)H[2] << 32 | H[3];
+ zcp->zc_word[2] = (grub_uint64_t)H[4] << 32 | H[5];
+ zcp->zc_word[3] = (grub_uint64_t)H[6] << 32 | H[7];
}
diff --git a/grub-core/fs/zfs/zfscrypt.c b/grub-core/fs/zfs/zfscrypt.c
index da30e9ab3..535fd4065 100644
--- a/grub-core/fs/zfs/zfscrypt.c
+++ b/grub-core/fs/zfs/zfscrypt.c
@@ -277,7 +277,7 @@ algo_decrypt (grub_crypto_cipher_handle_t cipher,
grub_uint64_t algo,
static grub_err_t
grub_zfs_decrypt_real (grub_crypto_cipher_handle_t cipher,
grub_uint64_t algo,
- void *nonce,
+ const void *nonce,
char *buf, grub_size_t size,
const grub_uint32_t *expected_mac,
grub_zfs_endian_t endian)
diff --git a/include/grub/zfs/sa_impl.h b/include/grub/zfs/sa_impl.h
index 0845d1290..b92c458a4 100644
--- a/include/grub/zfs/sa_impl.h
+++ b/include/grub/zfs/sa_impl.h
@@ -29,6 +29,7 @@ typedef struct sa_hdr_phys {
} sa_hdr_phys_t;
#define SA_HDR_SIZE(hdr) BF32_GET_SB(hdr->sa_layout_info, 10,
16, 3, 0)
+#define SA_MAGIC 0x2F505A
#define SA_TYPE_OFFSET 0x0
#define SA_SIZE_OFFSET 0x8
#define SA_MTIME_OFFSET 0x38
diff --git a/include/grub/zfs/spa.h b/include/grub/zfs/spa.h
index 5afbe4ecd..da44d1864 100644
--- a/include/grub/zfs/spa.h
+++ b/include/grub/zfs/spa.h
@@ -196,9 +196,18 @@ typedef struct blkptr {
#define DVA_GET_VDEV(dva) BF64_GET((dva)->dva_word[0], 32, 32)
#define DVA_SET_VDEV(dva, x) BF64_SET((dva)->dva_word[0], 32, 32, x)
+#define DVA_GET_OFFSET(dva) \
+ BF64_GET_SB((dva)->dva_word[1], 0, 63, SPA_MINBLOCKSHIFT, 0)
+#define DVA_SET_OFFSET(dva, x) \
+ BF64_SET_SB((dva)->dva_word[1], 0, 63, SPA_MINBLOCKSHIFT, 0, x)
+
#define DVA_GET_GANG(dva) BF64_GET((dva)->dva_word[1], 63, 1)
#define DVA_SET_GANG(dva, x) BF64_SET((dva)->dva_word[1], 63, 1, x)
+#define BP_GET_PSIZE(bp) \
+ BF64_GET_SB((bp)->blk_prop, 16, 16, SPA_MINBLOCKSHIFT, 1)
+#define BP_SET_PSIZE(bp, x) \
+ BF64_SET_SB((bp)->blk_prop, 16, 16, SPA_MINBLOCKSHIFT, 1, x)
#define BP_GET_LSIZE(bp) \
BF64_GET_SB((bp)->blk_prop, 0, 16, SPA_MINBLOCKSHIFT, 1)
#define BP_SET_LSIZE(bp, x) \
diff --git a/include/grub/zfs/zfs.h b/include/grub/zfs/zfs.h
index 4ee513887..0c5c40a73 100644
--- a/include/grub/zfs/zfs.h
+++ b/include/grub/zfs/zfs.h
@@ -33,6 +33,14 @@ typedef enum grub_zfs_endian
GRUB_ZFS_BIG_ENDIAN = 0
} grub_zfs_endian_t;
+#ifdef GRUB_CPU_WORDS_BIGENDIAN
+#define GRUB_ZFS_IS_NATIVE_BYTEORDER(x) ((x) == GRUB_ZFS_BIG_ENDIAN)
+#define GRUB_ZFS_NATIVE_ENDIAN GRUB_ZFS_BIG_ENDIAN
+#else
+#define GRUB_ZFS_IS_NATIVE_BYTEORDER(x) ((x) != GRUB_ZFS_BIG_ENDIAN)
+#define GRUB_ZFS_NATIVE_ENDIAN GRUB_ZFS_LITTLE_ENDIAN
+#endif
+
/*
* On-disk version number.
*/
@@ -141,7 +149,7 @@ grub_zfs_add_key (grub_uint8_t *key_in,
extern grub_err_t (*grub_zfs_decrypt) (grub_crypto_cipher_handle_t cipher,
grub_uint64_t algo,
- void *nonce,
+ const void *nonce,
char *buf, grub_size_t size,
const grub_uint32_t *expected_mac,
grub_zfs_endian_t endian);
--
2.49.0
_______________________________________________
Grub-devel mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/grub-devel