Illumos 5818 - zfs {ref}compressratio is incorrect with 4k sector size

5818 zfs {ref}compressratio is incorrect with 4k sector size
Reviewed by: Alex Reece <alex@delphix.com>
Reviewed by: George Wilson <george@delphix.com>
Reviewed by: Richard Elling <richard.elling@richardelling.com>
Reviewed by: Steven Hartland <killing@multiplay.co.uk>
Approved by: Albert Lee <trisk@omniti.com>

References:
  https://www.illumos.org/issues/5818
  https://github.com/illumos/illumos-gate/commit/81cd5c5

Ported-by: Don Brady <don.brady@intel.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #3432
This commit is contained in:
Matthew Ahrens
2015-05-19 22:14:01 -06:00
committed by Brian Behlendorf
parent 9c43027b3f
commit c3520e7f1f
7 changed files with 45 additions and 33 deletions
+17 -10
View File
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2014 by Delphix. All rights reserved.
* Copyright (c) 2011, 2015 by Delphix. All rights reserved.
* Copyright (c) 2011 Nexenta Systems, Inc. All rights reserved.
*/
@@ -1195,19 +1195,26 @@ zio_write_bp_init(zio_t *zio)
return (ZIO_PIPELINE_CONTINUE);
} else {
/*
* Round up compressed size to MINBLOCKSIZE and
* zero the tail.
* Round up compressed size up to the ashift
* of the smallest-ashift device, and zero the tail.
* This ensures that the compressed size of the BP
* (and thus compressratio property) are correct,
* in that we charge for the padding used to fill out
* the last sector.
*/
size_t rounded =
P2ROUNDUP(psize, (size_t)SPA_MINBLOCKSIZE);
if (rounded > psize) {
bzero((char *)cbuf + psize, rounded - psize);
psize = rounded;
}
if (psize == lsize) {
size_t rounded;
ASSERT3U(spa->spa_min_ashift, >=, SPA_MINBLOCKSHIFT);
rounded = (size_t)P2ROUNDUP(psize,
1ULL << spa->spa_min_ashift);
if (rounded >= lsize) {
compress = ZIO_COMPRESS_OFF;
zio_buf_free(cbuf, lsize);
psize = lsize;
} else {
bzero((char *)cbuf + psize, rounded - psize);
psize = rounded;
zio_push_transform(zio, cbuf,
psize, lsize, NULL);
}