FreeBSD/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
/*
 * Decompresses a zio read back from an l2arc device. On success, the
 * underlying zio's io_data buffer is overwritten by the uncompressed
 * version. On decompression error (corrupt compressed stream), the
 * zio->io_error value is set to signal an I/O error.
 *
 * Please note that the compressed data stream is not checksummed, so
 * if the underlying device is experiencing data corruption, we may feed
 * corrupt data to the decompressor, so the decompressor needs to be
 * able to handle this situation (LZ4 does).
 */
Decompresses a zio read back from an l2arc device. On success, the
underlying zio's io_data buffer is overwritten by the uncompressed
version. On decompression error (corrupt compressed stream), the
zio->io_error value is set to signal an I/O error.

Please note that the compressed data stream is not checksummed, so
if the underlying device is experiencing data corruption, we may feed
corrupt data to the decompressor, so the decompressor needs to be
able to handle this situation (LZ4 does).
Decompresses a zio read back from an l2arc device . On success the underlying zio ' s io_data buffer is overwritten by the uncompressed version . On decompression error ( corrupt compressed stream ) the zio - > io_error value is set to signal an I / O error . Please note that the compressed data stream is not checksummed so if the underlying device is experiencing data corruption we may feed corrupt data to the decompressor so the decompressor needs to be able to handle this situation ( LZ4 does ) .
static void
l2arc_decompress_zio(zio_t *zio, arc_buf_hdr_t *hdr, enum zio_compress c)
{
	ASSERT(L2ARC_IS_VALID_COMPRESS(c));
	if (zio->io_error != 0) {
		zio->io_orig_size = zio->io_size = hdr->b_size;
		return;
	}
	if (c == ZIO_COMPRESS_EMPTY) {
		ASSERT(hdr->b_l1hdr.b_buf != NULL);
		bzero(hdr->b_l1hdr.b_buf->b_data, hdr->b_size);
		zio->io_data = zio->io_orig_data = hdr->b_l1hdr.b_buf->b_data;
	} else {
		ASSERT(zio->io_data != NULL);
		uint64_t csize;
		void *cdata;
		csize = zio->io_size;
		cdata = zio_data_buf_alloc(csize);
		bcopy(zio->io_data, cdata, csize);
		if (zio_decompress_data(c, cdata, zio->io_data, csize,
		    hdr->b_size) != 0)
			zio->io_error = EIO;
		zio_data_buf_free(cdata, csize);
	}
	zio->io_orig_size = zio->io_size = hdr->b_size;
}
static void l2arc_decompress_zio ( zio_t * zio , arc_buf_hdr_t * hdr , enum zio_compress c ) { ASSERT ( L2ARC_IS_VALID_COMPRESS ( c ) ) ; if ( zio -> io_error != 0 ) { zio -> io_orig_size = zio -> io_size = hdr -> b_size ; return ; } if ( c == ZIO_COMPRESS_EMPTY ) { ASSERT ( hdr -> b_l1hdr . b_buf != NULL ) ; bzero ( hdr -> b_l1hdr . b_buf -> b_data , hdr -> b_size ) ; zio -> io_data = zio -> io_orig_data = hdr -> b_l1hdr . b_buf -> b_data ; } else { ASSERT ( zio -> io_data != NULL ) ; uint64_t csize ; void * cdata ; csize = zio -> io_size ; cdata = zio_data_buf_alloc ( csize ) ; bcopy ( zio -> io_data , cdata , csize ) ; if ( zio_decompress_data ( c , cdata , zio -> io_data , csize , hdr -> b_size ) != 0 ) zio -> io_error = EIO ; zio_data_buf_free ( cdata , csize ) ; } zio -> io_orig_size = zio -> io_size = hdr -> b_size ; }
Decompresses a zio read back from an l2arc device.
Decompresses a zio read back from an l2arc device .
/*
		 * An io error has occured, just restore the original io
		 * size in preparation for a main pool read.
		 */ /*
		 * An empty buffer results in a null zio, which means we
		 * need to fill its io_data after we're done restoring the
		 * buffer's contents.
		 */ /*
		 * We copy the compressed data from the start of the arc buffer
		 * (the zio_read will have pulled in only what we need, the
		 * rest is garbage which we will overwrite at decompression)
		 * and then decompress back to the ARC data buffer. This way we
		 * can minimize copying by simply decompressing back over the
		 * original compressed data (rather than decompressing to an
		 * aux buffer and then copying back the uncompressed buffer,
		 * which is likely to be much larger).
		 */ /* Restore the expected uncompressed IO size. */