]> git.proxmox.com Git - mirror_zfs.git/blobdiff - module/zfs/zio.c
Illumos 5818 - zfs {ref}compressratio is incorrect with 4k sector size
[mirror_zfs.git] / module / zfs / zio.c
index 2b338f2a717961d3addcbb6b0994378b40776e3e..1e5be8bfc8380855094dedfcd109db653589006b 100644 (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);
                        }