Skip to content

Commit c3520e7

Browse files
ahrensbehlendorf
authored andcommitted
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 illumos/illumos-gate@81cd5c5 Ported-by: Don Brady <don.brady@intel.com> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #3432
1 parent 9c43027 commit c3520e7

File tree

7 files changed

+45
-33
lines changed

7 files changed

+45
-33
lines changed

cmd/ztest/ztest.c

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
*/
2121
/*
2222
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23-
* Copyright (c) 2011, 2014 by Delphix. All rights reserved.
23+
* Copyright (c) 2011, 2015 by Delphix. All rights reserved.
2424
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
2525
* Copyright (c) 2013 Steven Hartland. All rights reserved.
2626
*/
@@ -1022,21 +1022,6 @@ ztest_random_spa_version(uint64_t initial_version)
10221022
return (version);
10231023
}
10241024

1025-
/*
1026-
* Find the largest ashift used
1027-
*/
1028-
static uint64_t
1029-
ztest_spa_get_ashift(void) {
1030-
uint64_t i;
1031-
uint64_t ashift = SPA_MINBLOCKSHIFT;
1032-
vdev_t *rvd = ztest_spa->spa_root_vdev;
1033-
1034-
for (i = 0; i < rvd->vdev_children; i++) {
1035-
ashift = MAX(ashift, rvd->vdev_child[i]->vdev_ashift);
1036-
}
1037-
return (ashift);
1038-
}
1039-
10401025
static int
10411026
ztest_random_blocksize(void)
10421027
{
@@ -1047,7 +1032,8 @@ ztest_random_blocksize(void)
10471032
int maxbs = SPA_OLD_MAXBLOCKSHIFT;
10481033
if (spa_maxblocksize(ztest_spa) == SPA_MAXBLOCKSIZE)
10491034
maxbs = 20;
1050-
uint64_t block_shift = ztest_random(maxbs - ztest_spa_get_ashift() + 1);
1035+
uint64_t block_shift =
1036+
ztest_random(maxbs - ztest_spa->spa_max_ashift + 1);
10511037
return (1 << (SPA_MINBLOCKSHIFT + block_shift));
10521038
}
10531039

