xref: /illumos-gate/usr/src/uts/common/fs/zfs/sys/abd.h (revision e86372a0)
1770499e1SDan Kimmel /*
2770499e1SDan Kimmel  * This file and its contents are supplied under the terms of the
3770499e1SDan Kimmel  * Common Development and Distribution License ("CDDL"), version 1.0.
4770499e1SDan Kimmel  * You may only use this file in accordance with the terms of version
5770499e1SDan Kimmel  * 1.0 of the CDDL.
6770499e1SDan Kimmel  *
7770499e1SDan Kimmel  * A full copy of the text of the CDDL should have accompanied this
8770499e1SDan Kimmel  * source.  A copy of the CDDL is also available via the Internet at
9770499e1SDan Kimmel  * http://www.illumos.org/license/CDDL.
10770499e1SDan Kimmel  */
11770499e1SDan Kimmel 
12770499e1SDan Kimmel /*
13770499e1SDan Kimmel  * Copyright (c) 2014 by Chunwei Chen. All rights reserved.
14770499e1SDan Kimmel  * Copyright (c) 2016 by Delphix. All rights reserved.
15770499e1SDan Kimmel  */
16770499e1SDan Kimmel 
17770499e1SDan Kimmel #ifndef _ABD_H
18770499e1SDan Kimmel #define	_ABD_H
19770499e1SDan Kimmel 
20770499e1SDan Kimmel #include <sys/isa_defs.h>
21770499e1SDan Kimmel #include <sys/int_types.h>
22770499e1SDan Kimmel #include <sys/debug.h>
23770499e1SDan Kimmel #include <sys/refcount.h>
24770499e1SDan Kimmel #ifdef _KERNEL
25770499e1SDan Kimmel #include <sys/uio.h>
26770499e1SDan Kimmel #endif
27770499e1SDan Kimmel 
28770499e1SDan Kimmel #ifdef __cplusplus
29770499e1SDan Kimmel extern "C" {
30770499e1SDan Kimmel #endif
31770499e1SDan Kimmel 
32770499e1SDan Kimmel typedef enum abd_flags {
33770499e1SDan Kimmel 	ABD_FLAG_LINEAR	= 1 << 0,	/* is buffer linear (or scattered)? */
34770499e1SDan Kimmel 	ABD_FLAG_OWNER	= 1 << 1,	/* does it own its data buffers? */
35770499e1SDan Kimmel 	ABD_FLAG_META	= 1 << 2	/* does this represent FS metadata? */
36770499e1SDan Kimmel } abd_flags_t;
37770499e1SDan Kimmel 
38770499e1SDan Kimmel typedef struct abd {
39770499e1SDan Kimmel 	abd_flags_t	abd_flags;
40770499e1SDan Kimmel 	uint_t		abd_size;	/* excludes scattered abd_offset */
41770499e1SDan Kimmel 	struct abd	*abd_parent;
42e914ace2STim Schumacher 	zfs_refcount_t	abd_children;
43770499e1SDan Kimmel 	union {
44770499e1SDan Kimmel 		struct abd_scatter {
45770499e1SDan Kimmel 			uint_t	abd_offset;
46770499e1SDan Kimmel 			uint_t	abd_chunk_size;
47770499e1SDan Kimmel 			void	*abd_chunks[];
48770499e1SDan Kimmel 		} abd_scatter;
49770499e1SDan Kimmel 		struct abd_linear {
50770499e1SDan Kimmel 			void	*abd_buf;
51770499e1SDan Kimmel 		} abd_linear;
52770499e1SDan Kimmel 	} abd_u;
53770499e1SDan Kimmel } abd_t;
54770499e1SDan Kimmel 
55770499e1SDan Kimmel typedef int abd_iter_func_t(void *, size_t, void *);
56770499e1SDan Kimmel typedef int abd_iter_func2_t(void *, void *, size_t, void *);
57770499e1SDan Kimmel 
58770499e1SDan Kimmel extern boolean_t zfs_abd_scatter_enabled;
59770499e1SDan Kimmel 
60770499e1SDan Kimmel inline boolean_t
abd_is_linear(abd_t * abd)61770499e1SDan Kimmel abd_is_linear(abd_t *abd)
62770499e1SDan Kimmel {
635e2a0747SAndriy Gapon 	return ((abd->abd_flags & ABD_FLAG_LINEAR) != 0 ? B_TRUE : B_FALSE);
64770499e1SDan Kimmel }
65770499e1SDan Kimmel 
66770499e1SDan Kimmel /*
67770499e1SDan Kimmel  * Allocations and deallocations
68770499e1SDan Kimmel  */
69770499e1SDan Kimmel 
70770499e1SDan Kimmel abd_t *abd_alloc(size_t, boolean_t);
71770499e1SDan Kimmel abd_t *abd_alloc_linear(size_t, boolean_t);
72770499e1SDan Kimmel abd_t *abd_alloc_for_io(size_t, boolean_t);
73770499e1SDan Kimmel abd_t *abd_alloc_sametype(abd_t *, size_t);
74770499e1SDan Kimmel void abd_free(abd_t *);
75770499e1SDan Kimmel abd_t *abd_get_offset(abd_t *, size_t);
76eb633035STom Caputi abd_t *abd_get_offset_size(abd_t *, size_t, size_t);
77770499e1SDan Kimmel abd_t *abd_get_from_buf(void *, size_t);
78770499e1SDan Kimmel void abd_put(abd_t *);
79770499e1SDan Kimmel 
80770499e1SDan Kimmel /*
81770499e1SDan Kimmel  * Conversion to and from a normal buffer
82770499e1SDan Kimmel  */
83770499e1SDan Kimmel 
84770499e1SDan Kimmel void *abd_to_buf(abd_t *);
85770499e1SDan Kimmel void *abd_borrow_buf(abd_t *, size_t);
86770499e1SDan Kimmel void *abd_borrow_buf_copy(abd_t *, size_t);
87770499e1SDan Kimmel void abd_return_buf(abd_t *, void *, size_t);
88770499e1SDan Kimmel void abd_return_buf_copy(abd_t *, void *, size_t);
89770499e1SDan Kimmel void abd_take_ownership_of_buf(abd_t *, boolean_t);
90770499e1SDan Kimmel void abd_release_ownership_of_buf(abd_t *);
91770499e1SDan Kimmel 
92770499e1SDan Kimmel /*
93770499e1SDan Kimmel  * ABD operations
94770499e1SDan Kimmel  */
95770499e1SDan Kimmel 
96770499e1SDan Kimmel int abd_iterate_func(abd_t *, size_t, size_t, abd_iter_func_t *, void *);
97770499e1SDan Kimmel int abd_iterate_func2(abd_t *, abd_t *, size_t, size_t, size_t,
98770499e1SDan Kimmel     abd_iter_func2_t *, void *);
99770499e1SDan Kimmel void abd_copy_off(abd_t *, abd_t *, size_t, size_t, size_t);
100770499e1SDan Kimmel void abd_copy_from_buf_off(abd_t *, const void *, size_t, size_t);
101770499e1SDan Kimmel void abd_copy_to_buf_off(void *, abd_t *, size_t, size_t);
102770499e1SDan Kimmel int abd_cmp(abd_t *, abd_t *, size_t);
103770499e1SDan Kimmel int abd_cmp_buf_off(abd_t *, const void *, size_t, size_t);
104770499e1SDan Kimmel void abd_zero_off(abd_t *, size_t, size_t);
105770499e1SDan Kimmel 
106*e86372a0SGvozden Neskovic void abd_raidz_gen_iterate(abd_t **cabds, abd_t *dabd,
107*e86372a0SGvozden Neskovic 	ssize_t csize, ssize_t dsize, const unsigned parity,
108*e86372a0SGvozden Neskovic 	void (*func_raidz_gen)(void **, const void *, size_t, size_t));
109*e86372a0SGvozden Neskovic void abd_raidz_rec_iterate(abd_t **cabds, abd_t **tabds,
110*e86372a0SGvozden Neskovic 	ssize_t tsize, const unsigned parity,
111*e86372a0SGvozden Neskovic 	void (*func_raidz_rec)(void **t, const size_t tsize, void **c,
112*e86372a0SGvozden Neskovic 	const unsigned *mul),
113*e86372a0SGvozden Neskovic 	const unsigned *mul);
114*e86372a0SGvozden Neskovic 
115770499e1SDan Kimmel /*
116770499e1SDan Kimmel  * Wrappers for calls with offsets of 0
117770499e1SDan Kimmel  */
118770499e1SDan Kimmel 
119770499e1SDan Kimmel inline void
abd_copy(abd_t * dabd,abd_t * sabd,size_t size)120770499e1SDan Kimmel abd_copy(abd_t *dabd, abd_t *sabd, size_t size)
121770499e1SDan Kimmel {
122770499e1SDan Kimmel 	abd_copy_off(dabd, sabd, 0, 0, size);
123770499e1SDan Kimmel }
124770499e1SDan Kimmel 
125770499e1SDan Kimmel inline void
abd_copy_from_buf(abd_t * abd,const void * buf,size_t size)1269b195260SAndriy Gapon abd_copy_from_buf(abd_t *abd, const void *buf, size_t size)
127770499e1SDan Kimmel {
128770499e1SDan Kimmel 	abd_copy_from_buf_off(abd, buf, 0, size);
129770499e1SDan Kimmel }
130770499e1SDan Kimmel 
131770499e1SDan Kimmel inline void
abd_copy_to_buf(void * buf,abd_t * abd,size_t size)132770499e1SDan Kimmel abd_copy_to_buf(void* buf, abd_t *abd, size_t size)
133770499e1SDan Kimmel {
134770499e1SDan Kimmel 	abd_copy_to_buf_off(buf, abd, 0, size);
135770499e1SDan Kimmel }
136770499e1SDan Kimmel 
137770499e1SDan Kimmel inline int
abd_cmp_buf(abd_t * abd,const void * buf,size_t size)1389b195260SAndriy Gapon abd_cmp_buf(abd_t *abd, const void *buf, size_t size)
139770499e1SDan Kimmel {
140770499e1SDan Kimmel 	return (abd_cmp_buf_off(abd, buf, 0, size));
141770499e1SDan Kimmel }
142770499e1SDan Kimmel 
143770499e1SDan Kimmel inline void
abd_zero(abd_t * abd,size_t size)144770499e1SDan Kimmel abd_zero(abd_t *abd, size_t size)
145770499e1SDan Kimmel {
146770499e1SDan Kimmel 	abd_zero_off(abd, 0, size);
147770499e1SDan Kimmel }
148770499e1SDan Kimmel 
149770499e1SDan Kimmel /*
150770499e1SDan Kimmel  * Module lifecycle
151770499e1SDan Kimmel  */
152770499e1SDan Kimmel 
153770499e1SDan Kimmel void abd_init(void);
154770499e1SDan Kimmel void abd_fini(void);
155770499e1SDan Kimmel 
156770499e1SDan Kimmel #ifdef __cplusplus
157770499e1SDan Kimmel }
158770499e1SDan Kimmel #endif
159770499e1SDan Kimmel 
160770499e1SDan Kimmel #endif	/* _ABD_H */
161