* Release this buffer from the cache, making it an anonymous buffer. This * must be done after a read and prior to modifying the buffer contents. * If the buffer has more than one reference, we must make * a new hdr for the buffer. */
| 6543 | * a new hdr for the buffer. |
| 6544 | */ |
| 6545 | void |
| 6546 | arc_release(arc_buf_t *buf, void *tag) |
| 6547 | { |
| 6548 | arc_buf_hdr_t *hdr = buf->b_hdr; |
| 6549 | |
| 6550 | /* |
| 6551 | * It would be nice to assert that if its DMU metadata (level > |
| 6552 | * 0 || it's the dnode file), then it must be syncing context. |
| 6553 | * But we don't know that information at this level. |
| 6554 | */ |
| 6555 | |
| 6556 | mutex_enter(&buf->b_evict_lock); |
| 6557 | |
| 6558 | ASSERT(HDR_HAS_L1HDR(hdr)); |
| 6559 | |
| 6560 | /* |
| 6561 | * We don't grab the hash lock prior to this check, because if |
| 6562 | * the buffer's header is in the arc_anon state, it won't be |
| 6563 | * linked into the hash table. |
| 6564 | */ |
| 6565 | if (hdr->b_l1hdr.b_state == arc_anon) { |
| 6566 | mutex_exit(&buf->b_evict_lock); |
| 6567 | ASSERT(!HDR_IO_IN_PROGRESS(hdr)); |
| 6568 | ASSERT(!HDR_IN_HASH_TABLE(hdr)); |
| 6569 | ASSERT(!HDR_HAS_L2HDR(hdr)); |
| 6570 | ASSERT(HDR_EMPTY(hdr)); |
| 6571 | |
| 6572 | ASSERT3U(hdr->b_l1hdr.b_bufcnt, ==, 1); |
| 6573 | ASSERT3S(zfs_refcount_count(&hdr->b_l1hdr.b_refcnt), ==, 1); |
| 6574 | ASSERT(!list_link_active(&hdr->b_l1hdr.b_arc_node)); |
| 6575 | |
| 6576 | hdr->b_l1hdr.b_arc_access = 0; |
| 6577 | |
| 6578 | /* |
| 6579 | * If the buf is being overridden then it may already |
| 6580 | * have a hdr that is not empty. |
| 6581 | */ |
| 6582 | buf_discard_identity(hdr); |
| 6583 | arc_buf_thaw(buf); |
| 6584 | |
| 6585 | return; |
| 6586 | } |
| 6587 | |
| 6588 | kmutex_t *hash_lock = HDR_LOCK(hdr); |
| 6589 | mutex_enter(hash_lock); |
| 6590 | |
| 6591 | /* |
| 6592 | * This assignment is only valid as long as the hash_lock is |
| 6593 | * held, we must be careful not to reference state or the |
| 6594 | * b_state field after dropping the lock. |
| 6595 | */ |
| 6596 | arc_state_t *state = hdr->b_l1hdr.b_state; |
| 6597 | ASSERT3P(hash_lock, ==, HDR_LOCK(hdr)); |
| 6598 | ASSERT3P(state, !=, arc_anon); |
| 6599 | |
| 6600 | /* this buffer is not on any list */ |
| 6601 | ASSERT3S(zfs_refcount_count(&hdr->b_l1hdr.b_refcnt), >, 0); |
| 6602 |
no test coverage detected