aboutsummaryrefslogtreecommitdiff
path: root/uts/common/fs/zfs/sys/dnode.h
diff options
context:
space:
mode:
authorXin LI <delphij@FreeBSD.org>2014-08-20 06:34:24 +0000
committerXin LI <delphij@FreeBSD.org>2014-08-20 06:34:24 +0000
commit4662ff88864d53071006391267c7deadaa907e6e (patch)
tree10fce868b2774d3eb1e9200642eda9f810c5b755 /uts/common/fs/zfs/sys/dnode.h
parenta04032b50f086d6a47f8e444b721a52d737d2217 (diff)
downloadsrc-4662ff88864d53071006391267c7deadaa907e6e.tar.gz
src-4662ff88864d53071006391267c7deadaa907e6e.zip
5095 panic when adding a duplicate dbuf to dn_dbufs
Reviewed by: Adam Leventhal <adam.leventhal@delphix.com> Reviewed by: George Wilson <george.wilson@delphix.com> Reviewed by: Mattew Ahrens <mahrens@delphix.com> Reviewed by: Dan Kimmel <dan.kimmel@delphix.com> Reviewed by: Dan McDonald <danmcd@omniti.com> Reviewed by: Josef Sipek <jeffpc@josefsipek.net> Approved by: Robert Mustacchi <rm@joyent.com> Author: Alex Reece <alex@delphix.com> illumos/illumos-gate@86bb58aec7165f8a0303564575c65e5a2ad58bf1
Notes
Notes: svn path=/vendor-sys/illumos/dist/; revision=270198
Diffstat (limited to 'uts/common/fs/zfs/sys/dnode.h')
-rw-r--r--uts/common/fs/zfs/sys/dnode.h13
1 files changed, 12 insertions, 1 deletions
diff --git a/uts/common/fs/zfs/sys/dnode.h b/uts/common/fs/zfs/sys/dnode.h
index 6e4a845a36a1..8a4f3f6185e3 100644
--- a/uts/common/fs/zfs/sys/dnode.h
+++ b/uts/common/fs/zfs/sys/dnode.h
@@ -211,7 +211,18 @@ typedef struct dnode {
refcount_t dn_holds;
kmutex_t dn_dbufs_mtx;
- avl_tree_t dn_dbufs; /* descendent dbufs */
+ /*
+ * Descendent dbufs, ordered by dbuf_compare. Note that dn_dbufs
+ * can contain multiple dbufs of the same (level, blkid) when a
+ * dbuf is marked DB_EVICTING without being removed from
+ * dn_dbufs. To maintain the avl invariant that there cannot be
+ * duplicate entries, we order the dbufs by an arbitrary value -
+ * their address in memory. This means that dn_dbufs cannot be used to
+ * directly look up a dbuf. Instead, callers must use avl_walk, have
+ * a reference to the dbuf, or look up a non-existant node with
+ * db_state = DB_SEARCH (see dbuf_free_range for an example).
+ */
+ avl_tree_t dn_dbufs;
/* protected by dn_struct_rwlock */
struct dmu_buf_impl *dn_bonus; /* bonus buffer dbuf */