Print this page
5045 use atomic_{inc,dec}_* instead of atomic_add_*


 158         uint64_t hv = DBUF_HASH(os, obj, level, blkid);
 159         uint64_t idx = hv & h->hash_table_mask;
 160         dmu_buf_impl_t *dbf;
 161 
 162         mutex_enter(DBUF_HASH_MUTEX(h, idx));
 163         for (dbf = h->hash_table[idx]; dbf != NULL; dbf = dbf->db_hash_next) {
 164                 if (DBUF_EQUAL(dbf, os, obj, level, blkid)) {
 165                         mutex_enter(&dbf->db_mtx);
 166                         if (dbf->db_state != DB_EVICTING) {
 167                                 mutex_exit(DBUF_HASH_MUTEX(h, idx));
 168                                 return (dbf);
 169                         }
 170                         mutex_exit(&dbf->db_mtx);
 171                 }
 172         }
 173 
 174         mutex_enter(&db->db_mtx);
 175         db->db_hash_next = h->hash_table[idx];
 176         h->hash_table[idx] = db;
 177         mutex_exit(DBUF_HASH_MUTEX(h, idx));
 178         atomic_add_64(&dbuf_hash_count, 1);
 179 
 180         return (NULL);
 181 }
 182 
 183 /*
 184  * Remove an entry from the hash table.  This operation will
 185  * fail if there are any existing holds on the db.
 186  */
 187 static void
 188 dbuf_hash_remove(dmu_buf_impl_t *db)
 189 {
 190         dbuf_hash_table_t *h = &dbuf_hash_table;
 191         uint64_t hv = DBUF_HASH(db->db_objset, db->db.db_object,
 192             db->db_level, db->db_blkid);
 193         uint64_t idx = hv & h->hash_table_mask;
 194         dmu_buf_impl_t *dbf, **dbp;
 195 
 196         /*
 197          * We musn't hold db_mtx to maintin lock ordering:
 198          * DBUF_HASH_MUTEX > db_mtx.
 199          */
 200         ASSERT(refcount_is_zero(&db->db_holds));
 201         ASSERT(db->db_state == DB_EVICTING);
 202         ASSERT(!MUTEX_HELD(&db->db_mtx));
 203 
 204         mutex_enter(DBUF_HASH_MUTEX(h, idx));
 205         dbp = &h->hash_table[idx];
 206         while ((dbf = *dbp) != db) {
 207                 dbp = &dbf->db_hash_next;
 208                 ASSERT(dbf != NULL);
 209         }
 210         *dbp = db->db_hash_next;
 211         db->db_hash_next = NULL;
 212         mutex_exit(DBUF_HASH_MUTEX(h, idx));
 213         atomic_add_64(&dbuf_hash_count, -1);
 214 }
 215 
 216 static arc_evict_func_t dbuf_do_evict;
 217 
 218 static void
 219 dbuf_evict_user(dmu_buf_impl_t *db)
 220 {
 221         ASSERT(MUTEX_HELD(&db->db_mtx));
 222 
 223         if (db->db_level != 0 || db->db_evict_func == NULL)
 224                 return;
 225 
 226         if (db->db_user_data_ptr_ptr)
 227                 *db->db_user_data_ptr_ptr = db->db.db_data;
 228         db->db_evict_func(&db->db, db->db_user_ptr);
 229         db->db_user_ptr = NULL;
 230         db->db_user_data_ptr_ptr = NULL;
 231         db->db_evict_func = NULL;
 232 }
 233 




 158         uint64_t hv = DBUF_HASH(os, obj, level, blkid);
 159         uint64_t idx = hv & h->hash_table_mask;
 160         dmu_buf_impl_t *dbf;
 161 
 162         mutex_enter(DBUF_HASH_MUTEX(h, idx));
 163         for (dbf = h->hash_table[idx]; dbf != NULL; dbf = dbf->db_hash_next) {
 164                 if (DBUF_EQUAL(dbf, os, obj, level, blkid)) {
 165                         mutex_enter(&dbf->db_mtx);
 166                         if (dbf->db_state != DB_EVICTING) {
 167                                 mutex_exit(DBUF_HASH_MUTEX(h, idx));
 168                                 return (dbf);
 169                         }
 170                         mutex_exit(&dbf->db_mtx);
 171                 }
 172         }
 173 
 174         mutex_enter(&db->db_mtx);
 175         db->db_hash_next = h->hash_table[idx];
 176         h->hash_table[idx] = db;
 177         mutex_exit(DBUF_HASH_MUTEX(h, idx));
 178         atomic_inc_64(&dbuf_hash_count);
 179 
 180         return (NULL);
 181 }
 182 
 183 /*
 184  * Remove an entry from the hash table.  This operation will
 185  * fail if there are any existing holds on the db.
 186  */
 187 static void
 188 dbuf_hash_remove(dmu_buf_impl_t *db)
 189 {
 190         dbuf_hash_table_t *h = &dbuf_hash_table;
 191         uint64_t hv = DBUF_HASH(db->db_objset, db->db.db_object,
 192             db->db_level, db->db_blkid);
 193         uint64_t idx = hv & h->hash_table_mask;
 194         dmu_buf_impl_t *dbf, **dbp;
 195 
 196         /*
 197          * We musn't hold db_mtx to maintin lock ordering:
 198          * DBUF_HASH_MUTEX > db_mtx.
 199          */
 200         ASSERT(refcount_is_zero(&db->db_holds));
 201         ASSERT(db->db_state == DB_EVICTING);
 202         ASSERT(!MUTEX_HELD(&db->db_mtx));
 203 
 204         mutex_enter(DBUF_HASH_MUTEX(h, idx));
 205         dbp = &h->hash_table[idx];
 206         while ((dbf = *dbp) != db) {
 207                 dbp = &dbf->db_hash_next;
 208                 ASSERT(dbf != NULL);
 209         }
 210         *dbp = db->db_hash_next;
 211         db->db_hash_next = NULL;
 212         mutex_exit(DBUF_HASH_MUTEX(h, idx));
 213         atomic_dec_64(&dbuf_hash_count);
 214 }
 215 
 216 static arc_evict_func_t dbuf_do_evict;
 217 
 218 static void
 219 dbuf_evict_user(dmu_buf_impl_t *db)
 220 {
 221         ASSERT(MUTEX_HELD(&db->db_mtx));
 222 
 223         if (db->db_level != 0 || db->db_evict_func == NULL)
 224                 return;
 225 
 226         if (db->db_user_data_ptr_ptr)
 227                 *db->db_user_data_ptr_ptr = db->db.db_data;
 228         db->db_evict_func(&db->db, db->db_user_ptr);
 229         db->db_user_ptr = NULL;
 230         db->db_user_data_ptr_ptr = NULL;
 231         db->db_evict_func = NULL;
 232 }
 233