| 150 | } |
| 151 | |
| 152 | int64_t |
| 153 | zfs_refcount_remove_many(zfs_refcount_t *rc, uint64_t number, |
| 154 | const void *holder) |
| 155 | { |
| 156 | reference_t *ref; |
| 157 | int64_t count; |
| 158 | |
| 159 | mutex_enter(&rc->rc_mtx); |
| 160 | ASSERT3U(rc->rc_count, >=, number); |
| 161 | |
| 162 | if (!rc->rc_tracked) { |
| 163 | rc->rc_count -= number; |
| 164 | count = rc->rc_count; |
| 165 | mutex_exit(&rc->rc_mtx); |
| 166 | return (count); |
| 167 | } |
| 168 | |
| 169 | for (ref = list_head(&rc->rc_list); ref; |
| 170 | ref = list_next(&rc->rc_list, ref)) { |
| 171 | if (ref->ref_holder == holder && ref->ref_number == number) { |
| 172 | list_remove(&rc->rc_list, ref); |
| 173 | if (reference_history > 0) { |
| 174 | ref->ref_removed = |
| 175 | kmem_cache_alloc(reference_history_cache, |
| 176 | KM_SLEEP); |
| 177 | list_insert_head(&rc->rc_removed, ref); |
| 178 | rc->rc_removed_count++; |
| 179 | if (rc->rc_removed_count > reference_history) { |
| 180 | ref = list_tail(&rc->rc_removed); |
| 181 | list_remove(&rc->rc_removed, ref); |
| 182 | kmem_cache_free(reference_history_cache, |
| 183 | ref->ref_removed); |
| 184 | kmem_cache_free(reference_cache, ref); |
| 185 | rc->rc_removed_count--; |
| 186 | } |
| 187 | } else { |
| 188 | kmem_cache_free(reference_cache, ref); |
| 189 | } |
| 190 | rc->rc_count -= number; |
| 191 | count = rc->rc_count; |
| 192 | mutex_exit(&rc->rc_mtx); |
| 193 | return (count); |
| 194 | } |
| 195 | } |
| 196 | panic("No such hold %p on refcount %llx", holder, |
| 197 | (u_longlong_t)(uintptr_t)rc); |
| 198 | return (-1); |
| 199 | } |
| 200 | |
| 201 | int64_t |
| 202 | zfs_refcount_remove(zfs_refcount_t *rc, const void *holder) |
no test coverage detected