diff options
author | Alex Reece <[email protected]> | 2015-04-02 02:10:58 +1100 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2015-04-28 16:24:49 -0700 |
commit | 9925c28cdec943a6ffa81219cb469b727decf111 (patch) | |
tree | 219c9802db1a1a145deecd66d9bdfab7606e1b51 /include/sys | |
parent | 5aea3644d6aef3fe636053d6924bc0803fbd75b5 (diff) |
Illumos 5095 - panic when adding a duplicate dbuf to dn_dbufs
5095 panic when adding a duplicate dbuf to dn_dbufs
Author: Alex Reece <[email protected]>
Reviewed by: Adam Leventhal <[email protected]>
Reviewed by: George Wilson <[email protected]>
Reviewed by: Mattew Ahrens <[email protected]>
Reviewed by: Dan Kimmel <[email protected]>
Reviewed by: Dan McDonald <[email protected]>
Reviewed by: Josef Sipek <[email protected]>
Approved by: Robert Mustacchi <[email protected]>
References:
https://www.illumos.org/issues/5095
https://github.com/illumos/illumos-gate/commit/86bb58a
Ported-by: Chris Dunlop <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Diffstat (limited to 'include/sys')
-rw-r--r-- | include/sys/dbuf.h | 8 | ||||
-rw-r--r-- | include/sys/dnode.h | 13 |
2 files changed, 17 insertions, 4 deletions
diff --git a/include/sys/dbuf.h b/include/sys/dbuf.h index 2f593bb4d..d253add59 100644 --- a/include/sys/dbuf.h +++ b/include/sys/dbuf.h @@ -66,8 +66,13 @@ extern "C" { * | | * | | * +--------> NOFILL -------+ + * + * DB_SEARCH is an invalid state for a dbuf. It is used by dbuf_free_range + * to find all dbufs in a range of a dnode and must be less than any other + * dbuf_states_t (see comment on dn_dbufs in dnode.h). */ typedef enum dbuf_states { + DB_SEARCH = -1, DB_UNCACHED, DB_FILL, DB_NOFILL, @@ -213,9 +218,6 @@ typedef struct dmu_buf_impl { /* pointer to most recent dirty record for this buffer */ dbuf_dirty_record_t *db_last_dirty; - /* Creation time of dbuf (see comment in dbuf_compare). */ - hrtime_t db_creation; - /* * Our link on the owner dnodes's dn_dbufs list. * Protected by its dn_dbufs_mtx. diff --git a/include/sys/dnode.h b/include/sys/dnode.h index 2974a20dc..90a334ba7 100644 --- a/include/sys/dnode.h +++ b/include/sys/dnode.h @@ -233,7 +233,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 */ |