diff options
author | Keith M Wesolowski <wesolows@foobazco.org> | 2014-07-18 16:22:19 +0000 |
---|---|---|
committer | Keith M Wesolowski <wesolows@foobazco.org> | 2014-07-18 16:22:19 +0000 |
commit | f1cf1ab6d856ffb10ae7e44f10e17b457dcb698e (patch) | |
tree | 88a38416301bd8688406c456788701b45f0a654f /usr/src/uts/common/fs/zfs/dbuf.c | |
parent | af57471d469f7bb4ddca3c9f26895497ff4a86e0 (diff) | |
parent | 73527f441cbbd953fa42cc5a30a413bad75f24a9 (diff) | |
download | illumos-joyent-f1cf1ab6d856ffb10ae7e44f10e17b457dcb698e.tar.gz |
[illumos-gate merge]
commit 73527f441cbbd953fa42cc5a30a413bad75f24a9
4753 increase number of outstanding async writes when sync task is waiting
commit bbfa8ea8bb4168c969ba27d632dfe0aeec3fc0da
4631 zvol_get_stats triggering too many reads
commit 2a104a5236475eb73aa41eaaf3ed9f3ccbe0ca55
4958 zdb trips assert on pools with ashift >= 0xe
commit b4ecf764d8099c92d5c9c0f13a45514377f3d292
4995 panic in nlm_prog_4
commit 5cd496e3c5514951ae23bdd897cb29b202e2ff62
4994 nlm_register_lock_locally() fails to unlock held locks
commit 542a813c9f6736dc348fecc7244bf22b4e0a319c
5003 want kstats for per-zone cpu usage
Conflicts:
usr/src/uts/common/sys/zone.h
usr/src/uts/common/os/zone.c
usr/src/uts/common/klm/nlm_service.c
usr/src/uts/common/fs/zfs/metaslab.c
Diffstat (limited to 'usr/src/uts/common/fs/zfs/dbuf.c')
-rw-r--r-- | usr/src/uts/common/fs/zfs/dbuf.c | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/usr/src/uts/common/fs/zfs/dbuf.c b/usr/src/uts/common/fs/zfs/dbuf.c index 3480c64ec0..83afd52df4 100644 --- a/usr/src/uts/common/fs/zfs/dbuf.c +++ b/usr/src/uts/common/fs/zfs/dbuf.c @@ -181,8 +181,7 @@ dbuf_hash_insert(dmu_buf_impl_t *db) } /* - * Remove an entry from the hash table. This operation will - * fail if there are any existing holds on the db. + * Remove an entry from the hash table. It must be in the EVICTING state. */ static void dbuf_hash_remove(dmu_buf_impl_t *db) @@ -194,7 +193,7 @@ dbuf_hash_remove(dmu_buf_impl_t *db) dmu_buf_impl_t *dbf, **dbp; /* - * We musn't hold db_mtx to maintin lock ordering: + * We musn't hold db_mtx to maintain lock ordering: * DBUF_HASH_MUTEX > db_mtx. */ ASSERT(refcount_is_zero(&db->db_holds)); @@ -431,7 +430,6 @@ static void dbuf_set_data(dmu_buf_impl_t *db, arc_buf_t *buf) { ASSERT(MUTEX_HELD(&db->db_mtx)); - ASSERT(db->db_buf == NULL || !arc_has_callback(db->db_buf)); db->db_buf = buf; if (buf != NULL) { ASSERT(buf->b_data != NULL); @@ -1555,12 +1553,15 @@ dbuf_assign_arcbuf(dmu_buf_impl_t *db, arc_buf_t *buf, dmu_tx_t *tx) * when we are not holding the dn_dbufs_mtx, we can't clear the * entry in the dn_dbufs list. We have to wait until dbuf_destroy() * in this case. For callers from the DMU we will usually see: - * dbuf_clear()->arc_buf_evict()->dbuf_do_evict()->dbuf_destroy() + * dbuf_clear()->arc_clear_callback()->dbuf_do_evict()->dbuf_destroy() * For the arc callback, we will usually see: * dbuf_do_evict()->dbuf_clear();dbuf_destroy() * Sometimes, though, we will get a mix of these two: - * DMU: dbuf_clear()->arc_buf_evict() + * DMU: dbuf_clear()->arc_clear_callback() * ARC: dbuf_do_evict()->dbuf_destroy() + * + * This routine will dissociate the dbuf from the arc, by calling + * arc_clear_callback(), but will not evict the data from the ARC. */ void dbuf_clear(dmu_buf_impl_t *db) @@ -1568,7 +1569,7 @@ dbuf_clear(dmu_buf_impl_t *db) dnode_t *dn; dmu_buf_impl_t *parent = db->db_parent; dmu_buf_impl_t *dndb; - int dbuf_gone = FALSE; + boolean_t dbuf_gone = B_FALSE; ASSERT(MUTEX_HELD(&db->db_mtx)); ASSERT(refcount_is_zero(&db->db_holds)); @@ -1614,7 +1615,7 @@ dbuf_clear(dmu_buf_impl_t *db) } if (db->db_buf) - dbuf_gone = arc_buf_evict(db->db_buf); + dbuf_gone = arc_clear_callback(db->db_buf); if (!dbuf_gone) mutex_exit(&db->db_mtx); @@ -1782,8 +1783,7 @@ dbuf_create(dnode_t *dn, uint8_t level, uint64_t blkid, static int dbuf_do_evict(void *private) { - arc_buf_t *buf = private; - dmu_buf_impl_t *db = buf->b_private; + dmu_buf_impl_t *db = private; if (!MUTEX_HELD(&db->db_mtx)) mutex_enter(&db->db_mtx); @@ -2146,11 +2146,23 @@ dbuf_rele_and_unlock(dmu_buf_impl_t *db, void *tag) * block on-disk. If so, then we simply evict * ourselves. */ - if (!DBUF_IS_CACHEABLE(db) || - arc_buf_eviction_needed(db->db_buf)) + if (!DBUF_IS_CACHEABLE(db)) { + if (db->db_blkptr != NULL && + !BP_IS_HOLE(db->db_blkptr) && + !BP_IS_EMBEDDED(db->db_blkptr)) { + spa_t *spa = + dmu_objset_spa(db->db_objset); + blkptr_t bp = *db->db_blkptr; + dbuf_clear(db); + arc_freed(spa, &bp); + } else { + dbuf_clear(db); + } + } else if (arc_buf_eviction_needed(db->db_buf)) { dbuf_clear(db); - else + } else { mutex_exit(&db->db_mtx); + } } } else { mutex_exit(&db->db_mtx); |