* Allocate a buf for this hdr. If you care about the data that's in the hdr, * or if you want a compressed buffer, pass those flags in. Returns 0 if the * copy was made successfully, or an error code otherwise. */
| 2779 | * copy was made successfully, or an error code otherwise. |
| 2780 | */ |
| 2781 | static int |
| 2782 | arc_buf_alloc_impl(arc_buf_hdr_t *hdr, spa_t *spa, const zbookmark_phys_t *zb, |
| 2783 | void *tag, boolean_t encrypted, boolean_t compressed, boolean_t noauth, |
| 2784 | boolean_t fill, arc_buf_t **ret) |
| 2785 | { |
| 2786 | arc_buf_t *buf; |
| 2787 | arc_fill_flags_t flags = ARC_FILL_LOCKED; |
| 2788 | |
| 2789 | ASSERT(HDR_HAS_L1HDR(hdr)); |
| 2790 | ASSERT3U(HDR_GET_LSIZE(hdr), >, 0); |
| 2791 | VERIFY(hdr->b_type == ARC_BUFC_DATA || |
| 2792 | hdr->b_type == ARC_BUFC_METADATA); |
| 2793 | ASSERT3P(ret, !=, NULL); |
| 2794 | ASSERT3P(*ret, ==, NULL); |
| 2795 | IMPLY(encrypted, compressed); |
| 2796 | |
| 2797 | hdr->b_l1hdr.b_mru_hits = 0; |
| 2798 | hdr->b_l1hdr.b_mru_ghost_hits = 0; |
| 2799 | hdr->b_l1hdr.b_mfu_hits = 0; |
| 2800 | hdr->b_l1hdr.b_mfu_ghost_hits = 0; |
| 2801 | hdr->b_l1hdr.b_l2_hits = 0; |
| 2802 | |
| 2803 | buf = *ret = kmem_cache_alloc(buf_cache, KM_PUSHPAGE); |
| 2804 | buf->b_hdr = hdr; |
| 2805 | buf->b_data = NULL; |
| 2806 | buf->b_next = hdr->b_l1hdr.b_buf; |
| 2807 | buf->b_flags = 0; |
| 2808 | |
| 2809 | add_reference(hdr, tag); |
| 2810 | |
| 2811 | /* |
| 2812 | * We're about to change the hdr's b_flags. We must either |
| 2813 | * hold the hash_lock or be undiscoverable. |
| 2814 | */ |
| 2815 | ASSERT(HDR_EMPTY_OR_LOCKED(hdr)); |
| 2816 | |
| 2817 | /* |
| 2818 | * Only honor requests for compressed bufs if the hdr is actually |
| 2819 | * compressed. This must be overridden if the buffer is encrypted since |
| 2820 | * encrypted buffers cannot be decompressed. |
| 2821 | */ |
| 2822 | if (encrypted) { |
| 2823 | buf->b_flags |= ARC_BUF_FLAG_COMPRESSED; |
| 2824 | buf->b_flags |= ARC_BUF_FLAG_ENCRYPTED; |
| 2825 | flags |= ARC_FILL_COMPRESSED | ARC_FILL_ENCRYPTED; |
| 2826 | } else if (compressed && |
| 2827 | arc_hdr_get_compress(hdr) != ZIO_COMPRESS_OFF) { |
| 2828 | buf->b_flags |= ARC_BUF_FLAG_COMPRESSED; |
| 2829 | flags |= ARC_FILL_COMPRESSED; |
| 2830 | } |
| 2831 | |
| 2832 | if (noauth) { |
| 2833 | ASSERT0(encrypted); |
| 2834 | flags |= ARC_FILL_NOAUTH; |
| 2835 | } |
| 2836 | |
| 2837 | /* |
| 2838 | * If the hdr's data can be shared then we share the data buffer and |
no test coverage detected