source: mainline/uspace/lib/c/generic/bd_srv.c@ ccfe9c3

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since ccfe9c3 was ccfe9c3, checked in by Vojtech Horky <vojtechhorky@…>, 11 years ago

Add missing free() in error path (Coccinelle)

The problem was found using Coccinelle [1] with the slightly
modified version of kfree3/kmalloc.cocci [2].

[1] http://coccinelle.lip6.fr/
[2] https://github.com/coccinelle/coccinellery

  • Property mode set to 100644
File size: 6.4 KB
RevLine 
[4802dd7]1/*
2 * Copyright (c) 2012 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup libc
30 * @{
31 */
32/**
33 * @file
34 * @brief Block device server stub
35 */
36#include <errno.h>
37#include <ipc/bd.h>
38#include <macros.h>
39#include <stdlib.h>
40#include <sys/types.h>
41
42#include <bd_srv.h>
43
44static void bd_read_blocks_srv(bd_srv_t *srv, ipc_callid_t callid,
45 ipc_call_t *call)
46{
47 aoff64_t ba;
48 size_t cnt;
49 void *buf;
50 size_t size;
51 int rc;
52 ipc_callid_t rcallid;
53
54 ba = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call));
55 cnt = IPC_GET_ARG3(*call);
56
57 if (!async_data_read_receive(&rcallid, &size)) {
58 async_answer_0(callid, EINVAL);
59 return;
60 }
61
62 buf = malloc(size);
63 if (buf == NULL) {
64 async_answer_0(rcallid, ENOMEM);
65 async_answer_0(callid, ENOMEM);
66 return;
67 }
68
[135486d]69 if (srv->srvs->ops->read_blocks == NULL) {
[4802dd7]70 async_answer_0(rcallid, ENOTSUP);
71 async_answer_0(callid, ENOTSUP);
[ccfe9c3]72 free(buf);
[4802dd7]73 return;
74 }
75
[135486d]76 rc = srv->srvs->ops->read_blocks(srv, ba, cnt, buf, size);
[4802dd7]77 if (rc != EOK) {
78 async_answer_0(rcallid, ENOMEM);
79 async_answer_0(callid, ENOMEM);
[ccfe9c3]80 free(buf);
[4802dd7]81 return;
82 }
83
84 async_data_read_finalize(rcallid, buf, size);
85
86 free(buf);
87 async_answer_0(callid, EOK);
88}
89
90static void bd_read_toc_srv(bd_srv_t *srv, ipc_callid_t callid,
91 ipc_call_t *call)
92{
93 uint8_t session;
94 void *buf;
95 size_t size;
96 int rc;
97 ipc_callid_t rcallid;
98
99 session = IPC_GET_ARG1(*call);
100
101 if (!async_data_read_receive(&rcallid, &size)) {
102 async_answer_0(callid, EINVAL);
103 return;
104 }
105
106 buf = malloc(size);
107 if (buf == NULL) {
108 async_answer_0(rcallid, ENOMEM);
109 async_answer_0(callid, ENOMEM);
110 return;
111 }
112
[135486d]113 if (srv->srvs->ops->read_toc == NULL) {
[4802dd7]114 async_answer_0(rcallid, ENOTSUP);
115 async_answer_0(callid, ENOTSUP);
[ccfe9c3]116 free(buf);
[4802dd7]117 return;
118 }
119
[135486d]120 rc = srv->srvs->ops->read_toc(srv, session, buf, size);
[4802dd7]121 if (rc != EOK) {
122 async_answer_0(rcallid, ENOMEM);
123 async_answer_0(callid, ENOMEM);
[ccfe9c3]124 free(buf);
[4802dd7]125 return;
126 }
127
128 async_data_read_finalize(rcallid, buf, size);
129
130 free(buf);
131 async_answer_0(callid, EOK);
132}
133
[dd8b6a8]134static void bd_sync_cache_srv(bd_srv_t *srv, ipc_callid_t callid,
135 ipc_call_t *call)
136{
137 aoff64_t ba;
138 size_t cnt;
139 int rc;
140
141 ba = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call));
142 cnt = IPC_GET_ARG3(*call);
143
144 if (srv->srvs->ops->sync_cache == NULL) {
145 async_answer_0(callid, ENOTSUP);
146 return;
147 }
148
149 rc = srv->srvs->ops->sync_cache(srv, ba, cnt);
150 async_answer_0(callid, rc);
151}
152
[4802dd7]153static void bd_write_blocks_srv(bd_srv_t *srv, ipc_callid_t callid,
154 ipc_call_t *call)
155{
156 aoff64_t ba;
157 size_t cnt;
158 void *data;
159 size_t size;
160 int rc;
161
162 ba = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call));
163 cnt = IPC_GET_ARG3(*call);
164
165 rc = async_data_write_accept(&data, false, 0, 0, 0, &size);
166 if (rc != EOK) {
167 async_answer_0(callid, rc);
168 return;
169 }
170
[135486d]171 if (srv->srvs->ops->write_blocks == NULL) {
[4802dd7]172 async_answer_0(callid, ENOTSUP);
173 return;
174 }
175
[135486d]176 rc = srv->srvs->ops->write_blocks(srv, ba, cnt, data, size);
[4802dd7]177 free(data);
178 async_answer_0(callid, rc);
179}
180
181static void bd_get_block_size_srv(bd_srv_t *srv, ipc_callid_t callid,
182 ipc_call_t *call)
183{
184 int rc;
185 size_t block_size;
186
[135486d]187 if (srv->srvs->ops->get_block_size == NULL) {
[4802dd7]188 async_answer_0(callid, ENOTSUP);
189 return;
190 }
191
[135486d]192 rc = srv->srvs->ops->get_block_size(srv, &block_size);
[4802dd7]193 async_answer_1(callid, rc, block_size);
194}
195
196static void bd_get_num_blocks_srv(bd_srv_t *srv, ipc_callid_t callid,
197 ipc_call_t *call)
198{
199 int rc;
200 aoff64_t num_blocks;
201
[135486d]202 if (srv->srvs->ops->get_num_blocks == NULL) {
[4802dd7]203 async_answer_0(callid, ENOTSUP);
204 return;
205 }
206
[135486d]207 rc = srv->srvs->ops->get_num_blocks(srv, &num_blocks);
[4802dd7]208 async_answer_2(callid, rc, LOWER32(num_blocks), UPPER32(num_blocks));
209}
210
[135486d]211static bd_srv_t *bd_srv_create(bd_srvs_t *srvs)
[4802dd7]212{
[135486d]213 bd_srv_t *srv;
214
[75751db6]215 srv = calloc(1, sizeof(bd_srv_t));
[135486d]216 if (srv == NULL)
217 return NULL;
218
219 srv->srvs = srvs;
220 return srv;
[4802dd7]221}
222
[135486d]223void bd_srvs_init(bd_srvs_t *srvs)
[4802dd7]224{
[135486d]225 srvs->ops = NULL;
226 srvs->sarg = NULL;
227}
[4802dd7]228
[135486d]229int bd_conn(ipc_callid_t iid, ipc_call_t *icall, bd_srvs_t *srvs)
230{
231 bd_srv_t *srv;
232 int rc;
[4802dd7]233
234 /* Accept the connection */
235 async_answer_0(iid, EOK);
236
[135486d]237 srv = bd_srv_create(srvs);
238 if (srv == NULL)
239 return ENOMEM;
240
[4802dd7]241 async_sess_t *sess = async_callback_receive(EXCHANGE_SERIALIZE);
242 if (sess == NULL)
243 return ENOMEM;
244
245 srv->client_sess = sess;
246
[135486d]247 rc = srvs->ops->open(srvs, srv);
[4802dd7]248 if (rc != EOK)
249 return rc;
250
251 while (true) {
252 ipc_call_t call;
253 ipc_callid_t callid = async_get_call(&call);
254 sysarg_t method = IPC_GET_IMETHOD(call);
255
256 if (!method) {
257 /* The other side has hung up */
258 async_answer_0(callid, EOK);
259 break;
260 }
261
262 switch (method) {
263 case BD_READ_BLOCKS:
264 bd_read_blocks_srv(srv, callid, &call);
265 break;
266 case BD_READ_TOC:
267 bd_read_toc_srv(srv, callid, &call);
268 break;
[dd8b6a8]269 case BD_SYNC_CACHE:
270 bd_sync_cache_srv(srv, callid, &call);
271 break;
[4802dd7]272 case BD_WRITE_BLOCKS:
273 bd_write_blocks_srv(srv, callid, &call);
274 break;
275 case BD_GET_BLOCK_SIZE:
276 bd_get_block_size_srv(srv, callid, &call);
277 break;
278 case BD_GET_NUM_BLOCKS:
279 bd_get_num_blocks_srv(srv, callid, &call);
280 break;
281 default:
282 async_answer_0(callid, EINVAL);
283 }
284 }
285
[135486d]286 rc = srvs->ops->close(srv);
287 free(srv);
288
289 return rc;
[4802dd7]290}
291
292/** @}
293 */
Note: See TracBrowser for help on using the repository browser.