]>
git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/include/spdk_internal/sock.h
4 * Copyright (c) Intel Corporation. All rights reserved.
5 * Copyright (c) 2020 Mellanox Technologies LTD. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 * TCP network implementation abstraction layer
38 #ifndef SPDK_INTERNAL_SOCK_H
39 #define SPDK_INTERNAL_SOCK_H
41 #include "spdk/stdinc.h"
42 #include "spdk/sock.h"
43 #include "spdk/queue.h"
49 #define MAX_EVENTS_PER_POLL 32
50 #define DEFAULT_SOCK_PRIORITY 0
51 #define MIN_SOCK_PIPE_SIZE 1024
54 struct spdk_net_impl
*net_impl
;
55 struct spdk_sock_opts opts
;
59 struct spdk_sock_group_impl
*group_impl
;
60 TAILQ_ENTRY(spdk_sock
) link
;
63 TAILQ_HEAD(, spdk_sock_request
) queued_reqs
;
64 TAILQ_HEAD(, spdk_sock_request
) pending_reqs
;
73 struct spdk_sock_group
{
74 STAILQ_HEAD(, spdk_sock_group_impl
) group_impls
;
78 struct spdk_sock_group_impl
{
79 struct spdk_net_impl
*net_impl
;
80 TAILQ_HEAD(, spdk_sock
) socks
;
81 STAILQ_ENTRY(spdk_sock_group_impl
) link
;
82 /* List of removed sockets. refreshed each time we poll the sock group. */
83 int num_removed_socks
;
84 /* Unfortunately, we can't just keep a tailq of the sockets in case they are freed
85 * or added to another poll group later.
87 uintptr_t removed_socks
[MAX_EVENTS_PER_POLL
];
90 struct spdk_net_impl
{
94 int (*getaddr
)(struct spdk_sock
*sock
, char *saddr
, int slen
, uint16_t *sport
, char *caddr
,
95 int clen
, uint16_t *cport
);
96 struct spdk_sock
*(*connect
)(const char *ip
, int port
, struct spdk_sock_opts
*opts
);
97 struct spdk_sock
*(*listen
)(const char *ip
, int port
, struct spdk_sock_opts
*opts
);
98 struct spdk_sock
*(*accept
)(struct spdk_sock
*sock
);
99 int (*close
)(struct spdk_sock
*sock
);
100 ssize_t (*recv
)(struct spdk_sock
*sock
, void *buf
, size_t len
);
101 ssize_t (*readv
)(struct spdk_sock
*sock
, struct iovec
*iov
, int iovcnt
);
102 ssize_t (*writev
)(struct spdk_sock
*sock
, struct iovec
*iov
, int iovcnt
);
104 void (*writev_async
)(struct spdk_sock
*sock
, struct spdk_sock_request
*req
);
105 int (*flush
)(struct spdk_sock
*sock
);
107 int (*set_recvlowat
)(struct spdk_sock
*sock
, int nbytes
);
108 int (*set_recvbuf
)(struct spdk_sock
*sock
, int sz
);
109 int (*set_sendbuf
)(struct spdk_sock
*sock
, int sz
);
111 bool (*is_ipv6
)(struct spdk_sock
*sock
);
112 bool (*is_ipv4
)(struct spdk_sock
*sock
);
113 bool (*is_connected
)(struct spdk_sock
*sock
);
115 int (*get_placement_id
)(struct spdk_sock
*sock
, int *placement_id
);
116 struct spdk_sock_group_impl
*(*group_impl_create
)(void);
117 int (*group_impl_add_sock
)(struct spdk_sock_group_impl
*group
, struct spdk_sock
*sock
);
118 int (*group_impl_remove_sock
)(struct spdk_sock_group_impl
*group
, struct spdk_sock
*sock
);
119 int (*group_impl_poll
)(struct spdk_sock_group_impl
*group
, int max_events
,
120 struct spdk_sock
**socks
);
121 int (*group_impl_close
)(struct spdk_sock_group_impl
*group
);
123 int (*get_opts
)(struct spdk_sock_impl_opts
*opts
, size_t *len
);
124 int (*set_opts
)(const struct spdk_sock_impl_opts
*opts
, size_t len
);
126 STAILQ_ENTRY(spdk_net_impl
) link
;
129 void spdk_net_impl_register(struct spdk_net_impl
*impl
, int priority
);
131 #define SPDK_NET_IMPL_REGISTER(name, impl, priority) \
132 static void __attribute__((constructor)) net_impl_register_##name(void) \
134 spdk_net_impl_register(impl, priority); \
138 spdk_sock_request_queue(struct spdk_sock
*sock
, struct spdk_sock_request
*req
)
140 TAILQ_INSERT_TAIL(&sock
->queued_reqs
, req
, internal
.link
);
141 sock
->queued_iovcnt
+= req
->iovcnt
;
145 spdk_sock_request_pend(struct spdk_sock
*sock
, struct spdk_sock_request
*req
)
147 TAILQ_REMOVE(&sock
->queued_reqs
, req
, internal
.link
);
148 assert(sock
->queued_iovcnt
>= req
->iovcnt
);
149 sock
->queued_iovcnt
-= req
->iovcnt
;
150 TAILQ_INSERT_TAIL(&sock
->pending_reqs
, req
, internal
.link
);
154 spdk_sock_request_put(struct spdk_sock
*sock
, struct spdk_sock_request
*req
, int err
)
159 TAILQ_REMOVE(&sock
->pending_reqs
, req
, internal
.link
);
161 req
->internal
.offset
= 0;
163 closed
= sock
->flags
.closed
;
165 req
->cb_fn(req
->cb_arg
, err
);
166 assert(sock
->cb_cnt
> 0);
169 if (sock
->cb_cnt
== 0 && !closed
&& sock
->flags
.closed
) {
170 /* The user closed the socket in response to a callback above. */
172 spdk_sock_close(&sock
);
179 spdk_sock_abort_requests(struct spdk_sock
*sock
)
181 struct spdk_sock_request
*req
;
185 closed
= sock
->flags
.closed
;
188 req
= TAILQ_FIRST(&sock
->pending_reqs
);
190 TAILQ_REMOVE(&sock
->pending_reqs
, req
, internal
.link
);
192 req
->cb_fn(req
->cb_arg
, -ECANCELED
);
194 req
= TAILQ_FIRST(&sock
->pending_reqs
);
197 req
= TAILQ_FIRST(&sock
->queued_reqs
);
199 TAILQ_REMOVE(&sock
->queued_reqs
, req
, internal
.link
);
201 assert(sock
->queued_iovcnt
>= req
->iovcnt
);
202 sock
->queued_iovcnt
-= req
->iovcnt
;
204 req
->cb_fn(req
->cb_arg
, -ECANCELED
);
206 req
= TAILQ_FIRST(&sock
->queued_reqs
);
208 assert(sock
->cb_cnt
> 0);
211 assert(TAILQ_EMPTY(&sock
->queued_reqs
));
212 assert(TAILQ_EMPTY(&sock
->pending_reqs
));
214 if (sock
->cb_cnt
== 0 && !closed
&& sock
->flags
.closed
) {
215 /* The user closed the socket in response to a callback above. */
217 spdk_sock_close(&sock
);
227 #endif /* SPDK_INTERNAL_SOCK_H */