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>


   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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright (c) 2013 by Delphix. All rights reserved.
  24  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  25  * Copyright (c) 2013 Steven Hartland. All rights reserved.

  26  */
  27 
  28 #ifndef _SYS_DSL_DATASET_H
  29 #define _SYS_DSL_DATASET_H
  30 
  31 #include <sys/dmu.h>
  32 #include <sys/spa.h>
  33 #include <sys/txg.h>
  34 #include <sys/zio.h>
  35 #include <sys/bplist.h>
  36 #include <sys/dsl_synctask.h>
  37 #include <sys/zfs_context.h>
  38 #include <sys/dsl_deadlist.h>
  39 #include <sys/refcount.h>
  40 
  41 #ifdef  __cplusplus
  42 extern "C" {
  43 #endif
  44 
  45 struct dsl_dataset;


 115         uint64_t ds_referenced_bytes;
 116         uint64_t ds_compressed_bytes;
 117         uint64_t ds_uncompressed_bytes;
 118         uint64_t ds_unique_bytes;       /* only relevant to snapshots */
 119         /*
 120          * The ds_fsid_guid is a 56-bit ID that can change to avoid
 121          * collisions.  The ds_guid is a 64-bit ID that will never
 122          * change, so there is a small probability that it will collide.
 123          */
 124         uint64_t ds_fsid_guid;
 125         uint64_t ds_guid;
 126         uint64_t ds_flags;              /* DS_FLAG_* */
 127         blkptr_t ds_bp;
 128         uint64_t ds_next_clones_obj;    /* DMU_OT_DSL_CLONES */
 129         uint64_t ds_props_obj;          /* DMU_OT_DSL_PROPS for snaps */
 130         uint64_t ds_userrefs_obj;       /* DMU_OT_USERREFS */
 131         uint64_t ds_pad[5]; /* pad out to 320 bytes for good measure */
 132 } dsl_dataset_phys_t;
 133 
 134 typedef struct dsl_dataset {


 135         /* Immutable: */
 136         struct dsl_dir *ds_dir;
 137         dmu_buf_t *ds_dbuf;
 138         uint64_t ds_object;
 139         uint64_t ds_fsid_guid;

 140 
 141         /* only used in syncing context, only valid for non-snapshots: */
 142         struct dsl_dataset *ds_prev;
 143         uint64_t ds_bookmarks;  /* DMU_OTN_ZAP_METADATA */
 144         boolean_t ds_large_blocks;
 145         boolean_t ds_need_large_blocks;
 146 
 147         /* has internal locking: */
 148         dsl_deadlist_t ds_deadlist;
 149         bplist_t ds_pending_deadlist;
 150 
 151         /* protected by lock on pool's dp_dirty_datasets list */
 152         txg_node_t ds_dirty_link;
 153         list_node_t ds_synced_link;
 154 
 155         /*
 156          * ds_phys->ds_<accounting> is also protected by ds_lock.
 157          * Protected by ds_lock:
 158          */
 159         kmutex_t ds_lock;


 180 
 181         kmutex_t ds_sendstream_lock;
 182         list_t ds_sendstreams;
 183 
 184         /* Protected by ds_lock; keep at end of struct for better locality */
 185         char ds_snapname[MAXNAMELEN];
 186 } dsl_dataset_t;
 187 
 188 inline dsl_dataset_phys_t *
 189 dsl_dataset_phys(dsl_dataset_t *ds)
 190 {
 191         return (ds->ds_dbuf->db_data);
 192 }
 193 
 194 /*
 195  * The max length of a temporary tag prefix is the number of hex digits
 196  * required to express UINT64_MAX plus one for the hyphen.
 197  */
 198 #define MAX_TAG_PREFIX_LEN      17
 199 
 200 inline boolean_t
 201 dsl_dataset_is_snapshot(dsl_dataset_t *ds)
 202 {
 203         return (dsl_dataset_phys(ds)->ds_num_children != 0);
 204 }
 205 
 206 #define DS_UNIQUE_IS_ACCURATE(ds)       \
 207         ((dsl_dataset_phys(ds)->ds_flags & DS_FLAG_UNIQUE_ACCURATE) != 0)
 208 
 209 int dsl_dataset_hold(struct dsl_pool *dp, const char *name, void *tag,
 210     dsl_dataset_t **dsp);
 211 int dsl_dataset_hold_obj(struct dsl_pool *dp, uint64_t dsobj, void *tag,
 212     dsl_dataset_t **);
 213 void dsl_dataset_rele(dsl_dataset_t *ds, void *tag);
 214 int dsl_dataset_own(struct dsl_pool *dp, const char *name,
 215     void *tag, dsl_dataset_t **dsp);
 216 int dsl_dataset_own_obj(struct dsl_pool *dp, uint64_t dsobj,
 217     void *tag, dsl_dataset_t **dsp);
 218 void dsl_dataset_disown(dsl_dataset_t *ds, void *tag);
 219 void dsl_dataset_name(dsl_dataset_t *ds, char *name);
 220 boolean_t dsl_dataset_tryown(dsl_dataset_t *ds, void *tag);
 221 uint64_t dsl_dataset_create_sync(dsl_dir_t *pds, const char *lastname,
 222     dsl_dataset_t *origin, uint64_t flags, cred_t *, dmu_tx_t *);
 223 uint64_t dsl_dataset_create_sync_dd(dsl_dir_t *dd, dsl_dataset_t *origin,
 224     uint64_t flags, dmu_tx_t *tx);
 225 int dsl_dataset_snapshot(nvlist_t *snaps, nvlist_t *props, nvlist_t *errors);




   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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright (c) 2013 by Delphix. All rights reserved.
  24  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  25  * Copyright (c) 2013 Steven Hartland. All rights reserved.
  26  * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
  27  */
  28 
  29 #ifndef _SYS_DSL_DATASET_H
  30 #define _SYS_DSL_DATASET_H
  31 
  32 #include <sys/dmu.h>
  33 #include <sys/spa.h>
  34 #include <sys/txg.h>
  35 #include <sys/zio.h>
  36 #include <sys/bplist.h>
  37 #include <sys/dsl_synctask.h>
  38 #include <sys/zfs_context.h>
  39 #include <sys/dsl_deadlist.h>
  40 #include <sys/refcount.h>
  41 
  42 #ifdef  __cplusplus
  43 extern "C" {
  44 #endif
  45 
  46 struct dsl_dataset;


 116         uint64_t ds_referenced_bytes;
 117         uint64_t ds_compressed_bytes;
 118         uint64_t ds_uncompressed_bytes;
 119         uint64_t ds_unique_bytes;       /* only relevant to snapshots */
 120         /*
 121          * The ds_fsid_guid is a 56-bit ID that can change to avoid
 122          * collisions.  The ds_guid is a 64-bit ID that will never
 123          * change, so there is a small probability that it will collide.
 124          */
 125         uint64_t ds_fsid_guid;
 126         uint64_t ds_guid;
 127         uint64_t ds_flags;              /* DS_FLAG_* */
 128         blkptr_t ds_bp;
 129         uint64_t ds_next_clones_obj;    /* DMU_OT_DSL_CLONES */
 130         uint64_t ds_props_obj;          /* DMU_OT_DSL_PROPS for snaps */
 131         uint64_t ds_userrefs_obj;       /* DMU_OT_USERREFS */
 132         uint64_t ds_pad[5]; /* pad out to 320 bytes for good measure */
 133 } dsl_dataset_phys_t;
 134 
 135 typedef struct dsl_dataset {
 136         dmu_buf_user_t ds_dbu;
 137 
 138         /* Immutable: */
 139         struct dsl_dir *ds_dir;
 140         dmu_buf_t *ds_dbuf;
 141         uint64_t ds_object;
 142         uint64_t ds_fsid_guid;
 143         boolean_t ds_is_snapshot;
 144 
 145         /* only used in syncing context, only valid for non-snapshots: */
 146         struct dsl_dataset *ds_prev;
 147         uint64_t ds_bookmarks;  /* DMU_OTN_ZAP_METADATA */
 148         boolean_t ds_large_blocks;
 149         boolean_t ds_need_large_blocks;
 150 
 151         /* has internal locking: */
 152         dsl_deadlist_t ds_deadlist;
 153         bplist_t ds_pending_deadlist;
 154 
 155         /* protected by lock on pool's dp_dirty_datasets list */
 156         txg_node_t ds_dirty_link;
 157         list_node_t ds_synced_link;
 158 
 159         /*
 160          * ds_phys->ds_<accounting> is also protected by ds_lock.
 161          * Protected by ds_lock:
 162          */
 163         kmutex_t ds_lock;


 184 
 185         kmutex_t ds_sendstream_lock;
 186         list_t ds_sendstreams;
 187 
 188         /* Protected by ds_lock; keep at end of struct for better locality */
 189         char ds_snapname[MAXNAMELEN];
 190 } dsl_dataset_t;
 191 
 192 inline dsl_dataset_phys_t *
 193 dsl_dataset_phys(dsl_dataset_t *ds)
 194 {
 195         return (ds->ds_dbuf->db_data);
 196 }
 197 
 198 /*
 199  * The max length of a temporary tag prefix is the number of hex digits
 200  * required to express UINT64_MAX plus one for the hyphen.
 201  */
 202 #define MAX_TAG_PREFIX_LEN      17
 203 






 204 #define DS_UNIQUE_IS_ACCURATE(ds)       \
 205         ((dsl_dataset_phys(ds)->ds_flags & DS_FLAG_UNIQUE_ACCURATE) != 0)
 206 
 207 int dsl_dataset_hold(struct dsl_pool *dp, const char *name, void *tag,
 208     dsl_dataset_t **dsp);
 209 int dsl_dataset_hold_obj(struct dsl_pool *dp, uint64_t dsobj, void *tag,
 210     dsl_dataset_t **);
 211 void dsl_dataset_rele(dsl_dataset_t *ds, void *tag);
 212 int dsl_dataset_own(struct dsl_pool *dp, const char *name,
 213     void *tag, dsl_dataset_t **dsp);
 214 int dsl_dataset_own_obj(struct dsl_pool *dp, uint64_t dsobj,
 215     void *tag, dsl_dataset_t **dsp);
 216 void dsl_dataset_disown(dsl_dataset_t *ds, void *tag);
 217 void dsl_dataset_name(dsl_dataset_t *ds, char *name);
 218 boolean_t dsl_dataset_tryown(dsl_dataset_t *ds, void *tag);
 219 uint64_t dsl_dataset_create_sync(dsl_dir_t *pds, const char *lastname,
 220     dsl_dataset_t *origin, uint64_t flags, cred_t *, dmu_tx_t *);
 221 uint64_t dsl_dataset_create_sync_dd(dsl_dir_t *dd, dsl_dataset_t *origin,
 222     uint64_t flags, dmu_tx_t *tx);
 223 int dsl_dataset_snapshot(nvlist_t *snaps, nvlist_t *props, nvlist_t *errors);