summaryrefslogtreecommitdiff
path: root/usr/src/grub
diff options
context:
space:
mode:
authorKeith M Wesolowski <wesolows@foobazco.org>2014-06-06 18:08:43 +0000
committerKeith M Wesolowski <wesolows@foobazco.org>2014-06-06 18:08:43 +0000
commit63162cf70473b17134d09687effc3da3d4f75588 (patch)
treed22ddd687f7e324b77ec7d197c146a58519d75fd /usr/src/grub
parent947d419922a14b9fce40294b5c0d6470a768c105 (diff)
parent06315b795c0d54f0228e0b8af497a28752dd92da (diff)
downloadillumos-joyent-63162cf70473b17134d09687effc3da3d4f75588.tar.gz
[illumos-gate merge]
commit 06315b795c0d54f0228e0b8af497a28752dd92da 4881 zfs send performance degradation when embedded block pointers are encountered commit 7fd05ac4dec0c343d2f68f310d3718b715ecfbaf 4390 i/o errors when deleting filesystem/zvol can lead to space map corruption commit 5d7b4d438c4a51eccc95e77a83a437b4d48380eb 4757 ZFS embedded-data block pointers ("zero block compression") 4913 zfs release should not be subject to space checks Conflicts: usr/src/man/man1m/zfs.1m
Diffstat (limited to 'usr/src/grub')
-rw-r--r--usr/src/grub/capability2
-rw-r--r--usr/src/grub/grub-0.97/stage2/fsys_zfs.c90
-rw-r--r--usr/src/grub/grub-0.97/stage2/zfs-include/spa.h27
3 files changed, 109 insertions, 10 deletions
diff --git a/usr/src/grub/capability b/usr/src/grub/capability
index 964cbe9306..e0f25f1275 100644
--- a/usr/src/grub/capability
+++ b/usr/src/grub/capability
@@ -29,7 +29,7 @@
# GRUB necessitating that the boot blocks be reinstalled for that fix or
# enhancement to take effect.
#
-VERSION=23
+VERSION=24
dboot
xVM
zfs
diff --git a/usr/src/grub/grub-0.97/stage2/fsys_zfs.c b/usr/src/grub/grub-0.97/stage2/fsys_zfs.c
index 950f3ce880..341b6cd971 100644
--- a/usr/src/grub/grub-0.97/stage2/fsys_zfs.c
+++ b/usr/src/grub/grub-0.97/stage2/fsys_zfs.c
@@ -166,12 +166,15 @@ zio_checksum_verify(blkptr_t *bp, char *data, int size)
zio_checksum_info_t *ci = &zio_checksum_table[checksum];
zio_cksum_t actual_cksum, expected_cksum;
- /* byteswap is not supported */
- if (byteswap)
+ if (byteswap) {
+ grub_printf("byteswap not supported\n");
return (-1);
+ }
- if (checksum >= ZIO_CHECKSUM_FUNCTIONS || ci->ci_func[0] == NULL)
+ if (checksum >= ZIO_CHECKSUM_FUNCTIONS || ci->ci_func[0] == NULL) {
+ grub_printf("checksum algorithm %u not supported\n", checksum);
return (-1);
+ }
if (ci->ci_eck) {
expected_cksum = zec->zec_cksum;
@@ -179,7 +182,6 @@ zio_checksum_verify(blkptr_t *bp, char *data, int size)
ci->ci_func[0](data, size, &actual_cksum);
zec->zec_cksum = expected_cksum;
zc = expected_cksum;
-
} else {
ci->ci_func[byteswap](data, size, &actual_cksum);
}
@@ -379,6 +381,72 @@ zio_read_data(blkptr_t *bp, void *buf, char *stack)
}
/*
+ * buf must be at least BPE_GET_PSIZE(bp) bytes long (which will never be
+ * more than BPE_PAYLOAD_SIZE bytes).
+ */
+static void
+decode_embedded_bp_compressed(const blkptr_t *bp, void *buf)
+{
+ int psize, i;
+ uint8_t *buf8 = buf;
+ uint64_t w = 0;
+ const uint64_t *bp64 = (const 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)) * NBBY, NBBY);
+ }
+}
+
+/*
+ * Fill in the buffer with the (decompressed) payload of the embedded
+ * blkptr_t. Takes into account compression and byteorder (the payload is
+ * treated as a stream of bytes).
+ * Return 0 on success, or ENOSPC if it won't fit in the buffer.
+ */
+static int
+decode_embedded_bp(const blkptr_t *bp, void *buf)
+{
+ int comp;
+ int lsize, psize;
+ uint8_t *dst = buf;
+ uint64_t w = 0;
+
+ lsize = BPE_GET_LSIZE(bp);
+ psize = BPE_GET_PSIZE(bp);
+ comp = BP_GET_COMPRESS(bp);
+
+ if (comp != ZIO_COMPRESS_OFF) {
+ uint8_t dstbuf[BPE_PAYLOAD_SIZE];
+
+ if ((unsigned int)comp >= ZIO_COMPRESS_FUNCTIONS ||
+ decomp_table[comp].decomp_func == NULL) {
+ grub_printf("compression algorithm not supported\n");
+ return (ERR_FSYS_CORRUPT);
+ }
+
+ decode_embedded_bp_compressed(bp, dstbuf);
+ decomp_table[comp].decomp_func(dstbuf, buf, psize, lsize);
+ } else {
+ decode_embedded_bp_compressed(bp, buf);
+ }
+
+ return (0);
+}
+
+/*
* Read in a block of data, verify its checksum, decompress if needed,
* and put the uncompressed data in buf.
*
@@ -392,6 +460,15 @@ zio_read(blkptr_t *bp, void *buf, char *stack)
int lsize, psize, comp;
char *retbuf;
+ if (BP_IS_EMBEDDED(bp)) {
+ if (BPE_GET_ETYPE(bp) != BP_EMBEDDED_TYPE_DATA) {
+ grub_printf("unsupported embedded BP (type=%u)\n",
+ (int)BPE_GET_ETYPE(bp));
+ return (ERR_FSYS_CORRUPT);
+ }
+ return (decode_embedded_bp(bp, buf));
+ }
+
comp = BP_GET_COMPRESS(bp);
lsize = BP_GET_LSIZE(bp);
psize = BP_GET_PSIZE(bp);
@@ -404,7 +481,8 @@ zio_read(blkptr_t *bp, void *buf, char *stack)
}
if ((char *)buf < stack && ((char *)buf) + lsize > stack) {
- grub_printf("not enough memory allocated\n");
+ grub_printf("not enough memory to fit %u bytes on stack\n",
+ lsize);
return (ERR_WONT_FIT);
}
@@ -764,6 +842,7 @@ zap_iterate(dnode_phys_t *zap_dnode, zap_cb_t *cb, void *arg, char *stack)
* Input
* mdn - metadnode to get the object dnode
* objnum - object number for the object dnode
+ * type - if nonzero, object must be of this type
* buf - data buffer that holds the returning dnode
* stack - scratch area
*
@@ -968,6 +1047,7 @@ static const char *spa_feature_names[] = {
"org.illumos:lz4_compress",
"com.delphix:hole_birth",
"com.delphix:extensible_dataset",
+ "com.delphix:embedded_data",
NULL
};
diff --git a/usr/src/grub/grub-0.97/stage2/zfs-include/spa.h b/usr/src/grub/grub-0.97/stage2/zfs-include/spa.h
index 8d53ad6866..19fe52f13f 100644
--- a/usr/src/grub/grub-0.97/stage2/zfs-include/spa.h
+++ b/usr/src/grub/grub-0.97/stage2/zfs-include/spa.h
@@ -116,7 +116,7 @@ typedef struct zio_cksum {
* +-------+-------+-------+-------+-------+-------+-------+-------+
* 5 |G| offset3 |
* +-------+-------+-------+-------+-------+-------+-------+-------+
- * 6 |BDX|lvl| type | cksum | comp | PSIZE | LSIZE |
+ * 6 |BDX|lvl| type | cksum |E| comp| PSIZE | LSIZE |
* +-------+-------+-------+-------+-------+-------+-------+-------+
* 7 | padding |
* +-------+-------+-------+-------+-------+-------+-------+-------+
@@ -150,7 +150,8 @@ typedef struct zio_cksum {
* G gang block indicator
* B byteorder (endianness)
* D dedup
- * X unused
+ * X encryption (on version 30, which is not supported)
+ * E blkptr_t contains embedded data
* lvl level of indirection
* type DMU object type
* phys birth txg of block allocation; zero if same as logical birth txg
@@ -204,8 +205,8 @@ typedef struct blkptr {
#define BP_SET_PSIZE(bp, x) \
BF64_SET_SB((bp)->blk_prop, 16, SPA_PSIZEBITS, SPA_MINBLOCKSHIFT, 1, x)
-#define BP_GET_COMPRESS(bp) BF64_GET((bp)->blk_prop, 32, 8)
-#define BP_SET_COMPRESS(bp, x) BF64_SET((bp)->blk_prop, 32, 8, x)
+#define BP_GET_COMPRESS(bp) BF64_GET((bp)->blk_prop, 32, 7)
+#define BP_SET_COMPRESS(bp, x) BF64_SET((bp)->blk_prop, 32, 7, x)
#define BP_GET_CHECKSUM(bp) BF64_GET((bp)->blk_prop, 40, 8)
#define BP_SET_CHECKSUM(bp, x) BF64_SET((bp)->blk_prop, 40, 8, x)
@@ -216,6 +217,8 @@ typedef struct blkptr {
#define BP_GET_LEVEL(bp) BF64_GET((bp)->blk_prop, 56, 5)
#define BP_SET_LEVEL(bp, x) BF64_SET((bp)->blk_prop, 56, 5, x)
+#define BP_IS_EMBEDDED(bp) BF64_GET((bp)->blk_prop, 39, 1)
+
#define BP_GET_DEDUP(bp) BF64_GET((bp)->blk_prop, 62, 1)
#define BP_SET_DEDUP(bp, x) BF64_SET((bp)->blk_prop, 62, 1, x)
@@ -297,6 +300,22 @@ typedef struct blkptr {
ZIO_SET_CHECKSUM(&(bp)->blk_cksum, 0, 0, 0, 0); \
}
+#define BPE_GET_ETYPE(bp) BP_GET_CHECKSUM(bp)
+#define BPE_GET_LSIZE(bp) \
+ BF64_GET_SB((bp)->blk_prop, 0, 25, 0, 1)
+#define BPE_GET_PSIZE(bp) \
+ BF64_GET_SB((bp)->blk_prop, 25, 7, 0, 1)
+
+typedef enum bp_embedded_type {
+ BP_EMBEDDED_TYPE_DATA,
+ NUM_BP_EMBEDDED_TYPES
+} bp_embedded_type_t;
+
+#define BPE_NUM_WORDS 14
+#define BPE_PAYLOAD_SIZE (BPE_NUM_WORDS * sizeof (uint64_t))
+#define BPE_IS_PAYLOADWORD(bp, wp) \
+ ((wp) != &(bp)->blk_prop && (wp) != &(bp)->blk_birth)
+
#ifdef _BIG_ENDIAN
#define ZFS_HOST_BYTEORDER (0ULL)
#else