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 9 * or https://opensource.org/licenses/CDDL-1.0. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 2014 by Chunwei Chen. All rights reserved. 23 * Copyright (c) 2016, 2019 by Delphix. All rights reserved. 24 * Copyright (c) 2023, 2024, Klara Inc. 25 */ 26 27 #ifndef _ABD_IMPL_H 28 #define _ABD_IMPL_H 29 30 #include <sys/abd.h> 31 #include <sys/abd_impl_os.h> 32 #include <sys/wmsum.h> 33 34 #ifdef __cplusplus 35 extern "C" { 36 #endif 37 38 typedef enum abd_stats_op { 39 ABDSTAT_INCR, /* Increase abdstat values */ 40 ABDSTAT_DECR /* Decrease abdstat values */ 41 } abd_stats_op_t; 42 43 /* forward declarations */ 44 struct scatterlist; 45 struct page; 46 #if defined(__FreeBSD__) && defined(_KERNEL) 47 struct sf_buf; 48 #endif 49 50 struct abd_iter { 51 /* public interface */ 52 union { 53 /* for abd_iter_map()/abd_iter_unmap() */ 54 struct { 55 /* addr corresponding to iter_pos */ 56 void *iter_mapaddr; 57 /* length of data valid at mapaddr */ 58 size_t iter_mapsize; 59 }; 60 /* for abd_iter_page() */ 61 struct { 62 /* current page */ 63 struct page *iter_page; 64 /* offset of data in page */ 65 size_t iter_page_doff; 66 /* size of data in page */ 67 size_t iter_page_dsize; 68 }; 69 }; 70 71 /* private */ 72 abd_t *iter_abd; /* ABD being iterated through */ 73 size_t iter_pos; 74 size_t iter_offset; /* offset in current sg/abd_buf, */ 75 /* abd_offset included */ 76 #if defined(__FreeBSD__) && defined(_KERNEL) 77 struct sf_buf *sf; /* used to map in vm_page_t FreeBSD */ 78 #else 79 struct scatterlist *iter_sg; /* current sg */ 80 #endif 81 }; 82 83 extern abd_t *abd_zero_scatter; 84 85 abd_t *abd_gang_get_offset(abd_t *, size_t *); 86 abd_t *abd_alloc_struct(size_t); 87 void abd_free_struct(abd_t *); 88 void abd_init_struct(abd_t *); 89 90 /* 91 * OS specific functions 92 */ 93 94 abd_t *abd_alloc_struct_impl(size_t); 95 abd_t *abd_get_offset_scatter(abd_t *, abd_t *, size_t, size_t); 96 void abd_free_struct_impl(abd_t *); 97 void abd_alloc_chunks(abd_t *, size_t); 98 void abd_free_chunks(abd_t *); 99 void abd_update_scatter_stats(abd_t *, abd_stats_op_t); 100 void abd_update_linear_stats(abd_t *, abd_stats_op_t); 101 void abd_verify_scatter(abd_t *); 102 void abd_free_linear_page(abd_t *); 103 /* OS specific abd_iter functions */ 104 void abd_iter_init(struct abd_iter *, abd_t *); 105 boolean_t abd_iter_at_end(struct abd_iter *); 106 void abd_iter_advance(struct abd_iter *, size_t); 107 void abd_iter_map(struct abd_iter *); 108 void abd_iter_unmap(struct abd_iter *); 109 void abd_iter_page(struct abd_iter *); 110 111 /* 112 * Helper macros 113 */ 114 #define ABDSTAT_INCR(stat, val) \ 115 wmsum_add(&abd_sums.stat, (val)) 116 #define ABDSTAT_BUMP(stat) ABDSTAT_INCR(stat, 1) 117 #define ABDSTAT_BUMPDOWN(stat) ABDSTAT_INCR(stat, -1) 118 119 #define ABD_SCATTER(abd) ((abd)->abd_u.abd_scatter) 120 #define ABD_LINEAR_BUF(abd) ((abd)->abd_u.abd_linear.abd_buf) 121 #define ABD_GANG(abd) ((abd)->abd_u.abd_gang) 122 123 #ifdef __cplusplus 124 } 125 #endif 126 127 #endif /* _ABD_IMPL_H */ 128