]> git.proxmox.com Git - mirror_zfs.git/commitdiff
OpenZFS 7163 - ztest failures due to excess error injection
authorGeorge Melikov <mail@gmelikov.ru>
Thu, 26 Jan 2017 20:34:29 +0000 (23:34 +0300)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Thu, 26 Jan 2017 20:34:29 +0000 (12:34 -0800)
Authored by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: George Wilson <george.wilson@delphix.com>
Reviewed by: Paul Dagnelie <pcd@delphix.com>
Approved by: Robert Mustacchi <rm@joyent.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Ported-by: George Melikov <mail@gmelikov.ru>
OpenZFS-issue: https://www.illumos.org/issues/7163
OpenZFS-commit: https://github.com/openzfs/openzfs/commit/f34284d
Closes #4484
Closes #5661

cmd/ztest/ztest.c

index 3b504e7913f57266da87d605bd2888fca654422e..1f5afe4afcdf06360882c8e013a697a8b2a67cd6 100644 (file)
@@ -5214,7 +5214,7 @@ ztest_fault_inject(ztest_ds_t *zd, uint64_t id)
        char *path0;
        char *pathrand;
        size_t fsize;
-       int bshift = SPA_MAXBLOCKSHIFT + 2;     /* don't scrog all labels */
+       int bshift = SPA_MAXBLOCKSHIFT + 2;
        int iters = 1000;
        int maxfaults;
        int mirror_save;
@@ -5407,7 +5407,29 @@ ztest_fault_inject(ztest_ds_t *zd, uint64_t id)
                    (leaves << bshift) + (leaf << bshift) +
                    (ztest_random(1ULL << (bshift - 1)) & -8ULL);
 
-               if (offset >= fsize)
+               /*
+                * Only allow damage to the labels at one end of the vdev.
+                *
+                * If all labels are damaged, the device will be totally
+                * inaccessible, which will result in loss of data,
+                * because we also damage (parts of) the other side of
+                * the mirror/raidz.
+                *
+                * Additionally, we will always have both an even and an
+                * odd label, so that we can handle crashes in the
+                * middle of vdev_config_sync().
+                */
+               if ((leaf & 1) == 0 && offset < VDEV_LABEL_START_SIZE)
+                       continue;
+
+               /*
+                * The two end labels are stored at the "end" of the disk, but
+                * the end of the disk (vdev_psize) is aligned to
+                * sizeof (vdev_label_t).
+                */
+               uint64_t psize = P2ALIGN(fsize, sizeof (vdev_label_t));
+               if ((leaf & 1) == 1 &&
+                   offset + sizeof (bad) > psize - VDEV_LABEL_END_SIZE)
                        continue;
 
                mutex_enter(&ztest_vdev_lock);