include/sys/spa_impl.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
*/
2121
/*
2222
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23-
* Copyright (c) 2011, 2014 by Delphix. All rights reserved.
23+
* Copyright (c) 2011, 2015 by Delphix. All rights reserved.
2424
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
2525
* Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
2626
*/
@@ -150,6 +150,8 @@ struct spa {
150150
kcondvar_t spa_evicting_os_cv; /* Objset Eviction Completion */
151151
txg_list_t spa_vdev_txg_list; /* per-txg dirty vdev list */
152152
vdev_t *spa_root_vdev; /* top-level vdev container */
153+
int spa_min_ashift; /* of vdevs in normal class */
154+
int spa_max_ashift; /* of vdevs in normal class */
153155
uint64_t spa_config_guid; /* config pool guid */
154156
uint64_t spa_load_guid; /* spa_load initialized guid */
155157
uint64_t spa_last_synced_guid; /* last synced guid */

include/sys/vdev_impl.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
*/
2121
/*
2222
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23-
* Copyright (c) 2012, 2014 by Delphix. All rights reserved.
23+
* Copyright (c) 2011, 2015 by Delphix. All rights reserved.
2424
*/
2525

2626
#ifndef _SYS_VDEV_IMPL_H
@@ -210,7 +210,7 @@ struct vdev {
210210
boolean_t vdev_isl2cache; /* was a l2cache device */
211211
vdev_queue_t vdev_queue; /* I/O deadline schedule queue */
212212
vdev_cache_t vdev_cache; /* physical block cache */
213-
spa_aux_vdev_t *vdev_aux; /* for l2cache vdevs */
213+
spa_aux_vdev_t *vdev_aux; /* for l2cache and spares vdevs */
214214
zio_t *vdev_probe_zio; /* root of current probe */
215215
vdev_aux_t vdev_label_aux; /* on-disk aux state */
216216

module/zfs/spa.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2245,6 +2245,8 @@ spa_load_impl(spa_t *spa, uint64_t pool_guid, nvlist_t *config,
22452245
return (error);
22462246

22472247
ASSERT(spa->spa_root_vdev == rvd);
2248+
ASSERT3U(spa->spa_min_ashift, >=, SPA_MINBLOCKSHIFT);
2249+
ASSERT3U(spa->spa_max_ashift, <=, SPA_MAXBLOCKSHIFT);
22482250

22492251
if (type != SPA_IMPORT_ASSEMBLE) {
22502252
ASSERT(spa_guid(spa) == pool_guid);

module/zfs/spa_misc.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
*/
2121
/*
2222
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23-
* Copyright (c) 2011, 2014 by Delphix. All rights reserved.
23+
* Copyright (c) 2011, 2015 by Delphix. All rights reserved.
2424
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
2525
* Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
2626
*/
@@ -623,6 +623,9 @@ spa_add(const char *name, nvlist_t *config, const char *altroot)
623623

624624
spa->spa_debug = ((zfs_flags & ZFS_DEBUG_SPA) != 0);
625625

626+
spa->spa_min_ashift = INT_MAX;
627+
spa->spa_max_ashift = 0;
628+
626629
/*
627630
* As a pool is being created, treat all features as disabled by
628631
* setting SPA_FEATURE_DISABLED for all entries in the feature

module/zfs/vdev.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
/*
2323
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
2424
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
25-
* Copyright (c) 2011, 2014 by Delphix. All rights reserved.
25+
* Copyright (c) 2011, 2015 by Delphix. All rights reserved.
2626
*/
2727

2828
#include <sys/zfs_context.h>
@@ -206,8 +206,9 @@ vdev_add_child(vdev_t *pvd, vdev_t *cvd)
206206
size_t oldsize, newsize;
207207
uint64_t id = cvd->vdev_id;
208208
vdev_t **newchild;
209+
spa_t *spa = cvd->vdev_spa;
209210

210-
ASSERT(spa_config_held(cvd->vdev_spa, SCL_ALL, RW_WRITER) == SCL_ALL);
211+
ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == SCL_ALL);
211212
ASSERT(cvd->vdev_parent == NULL);
212213

213214
cvd->vdev_parent = pvd;
@@ -1336,6 +1337,17 @@ vdev_open(vdev_t *vd)
13361337
return (error);
13371338
}
13381339

1340+
/*
1341+
* Track the min and max ashift values for normal data devices.
1342+
*/
1343+
if (vd->vdev_top == vd && vd->vdev_ashift != 0 &&
1344+
!vd->vdev_islog && vd->vdev_aux == NULL) {
1345+
if (vd->vdev_ashift > spa->spa_max_ashift)
1346+
spa->spa_max_ashift = vd->vdev_ashift;
1347+
if (vd->vdev_ashift < spa->spa_min_ashift)
1348+
spa->spa_min_ashift = vd->vdev_ashift;
1349+
}
1350+
13391351
/*
13401352
* If a leaf vdev has a DTL, and seems healthy, then kick off a
13411353
* resilver. But don't do this if we are doing a reopen for a scrub,

module/zfs/zio.c

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
*/
2121
/*
2222
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23-
* Copyright (c) 2011, 2014 by Delphix. All rights reserved.
23+
* Copyright (c) 2011, 2015 by Delphix. All rights reserved.
2424
* Copyright (c) 2011 Nexenta Systems, Inc. All rights reserved.
2525
*/
2626

@@ -1195,19 +1195,26 @@ zio_write_bp_init(zio_t *zio)
11951195
return (ZIO_PIPELINE_CONTINUE);
11961196
} else {
11971197
/*
1198-
* Round up compressed size to MINBLOCKSIZE and
1199-
* zero the tail.
1198+
* Round up compressed size up to the ashift
1199+
* of the smallest-ashift device, and zero the tail.
1200+
* This ensures that the compressed size of the BP
1201+
* (and thus compressratio property) are correct,
1202+
* in that we charge for the padding used to fill out
1203+
* the last sector.
12001204
*/
1201-
size_t rounded =
1202-
P2ROUNDUP(psize, (size_t)SPA_MINBLOCKSIZE);
1203-
if (rounded > psize) {
1204-
bzero((char *)cbuf + psize, rounded - psize);
1205-
psize = rounded;
1206-
}
1207-
if (psize == lsize) {
1205+
size_t rounded;
1206+
1207+
ASSERT3U(spa->spa_min_ashift, >=, SPA_MINBLOCKSHIFT);
1208+
1209+
rounded = (size_t)P2ROUNDUP(psize,
1210+
1ULL << spa->spa_min_ashift);
1211+
if (rounded >= lsize) {
12081212
compress = ZIO_COMPRESS_OFF;
12091213
zio_buf_free(cbuf, lsize);
1214+
psize = lsize;
12101215
} else {
1216+
bzero((char *)cbuf + psize, rounded - psize);
1217+
psize = rounded;
12111218
zio_push_transform(zio, cbuf,
12121219
psize, lsize, NULL);
12131220
}

0 commit comments

Comments
 (0)