Deleted Added
full compact
dbuf.c (284593) dbuf.c (286541)
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
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

--- 104 unchanged lines hidden (view full) ---

113
114#define DBUF_EQUAL(dbuf, os, obj, level, blkid) \
115 ((dbuf)->db.db_object == (obj) && \
116 (dbuf)->db_objset == (os) && \
117 (dbuf)->db_level == (level) && \
118 (dbuf)->db_blkid == (blkid))
119
120dmu_buf_impl_t *
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
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

--- 104 unchanged lines hidden (view full) ---

113
114#define DBUF_EQUAL(dbuf, os, obj, level, blkid) \
115 ((dbuf)->db.db_object == (obj) && \
116 (dbuf)->db_objset == (os) && \
117 (dbuf)->db_level == (level) && \
118 (dbuf)->db_blkid == (blkid))
119
120dmu_buf_impl_t *
121dbuf_find(dnode_t *dn, uint8_t level, uint64_t blkid)
121dbuf_find(objset_t *os, uint64_t obj, uint8_t level, uint64_t blkid)
122{
123 dbuf_hash_table_t *h = &dbuf_hash_table;
122{
123 dbuf_hash_table_t *h = &dbuf_hash_table;
124 objset_t *os = dn->dn_objset;
125 uint64_t obj = dn->dn_object;
126 uint64_t hv = DBUF_HASH(os, obj, level, blkid);
127 uint64_t idx = hv & h->hash_table_mask;
128 dmu_buf_impl_t *db;
129
130 mutex_enter(DBUF_HASH_MUTEX(h, idx));
131 for (db = h->hash_table[idx]; db != NULL; db = db->db_hash_next) {
132 if (DBUF_EQUAL(db, os, obj, level, blkid)) {
133 mutex_enter(&db->db_mtx);
134 if (db->db_state != DB_EVICTING) {
135 mutex_exit(DBUF_HASH_MUTEX(h, idx));
136 return (db);
137 }
138 mutex_exit(&db->db_mtx);
139 }
140 }
141 mutex_exit(DBUF_HASH_MUTEX(h, idx));
142 return (NULL);
143}
144
124 uint64_t hv = DBUF_HASH(os, obj, level, blkid);
125 uint64_t idx = hv & h->hash_table_mask;
126 dmu_buf_impl_t *db;
127
128 mutex_enter(DBUF_HASH_MUTEX(h, idx));
129 for (db = h->hash_table[idx]; db != NULL; db = db->db_hash_next) {
130 if (DBUF_EQUAL(db, os, obj, level, blkid)) {
131 mutex_enter(&db->db_mtx);
132 if (db->db_state != DB_EVICTING) {
133 mutex_exit(DBUF_HASH_MUTEX(h, idx));
134 return (db);
135 }
136 mutex_exit(&db->db_mtx);
137 }
138 }
139 mutex_exit(DBUF_HASH_MUTEX(h, idx));
140 return (NULL);
141}
142
143static dmu_buf_impl_t *
144dbuf_find_bonus(objset_t *os, uint64_t object)
145{
146 dnode_t *dn;
147 dmu_buf_impl_t *db = NULL;
148
149 if (dnode_hold(os, object, FTAG, &dn) == 0) {
150 rw_enter(&dn->dn_struct_rwlock, RW_READER);
151 if (dn->dn_bonus != NULL) {
152 db = dn->dn_bonus;
153 mutex_enter(&db->db_mtx);
154 }
155 rw_exit(&dn->dn_struct_rwlock);
156 dnode_rele(dn, FTAG);
157 }
158 return (db);
159}
160
145/*
146 * Insert an entry into the hash table. If there is already an element
147 * equal to elem in the hash table, then the already existing element
148 * will be returned and the new element will not be inserted.
149 * Otherwise returns NULL.
150 */
151static dmu_buf_impl_t *
152dbuf_hash_insert(dmu_buf_impl_t *db)

--- 1694 unchanged lines hidden (view full) ---

1847
1848 ASSERT(blkid != DMU_BONUS_BLKID);
1849 ASSERT(RW_LOCK_HELD(&dn->dn_struct_rwlock));
1850
1851 if (dnode_block_freed(dn, blkid))
1852 return;
1853
1854 /* dbuf_find() returns with db_mtx held */
161/*
162 * Insert an entry into the hash table. If there is already an element
163 * equal to elem in the hash table, then the already existing element
164 * will be returned and the new element will not be inserted.
165 * Otherwise returns NULL.
166 */
167static dmu_buf_impl_t *
168dbuf_hash_insert(dmu_buf_impl_t *db)

--- 1694 unchanged lines hidden (view full) ---

