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 --- |