xref: /spdk/include/spdk_internal/sgl.h (revision a6dbe3721eb3b5990707fc3e378c95e505dd8ab5)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2021 Intel Corporation.
3  *   All rights reserved.
4  */
5 
6 #ifndef __SGL_INTERNAL_H__
7 #define __SGL_INTERNAL_H__
8 
9 #include "spdk/stdinc.h"
10 
11 #ifdef __cplusplus
12 extern "C" {
13 #endif
14 
15 struct spdk_iov_sgl {
16 	struct iovec    *iov;
17 	int             iovcnt;
18 	uint32_t        iov_offset;
19 	uint32_t        total_size;
20 };
21 
22 /**
23  * Initialize struct spdk_iov_sgl with iov, iovcnt and iov_offset.
24  *
25  * \param s the spdk_iov_sgl to be filled.
26  * \param iov the io vector to fill the s
27  * \param iovcnt the size the iov
28  * \param iov_offset the current filled iov_offset for s.
29  */
30 
31 static inline void
spdk_iov_sgl_init(struct spdk_iov_sgl * s,struct iovec * iov,int iovcnt,uint32_t iov_offset)32 spdk_iov_sgl_init(struct spdk_iov_sgl *s, struct iovec *iov, int iovcnt,
33 		  uint32_t iov_offset)
34 {
35 	s->iov = iov;
36 	s->iovcnt = iovcnt;
37 	s->iov_offset = iov_offset;
38 	s->total_size = 0;
39 }
40 
41 /**
42  * Consume the iovs in spdk_iov_sgl with passed bytes
43  *
44  * \param s the spdk_iov_sgl which contains the iov
45  * \param step the bytes_size consumed.
46  */
47 
48 static inline void
spdk_iov_sgl_advance(struct spdk_iov_sgl * s,uint32_t step)49 spdk_iov_sgl_advance(struct spdk_iov_sgl *s, uint32_t step)
50 {
51 	s->iov_offset += step;
52 	while (s->iovcnt > 0) {
53 		assert(s->iov != NULL);
54 		if (s->iov_offset < s->iov->iov_len) {
55 			break;
56 		}
57 
58 		s->iov_offset -= s->iov->iov_len;
59 		s->iov++;
60 		s->iovcnt--;
61 	}
62 }
63 
64 /**
65  * Append the data to the struct spdk_iov_sgl pointed by s
66  *
67  * \param s the address of the struct spdk_iov_sgl
68  * \param data the data buffer to be appended
69  * \param data_len the length of the data.
70  *
71  * \return true if all the data is appended.
72  */
73 
74 static inline bool
spdk_iov_sgl_append(struct spdk_iov_sgl * s,uint8_t * data,uint32_t data_len)75 spdk_iov_sgl_append(struct spdk_iov_sgl *s, uint8_t *data, uint32_t data_len)
76 {
77 	if (s->iov_offset >= data_len) {
78 		s->iov_offset -= data_len;
79 	} else {
80 		assert(s->iovcnt > 0);
81 		s->iov->iov_base = data + s->iov_offset;
82 		s->iov->iov_len = data_len - s->iov_offset;
83 		s->total_size += data_len - s->iov_offset;
84 		s->iov_offset = 0;
85 		s->iov++;
86 		s->iovcnt--;
87 		if (s->iovcnt == 0) {
88 			return false;
89 		}
90 	}
91 
92 	return true;
93 }
94 
95 #ifdef __cplusplus
96 }
97 #endif
98 
99 #endif /* __SGL_INTERNAL_H__ */
100