Print this page
5056 ZFS deadlock on db_mtx and dn_holds
Reviewed by: Will Andrews <willa@spectralogic.com>
Reviewed by: Matt Ahrens <mahrens@delphix.com>
Reviewed by: George Wilson <george.wilson@delphix.com>
Approved by: Dan McDonald <danmcd@omniti.com>


   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright (c) 2012 by Delphix. All rights reserved.

  24  */
  25 
  26 #include <sys/dsl_dataset.h>
  27 #include <sys/dmu.h>
  28 #include <sys/refcount.h>
  29 #include <sys/zap.h>
  30 #include <sys/zfs_context.h>
  31 #include <sys/dsl_pool.h>
  32 
  33 /*
  34  * Deadlist concurrency:
  35  *
  36  * Deadlists can only be modified from the syncing thread.
  37  *
  38  * Except for dsl_deadlist_insert(), it can only be modified with the
  39  * dp_config_rwlock held with RW_WRITER.
  40  *
  41  * The accessors (dsl_deadlist_space() and dsl_deadlist_space_range()) can
  42  * be called concurrently, from open context, with the dl_config_rwlock held
  43  * with RW_READER.


 102         dmu_object_info_from_db(dl->dl_dbuf, &doi);
 103         if (doi.doi_type == DMU_OT_BPOBJ) {
 104                 dmu_buf_rele(dl->dl_dbuf, dl);
 105                 dl->dl_dbuf = NULL;
 106                 dl->dl_oldfmt = B_TRUE;
 107                 VERIFY3U(0, ==, bpobj_open(&dl->dl_bpobj, os, object));
 108                 return;
 109         }
 110 
 111         dl->dl_oldfmt = B_FALSE;
 112         dl->dl_phys = dl->dl_dbuf->db_data;
 113         dl->dl_havetree = B_FALSE;
 114 }
 115 
 116 void
 117 dsl_deadlist_close(dsl_deadlist_t *dl)
 118 {
 119         void *cookie = NULL;
 120         dsl_deadlist_entry_t *dle;
 121 


 122         if (dl->dl_oldfmt) {
 123                 dl->dl_oldfmt = B_FALSE;
 124                 bpobj_close(&dl->dl_bpobj);
 125                 return;
 126         }
 127 
 128         if (dl->dl_havetree) {
 129                 while ((dle = avl_destroy_nodes(&dl->dl_tree, &cookie))
 130                     != NULL) {
 131                         bpobj_close(&dle->dle_bpobj);
 132                         kmem_free(dle, sizeof (*dle));
 133                 }
 134                 avl_destroy(&dl->dl_tree);
 135         }
 136         dmu_buf_rele(dl->dl_dbuf, dl);
 137         mutex_destroy(&dl->dl_lock);
 138         dl->dl_dbuf = NULL;
 139         dl->dl_phys = NULL;
 140 }
 141 




   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright (c) 2012 by Delphix. All rights reserved.
  24  * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
  25  */
  26 
  27 #include <sys/dsl_dataset.h>
  28 #include <sys/dmu.h>
  29 #include <sys/refcount.h>
  30 #include <sys/zap.h>
  31 #include <sys/zfs_context.h>
  32 #include <sys/dsl_pool.h>
  33 
  34 /*
  35  * Deadlist concurrency:
  36  *
  37  * Deadlists can only be modified from the syncing thread.
  38  *
  39  * Except for dsl_deadlist_insert(), it can only be modified with the
  40  * dp_config_rwlock held with RW_WRITER.
  41  *
  42  * The accessors (dsl_deadlist_space() and dsl_deadlist_space_range()) can
  43  * be called concurrently, from open context, with the dl_config_rwlock held
  44  * with RW_READER.


 103         dmu_object_info_from_db(dl->dl_dbuf, &doi);
 104         if (doi.doi_type == DMU_OT_BPOBJ) {
 105                 dmu_buf_rele(dl->dl_dbuf, dl);
 106                 dl->dl_dbuf = NULL;
 107                 dl->dl_oldfmt = B_TRUE;
 108                 VERIFY3U(0, ==, bpobj_open(&dl->dl_bpobj, os, object));
 109                 return;
 110         }
 111 
 112         dl->dl_oldfmt = B_FALSE;
 113         dl->dl_phys = dl->dl_dbuf->db_data;
 114         dl->dl_havetree = B_FALSE;
 115 }
 116 
 117 void
 118 dsl_deadlist_close(dsl_deadlist_t *dl)
 119 {
 120         void *cookie = NULL;
 121         dsl_deadlist_entry_t *dle;
 122 
 123         dl->dl_os = NULL;
 124 
 125         if (dl->dl_oldfmt) {
 126                 dl->dl_oldfmt = B_FALSE;
 127                 bpobj_close(&dl->dl_bpobj);
 128                 return;
 129         }
 130 
 131         if (dl->dl_havetree) {
 132                 while ((dle = avl_destroy_nodes(&dl->dl_tree, &cookie))
 133                     != NULL) {
 134                         bpobj_close(&dle->dle_bpobj);
 135                         kmem_free(dle, sizeof (*dle));
 136                 }
 137                 avl_destroy(&dl->dl_tree);
 138         }
 139         dmu_buf_rele(dl->dl_dbuf, dl);
 140         mutex_destroy(&dl->dl_lock);
 141         dl->dl_dbuf = NULL;
 142         dl->dl_phys = NULL;
 143 }
 144