From fd92825445a4f60cb588ce558775add5a6e13e3b Mon Sep 17 00:00:00 2001 From: Paul Dagnelie Date: Wed, 8 Sep 2021 13:52:28 -0700 Subject: [PATCH] Compressed receive with different ashift can result in incorrect PSIZE on disk We round up the psize to the nearest multiple of the asize or to the lsize, whichever is smaller. Once that's done, we allocate a new buffer of the appropriate size, zero the tail, and copy the data into it. This adds a small performance cost to these kinds of writes, but fixes the bookkeeping problems. Reviewed-by: Brian Behlendorf Reviewed-by: Matthew Ahrens Co-authored-by: Matthew Ahrens Signed-off-by: Paul Dagnelie Closes #12522 Closes #8462 --- module/zfs/zio.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/module/zfs/zio.c b/module/zfs/zio.c index 76ed4fad43..85e05ee6af 100644 --- a/module/zfs/zio.c +++ b/module/zfs/zio.c @@ -1771,6 +1771,18 @@ zio_write_compress(zio_t *zio) zio->io_abd, NULL, lsize, zp->zp_complevel); if (psize == 0 || psize >= lsize) compress = ZIO_COMPRESS_OFF; + } else if (zio->io_flags & ZIO_FLAG_RAW_COMPRESS) { + size_t rounded = MIN((size_t)roundup(psize, + spa->spa_min_alloc), lsize); + + if (rounded != psize) { + abd_t *cdata = abd_alloc_linear(rounded, B_TRUE); + abd_zero_off(cdata, psize, rounded - psize); + abd_copy_off(cdata, zio->io_abd, 0, 0, psize); + psize = rounded; + zio_push_transform(zio, cdata, + psize, rounded, NULL); + } } else { ASSERT3U(psize, !=, 0); }