From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1Yow9a-00040g-Fn for mharc-grub-devel@gnu.org; Sun, 03 May 2015 11:50:02 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38163) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Yow9Y-00040U-4e for grub-devel@gnu.org; Sun, 03 May 2015 11:50:01 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Yow9U-0006fu-27 for grub-devel@gnu.org; Sun, 03 May 2015 11:50:00 -0400 Received: from mail-la0-x22e.google.com ([2a00:1450:4010:c03::22e]:34896) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Yow9T-0006fq-Ls for grub-devel@gnu.org; Sun, 03 May 2015 11:49:55 -0400 Received: by labbd9 with SMTP id bd9so90379562lab.2 for ; Sun, 03 May 2015 08:49:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=date:from:to:cc:subject:message-id:in-reply-to:references :mime-version:content-type:content-transfer-encoding; bh=6Q0C1S+me8+y6w9KQo64Ar5SSgzF1N4CWbTQxZOfH64=; b=A5JNIj97QasrLetIcmLWNRUeRqFE9ELwyoJPw/1cFTI4f/RqONtQxyi6oEQrtQzqgL ymFdTT5shT3yS/0BIvp57WoQ2CMMXpFPYsuELRhtaBDccxRwR10HmvDMRiFsFtE6uifH n8DFiQ+i+JL8bJHDHiKAK91DZm35ZvjbaV7y2Ig2hYlaMkwJkWc0DdF1ZnugRCczu8Vh EAFZ5F+o7khlU6GQwUDx3+v9yNq3z4xNMMtR9aJ4ULEsjCG6l9p77tyDp10LxKZfHj8y M76V8yXDund5i2dBwaZnZNA2t0RnR+4i4njlGQ2/LRVxGH/YpHVsOCMIzBuZz16cHxvM OtGg== X-Received: by 10.112.155.165 with SMTP id vx5mr10412043lbb.65.1430668194890; Sun, 03 May 2015 08:49:54 -0700 (PDT) Received: from opensuse.site (ppp91-76-14-38.pppoe.mtu-net.ru. [91.76.14.38]) by mx.google.com with ESMTPSA id q1sm2760574laq.10.2015.05.03.08.49.53 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 03 May 2015 08:49:53 -0700 (PDT) Date: Sun, 3 May 2015 18:49:52 +0300 From: Andrei Borzenkov To: Toomas Soome Subject: Re: [PATCH 4/5] zfs com.delphix:embedded_data feature support Message-ID: <20150503184952.64f7a57f@opensuse.site> In-Reply-To: References: X-Mailer: Claws Mail 3.11.0 (GTK+ 2.24.27; x86_64-suse-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a00:1450:4010:c03::22e Cc: The development of GNU GRUB X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list Reply-To: The development of GNU GRUB List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 03 May 2015 15:50:01 -0000 =D0=92 Thu, 16 Apr 2015 08:23:22 +0300 Toomas Soome =D0=BF=D0=B8=D1=88=D0=B5=D1=82: Committed with trivial formatting fix. >=20 > --- > grub-core/fs/zfs/zfs.c | 84 ++++++++++++++++++++++++++++++++++++++++--= ------ > include/grub/zfs/spa.h | 27 +++++++++++++--- > 2 files changed, 93 insertions(+), 18 deletions(-) >=20 > diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c > index a731c3d..da44131 100644 > --- a/grub-core/fs/zfs/zfs.c > +++ b/grub-core/fs/zfs/zfs.c > @@ -282,6 +282,7 @@ grub_crypto_cipher_handle_t (*grub_zfs_load_key) (con= st struct grub_zfs_key *key > static const char *spa_feature_names[] =3D { > "org.illumos:lz4_compress", > "com.delphix:hole_birth", > + "com.delphix:embedded_data", > NULL > }; > =20 > @@ -1803,6 +1804,39 @@ zio_read_data (blkptr_t * bp, grub_zfs_endian_t en= dian, void *buf, > } > =20 > /* > + * 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 =3D buf; > + grub_uint64_t w =3D 0; > + const grub_uint64_t *bp64 =3D (const grub_uint64_t *)bp; > + > + psize =3D 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 =3D 0; i < psize; i++) > + { > + if (i % sizeof (w) =3D=3D 0) > + { > + /* beginning of a word */ > + w =3D *bp64; > + bp64++; > + if (!BPE_IS_PAYLOADWORD(bp, bp64)) > + bp64++; > + } > + buf8[i] =3D 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 =3D NULL; > =20 > checksum =3D (grub_zfs_to_cpu64((bp)->blk_prop, endian) >> 40) & 0xff; > - comp =3D (grub_zfs_to_cpu64((bp)->blk_prop, endian)>>32) & 0xff; > + comp =3D (grub_zfs_to_cpu64((bp)->blk_prop, endian)>>32) & 0x7f; > encrypted =3D ((grub_zfs_to_cpu64((bp)->blk_prop, endian) >> 60) & 3); > - lsize =3D (BP_IS_HOLE(bp) ? 0 : > - (((grub_zfs_to_cpu64 ((bp)->blk_prop, endian) & 0xffff) + 1) > - << SPA_MINBLOCKSHIFT)); > - psize =3D get_psize (bp, endian); > + if (BP_IS_EMBEDDED(bp)) > + { > + if (BPE_GET_ETYPE(bp) !=3D BP_EMBEDDED_TYPE_DATA) > + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, > + "unsupported embedded BP (type=3D%u)\n", > + BPE_GET_ETYPE(bp)); > + lsize =3D BPE_GET_LSIZE(bp); > + psize =3D BF64_GET_SB(grub_zfs_to_cpu64 ((bp)->blk_prop, endian), = 25, 7, 0, 1); > + } > + else > + { > + lsize =3D (BP_IS_HOLE(bp) ? 0 : > + (((grub_zfs_to_cpu64 ((bp)->blk_prop, endian) & 0xffff) + 1) > + << SPA_MINBLOCKSHIFT)); > + psize =3D get_psize (bp, endian); > + } > + grub_dprintf("zfs", "zio_read: E %d: size %" PRIdGRUB_SSIZE "/%" > + PRIdGRUB_SSIZE "\n", (int)BP_IS_EMBEDDED(bp), lsize, psize); > =20 > if (size) > *size =3D lsize; > @@ -1849,23 +1897,31 @@ zio_read (blkptr_t *bp, grub_zfs_endian_t endian,= void **buf, > compbuf =3D *buf =3D grub_malloc (lsize); > =20 > grub_dprintf ("zfs", "endian =3D %d\n", endian); > - err =3D zio_read_data (bp, endian, compbuf, data); > + if (BP_IS_EMBEDDED(bp)) > + err =3D decode_embedded_bp_compressed(bp, compbuf); > + else > + { > + err =3D zio_read_data (bp, endian, compbuf, data); > + grub_memset (compbuf, 0, ALIGN_UP (psize, 16) - psize); > + } > if (err) > { > grub_free (compbuf); > *buf =3D NULL; > return err; > } > - grub_memset (compbuf, 0, ALIGN_UP (psize, 16) - psize); > =20 > - err =3D 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 =3D NULL; > - return err; > + err =3D zio_checksum_verify (zc, checksum, endian, > + compbuf, psize); > + if (err) > + { > + grub_dprintf ("zfs", "incorrect checksum\n"); > + grub_free (compbuf); > + *buf =3D NULL; > + return err; > + } > } > =20 > if (encrypted) > diff --git a/include/grub/zfs/spa.h b/include/grub/zfs/spa.h > index df43b6b..5d89250 100644 > --- a/include/grub/zfs/spa.h > +++ b/include/grub/zfs/spa.h > @@ -126,7 +126,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 | > * +-------+-------+-------+-------+-------+-------+-------+-------+ > @@ -160,7 +160,8 @@ typedef struct zio_cksum { > * G gang block indicator > * B byteorder (endianness) > * D dedup > - * X unused > + * X encryption > + * 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 > @@ -203,8 +204,8 @@ typedef struct blkptr { > #define BP_SET_LSIZE(bp, x) \ > BF64_SET_SB((bp)->blk_prop, 0, 16, SPA_MINBLOCKSHIFT, 1, x) > =20 > -#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) > =20 > #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) > @@ -215,6 +216,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) > =20 > +#define BP_IS_EMBEDDED(bp) BF64_GET((bp)->blk_prop, 39, 1) > + > #define BP_GET_PROP_BIT_61(bp) BF64_GET((bp)->blk_prop, 61, 1) > #define BP_SET_PROP_BIT_61(bp, x) BF64_SET((bp)->blk_prop, 61, 1, x) > =20 > @@ -277,6 +280,22 @@ typedef struct blkptr { > (zcp)->zc_word[3] =3D w3; \ > } > =20 > +#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(grub_uint64_t)) > +#define BPE_IS_PAYLOADWORD(bp, wp) \ > + ((wp) !=3D &(bp)->blk_prop && (wp) !=3D &(bp)->blk_birth) > + > #define BP_IDENTITY(bp) (&(bp)->blk_dva[0]) > #define BP_IS_GANG(bp) DVA_GET_GANG(BP_IDENTITY(bp)) > #define DVA_IS_EMPTY(dva) ((dva)->dva_word[0] =3D=3D 0ULL && \