zfs: com.delphix:embedded_data feature support
This commit is contained in:
parent
a1007c6af2
commit
4a7ea4003b
2 changed files with 93 additions and 18 deletions
|
@ -282,6 +282,7 @@ grub_crypto_cipher_handle_t (*grub_zfs_load_key) (const struct grub_zfs_key *key
|
|||
static const char *spa_feature_names[] = {
|
||||
"org.illumos:lz4_compress",
|
||||
"com.delphix:hole_birth",
|
||||
"com.delphix:embedded_data",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -1802,6 +1803,39 @@ zio_read_data (blkptr_t * bp, grub_zfs_endian_t endian, void *buf,
|
|||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* buf must be at least BPE_GET_PSIZE(bp) bytes long (which will never be
|
||||
* more than BPE_PAYLOAD_SIZE bytes).
|
||||
*/
|
||||
static grub_err_t
|
||||
decode_embedded_bp_compressed(const blkptr_t *bp, void *buf)
|
||||
{
|
||||
grub_size_t psize, i;
|
||||
grub_uint8_t *buf8 = buf;
|
||||
grub_uint64_t w = 0;
|
||||
const grub_uint64_t *bp64 = (const grub_uint64_t *)bp;
|
||||
|
||||
psize = BPE_GET_PSIZE(bp);
|
||||
|
||||
/*
|
||||
* Decode the words of the block pointer into the byte array.
|
||||
* Low bits of first word are the first byte (little endian).
|
||||
*/
|
||||
for (i = 0; i < psize; i++)
|
||||
{
|
||||
if (i % sizeof (w) == 0)
|
||||
{
|
||||
/* beginning of a word */
|
||||
w = *bp64;
|
||||
bp64++;
|
||||
if (!BPE_IS_PAYLOADWORD(bp, bp64))
|
||||
bp64++;
|
||||
}
|
||||
buf8[i] = BF64_GET(w, (i % sizeof (w)) * 8, 8);
|
||||
}
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read in a block of data, verify its checksum, decompress if needed,
|
||||
* and put the uncompressed data in buf.
|
||||
|
@ -1820,12 +1854,26 @@ 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) & 0xff;
|
||||
comp = (grub_zfs_to_cpu64((bp)->blk_prop, endian)>>32) & 0x7f;
|
||||
encrypted = ((grub_zfs_to_cpu64((bp)->blk_prop, endian) >> 60) & 3);
|
||||
lsize = (BP_IS_HOLE(bp) ? 0 :
|
||||
(((grub_zfs_to_cpu64 ((bp)->blk_prop, endian) & 0xffff) + 1)
|
||||
<< SPA_MINBLOCKSHIFT));
|
||||
psize = get_psize (bp, endian);
|
||||
if (BP_IS_EMBEDDED(bp))
|
||||
{
|
||||
if (BPE_GET_ETYPE(bp) != BP_EMBEDDED_TYPE_DATA)
|
||||
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||
"unsupported embedded BP (type=%u)\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);
|
||||
}
|
||||
else
|
||||
{
|
||||
lsize = (BP_IS_HOLE(bp) ? 0 :
|
||||
(((grub_zfs_to_cpu64 ((bp)->blk_prop, endian) & 0xffff) + 1)
|
||||
<< SPA_MINBLOCKSHIFT));
|
||||
psize = get_psize (bp, endian);
|
||||
}
|
||||
grub_dprintf("zfs", "zio_read: E %d: size %" PRIdGRUB_SSIZE "/%"
|
||||
PRIdGRUB_SSIZE "\n", (int)BP_IS_EMBEDDED(bp), lsize, psize);
|
||||
|
||||
if (size)
|
||||
*size = lsize;
|
||||
|
@ -1849,23 +1897,31 @@ zio_read (blkptr_t *bp, grub_zfs_endian_t endian, void **buf,
|
|||
compbuf = *buf = grub_malloc (lsize);
|
||||
|
||||
grub_dprintf ("zfs", "endian = %d\n", endian);
|
||||
err = zio_read_data (bp, endian, compbuf, data);
|
||||
if (BP_IS_EMBEDDED(bp))
|
||||
err = decode_embedded_bp_compressed(bp, compbuf);
|
||||
else
|
||||
{
|
||||
err = zio_read_data (bp, endian, compbuf, data);
|
||||
grub_memset (compbuf, 0, ALIGN_UP (psize, 16) - psize);
|
||||
}
|
||||
if (err)
|
||||
{
|
||||
grub_free (compbuf);
|
||||
*buf = NULL;
|
||||
return err;
|
||||
}
|
||||
grub_memset (compbuf, 0, ALIGN_UP (psize, 16) - psize);
|
||||
|
||||
err = zio_checksum_verify (zc, checksum, endian,
|
||||
compbuf, psize);
|
||||
if (err)
|
||||
if (!BP_IS_EMBEDDED(bp))
|
||||
{
|
||||
grub_dprintf ("zfs", "incorrect checksum\n");
|
||||
grub_free (compbuf);
|
||||
*buf = NULL;
|
||||
return err;
|
||||
err = zio_checksum_verify (zc, checksum, endian,
|
||||
compbuf, psize);
|
||||
if (err)
|
||||
{
|
||||
grub_dprintf ("zfs", "incorrect checksum\n");
|
||||
grub_free (compbuf);
|
||||
*buf = NULL;
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
if (encrypted)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue