mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-23 02:44:41 +03:00
OpenZFS 9591 - ms_shift can be incorrectly changed
ms_shift can be incorrectly changed changed in MOS config for indirect vdevs that have been historically expanded According to spa_config_update() we expect new vdevs to have vdev_ms_array equal to 0 and then we go ahead and set their metaslab size. The problem is that indirect vdevs also have vdev_ms_array == 0 because their metaslabs are destroyed once their removal is done. As a result, if a vdev was expanded and then removed may have its ms_shift changed if another vdev was added after its removal. Fortunately this behavior does not cause any type of crash or bad behavior in the kernel but it can confuse zdb and anyone doing any kind of analysis of the history of the pools. Authored by: Serapheim Dimitropoulos <serapheim@delphix.com> Reviewed by: Matthew Ahrens <mahrens@delphix.com> Reviewed by: George Wilson <gwilson@zfsmail.com> Reviewed by: John Kennedy <john.kennedy@delphix.com> Reviewed by: Prashanth Sreenivasa <pks@delphix.com> Reviewed by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Tim Chase <tim@chase2k.com> Ported-by: Tim Chase <tim@chase2k.com> OpenZFS-commit: https://github.com/openzfs/openzfs/pull/651 OpenZFS-issue: https://illumos.org/issues/9591a External-issue: DLPX-58879 Closes #7644
This commit is contained in:
committed by
Brian Behlendorf
parent
af43029484
commit
7637ef8d23
+13
-1
@@ -22,7 +22,7 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2011, 2015 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2011, 2018 by Delphix. All rights reserved.
|
||||
* Copyright 2017 Joyent, Inc.
|
||||
*/
|
||||
|
||||
@@ -576,6 +576,18 @@ spa_config_update(spa_t *spa, int what)
|
||||
*/
|
||||
for (c = 0; c < rvd->vdev_children; c++) {
|
||||
vdev_t *tvd = rvd->vdev_child[c];
|
||||
|
||||
/*
|
||||
* Explicitly skip vdevs that are indirect or
|
||||
* log vdevs that are being removed. The reason
|
||||
* is that both of those can have vdev_ms_array
|
||||
* set to 0 and we wouldn't want to change their
|
||||
* metaslab size nor call vdev_expand() on them.
|
||||
*/
|
||||
if (!vdev_is_concrete(tvd) ||
|
||||
(tvd->vdev_islog && tvd->vdev_removing))
|
||||
continue;
|
||||
|
||||
if (tvd->vdev_ms_array == 0)
|
||||
vdev_metaslab_set_size(tvd);
|
||||
vdev_expand(tvd, txg);
|
||||
|
||||
+2
-2
@@ -4172,11 +4172,11 @@ vdev_expand(vdev_t *vd, uint64_t txg)
|
||||
{
|
||||
ASSERT(vd->vdev_top == vd);
|
||||
ASSERT(spa_config_held(vd->vdev_spa, SCL_ALL, RW_WRITER) == SCL_ALL);
|
||||
ASSERT(vdev_is_concrete(vd));
|
||||
|
||||
vdev_set_deflate_ratio(vd);
|
||||
|
||||
if ((vd->vdev_asize >> vd->vdev_ms_shift) > vd->vdev_ms_count &&
|
||||
vdev_is_concrete(vd)) {
|
||||
if ((vd->vdev_asize >> vd->vdev_ms_shift) > vd->vdev_ms_count) {
|
||||
VERIFY(vdev_metaslab_init(vd, txg) == 0);
|
||||
vdev_config_dirty(vd);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user