]> granicus.if.org Git - zfs/commitdiff
Fix racy assignment of zcb.zcb_haderrors
authorChunwei Chen <david.chen@nutanix.com>
Thu, 1 Feb 2018 23:42:41 +0000 (15:42 -0800)
committerTony Hutter <hutter2@llnl.gov>
Wed, 14 Mar 2018 23:10:36 +0000 (16:10 -0700)
zcb_haderrors will be modified in zdb_blkptr_done, which is
asynchronous. So we must move this assignment after zio_wait.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: loli10K <ezomori.nozomu@gmail.com>
Signed-off-by: Chunwei Chen <david.chen@nutanix.com>
Closes #7099

cmd/zdb/zdb.c

index 442685486e72cd43dec02111eddef7e86766420f..0cc1656a82084743ca37277b2e3f417768eb8bd5 100644 (file)
@@ -3313,7 +3313,7 @@ dump_block_stats(spa_t *spa)
        uint64_t norm_alloc, norm_space, total_alloc, total_found;
        int flags = TRAVERSE_PRE | TRAVERSE_PREFETCH_METADATA | TRAVERSE_HARD;
        boolean_t leaks = B_FALSE;
-       int e, c;
+       int e, c, err;
        bp_embedded_type_t i;
 
        (void) printf("\nTraversing all blocks %s%s%s%s%s...\n\n",
@@ -3354,7 +3354,7 @@ dump_block_stats(spa_t *spa)
 
        zcb.zcb_totalasize = metaslab_class_get_alloc(spa_normal_class(spa));
        zcb.zcb_start = zcb.zcb_lastprint = gethrtime();
-       zcb.zcb_haderrors |= traverse_pool(spa, 0, flags, zdb_blkptr_cb, &zcb);
+       err = traverse_pool(spa, 0, flags, zdb_blkptr_cb, &zcb);
 
        /*
         * If we've traversed the data blocks then we need to wait for those
@@ -3370,6 +3370,12 @@ dump_block_stats(spa_t *spa)
                }
        }
 
+       /*
+        * Done after zio_wait() since zcb_haderrors is modified in
+        * zdb_blkptr_done()
+        */
+       zcb.zcb_haderrors |= err;
+
        if (zcb.zcb_haderrors) {
                (void) printf("\nError counts:\n\n");
                (void) printf("\t%5s  %s\n", "errno", "count");