1863
1864 ASSERT(blkid != DMU_BONUS_BLKID);
1865 ASSERT(RW_LOCK_HELD(&dn->dn_struct_rwlock));
1866
1867 if (dnode_block_freed(dn, blkid))
1868 return;
1869
1870 /* dbuf_find() returns with db_mtx held */
1855 if (db = dbuf_find(dn, 0, blkid)) {
1871 if (db = dbuf_find(dn->dn_objset, dn->dn_object, 0, blkid)) {
1856 /*
1857 * This dbuf is already in the cache. We assume that
1858 * it is already CACHED, or else about to be either
1859 * read or filled.
1860 */
1861 mutex_exit(&db->db_mtx);
1862 return;
1863 }

--- 30 unchanged lines hidden (view full) ---

1894
1895 ASSERT(blkid != DMU_BONUS_BLKID);
1896 ASSERT(RW_LOCK_HELD(&dn->dn_struct_rwlock));
1897 ASSERT3U(dn->dn_nlevels, >, level);
1898
1899 *dbp = NULL;
1900top:
1901 /* dbuf_find() returns with db_mtx held */
1872 /*
1873 * This dbuf is already in the cache. We assume that
1874 * it is already CACHED, or else about to be either
1875 * read or filled.
1876 */
1877 mutex_exit(&db->db_mtx);
1878 return;
1879 }

--- 30 unchanged lines hidden (view full) ---

1910
1911 ASSERT(blkid != DMU_BONUS_BLKID);
1912 ASSERT(RW_LOCK_HELD(&dn->dn_struct_rwlock));
1913 ASSERT3U(dn->dn_nlevels, >, level);
1914
1915 *dbp = NULL;
1916top:
1917 /* dbuf_find() returns with db_mtx held */
1902 db = dbuf_find(dn, level, blkid);
1918 db = dbuf_find(dn->dn_objset, dn->dn_object, level, blkid);
1903
1904 if (db == NULL) {
1905 blkptr_t *bp = NULL;
1906 int err;
1907
1908 ASSERT3P(parent, ==, NULL);
1909 err = dbuf_findbp(dn, level, blkid, fail_sparse, &parent, &bp);
1910 if (fail_sparse) {

--- 119 unchanged lines hidden (view full) ---

2030#pragma weak dmu_buf_add_ref = dbuf_add_ref
2031void
2032dbuf_add_ref(dmu_buf_impl_t *db, void *tag)
2033{
2034 int64_t holds = refcount_add(&db->db_holds, tag);
2035 ASSERT(holds > 1);
2036}
2037
1919
1920 if (db == NULL) {
1921 blkptr_t *bp = NULL;
1922 int err;
1923
1924 ASSERT3P(parent, ==, NULL);
1925 err = dbuf_findbp(dn, level, blkid, fail_sparse, &parent, &bp);
1926 if (fail_sparse) {

--- 119 unchanged lines hidden (view full) ---

2046#pragma weak dmu_buf_add_ref = dbuf_add_ref
2047void
2048dbuf_add_ref(dmu_buf_impl_t *db, void *tag)
2049{
2050 int64_t holds = refcount_add(&db->db_holds, tag);
2051 ASSERT(holds > 1);
2052}
2053
2054#pragma weak dmu_buf_try_add_ref = dbuf_try_add_ref
2055boolean_t
2056dbuf_try_add_ref(dmu_buf_t *db_fake, objset_t *os, uint64_t obj, uint64_t blkid,
2057 void *tag)
2058{
2059 dmu_buf_impl_t *db = (dmu_buf_impl_t *)db_fake;
2060 dmu_buf_impl_t *found_db;
2061 boolean_t result = B_FALSE;
2062
2063 if (db->db_blkid == DMU_BONUS_BLKID)
2064 found_db = dbuf_find_bonus(os, obj);
2065 else
2066 found_db = dbuf_find(os, obj, 0, blkid);
2067
2068 if (found_db != NULL) {
2069 if (db == found_db && dbuf_refcount(db) > db->db_dirtycnt) {
2070 (void) refcount_add(&db->db_holds, tag);
2071 result = B_TRUE;
2072 }
2073 mutex_exit(&db->db_mtx);
2074 }
2075 return (result);
2076}
2077
2038/*
2039 * If you call dbuf_rele() you had better not be referencing the dnode handle
2040 * unless you have some other direct or indirect hold on the dnode. (An indirect
2041 * hold is a hold on one of the dnode's dbufs, including the bonus buffer.)
2042 * Without that, the dbuf_rele() could lead to a dnode_rele() followed by the
2043 * dnode's parent dbuf evicting its dnode handles.
2044 */
2045void

--- 798 unchanged lines hidden ---
2078/*
2079 * If you call dbuf_rele() you had better not be referencing the dnode handle
2080 * unless you have some other direct or indirect hold on the dnode. (An indirect
2081 * hold is a hold on one of the dnode's dbufs, including the bonus buffer.)
2082 * Without that, the dbuf_rele() could lead to a dnode_rele() followed by the
2083 * dnode's parent dbuf evicting its dnode handles.
2084 */
2085void

--- 798 unchanged lines hidden ---