/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
*/
#ifndef _SYS_DNODE_H
refcount_t dn_holds;
kmutex_t dn_dbufs_mtx;
- list_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 */
} dnode_handle_t;
typedef struct dnode_children {
+ dmu_buf_user_t dnc_dbu; /* User evict data */
size_t dnc_count; /* number of children */
- dnode_handle_t dnc_children[1]; /* sized dynamically */
+ dnode_handle_t dnc_children[]; /* sized dynamically */
} dnode_children_t;
typedef struct free_range {
uint64_t fr_nblks;
} free_range_t;
-dnode_t *dnode_special_open(struct objset *dd, dnode_phys_t *dnp,
+void dnode_special_open(struct objset *dd, dnode_phys_t *dnp,
uint64_t object, dnode_handle_t *dnh);
void dnode_special_close(dnode_handle_t *dnh);