]>
Commit | Line | Data |
---|---|---|
798bfe00 FZ |
1 | /* |
2 | * Copyright (C) 2005 Anthony Liguori <[email protected]> | |
3 | * | |
4 | * Network Block Device Common Code | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License as published by | |
8 | * the Free Software Foundation; under version 2 of the License. | |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | * GNU General Public License for more details. | |
14 | * | |
15 | * You should have received a copy of the GNU General Public License | |
16 | * along with this program; if not, see <http://www.gnu.org/licenses/>. | |
17 | */ | |
18 | ||
d38ea87a | 19 | #include "qemu/osdep.h" |
da34e65c | 20 | #include "qapi/error.h" |
798bfe00 FZ |
21 | #include "nbd-internal.h" |
22 | ||
1c778ef7 DB |
23 | ssize_t nbd_wr_syncv(QIOChannel *ioc, |
24 | struct iovec *iov, | |
25 | size_t niov, | |
1c778ef7 DB |
26 | size_t length, |
27 | bool do_read) | |
798bfe00 | 28 | { |
1c778ef7 DB |
29 | ssize_t done = 0; |
30 | Error *local_err = NULL; | |
31 | struct iovec *local_iov = g_new(struct iovec, niov); | |
32 | struct iovec *local_iov_head = local_iov; | |
33 | unsigned int nlocal_iov = niov; | |
798bfe00 | 34 | |
1e2a77a8 | 35 | nlocal_iov = iov_copy(local_iov, nlocal_iov, iov, niov, 0, length); |
798bfe00 | 36 | |
1c778ef7 | 37 | while (nlocal_iov > 0) { |
798bfe00 | 38 | ssize_t len; |
798bfe00 | 39 | if (do_read) { |
1c778ef7 | 40 | len = qio_channel_readv(ioc, local_iov, nlocal_iov, &local_err); |
798bfe00 | 41 | } else { |
1c778ef7 | 42 | len = qio_channel_writev(ioc, local_iov, nlocal_iov, &local_err); |
798bfe00 | 43 | } |
1c778ef7 DB |
44 | if (len == QIO_CHANNEL_ERR_BLOCK) { |
45 | if (qemu_in_coroutine()) { | |
ff82911c | 46 | qio_channel_yield(ioc, do_read ? G_IO_IN : G_IO_OUT); |
dacca04c PB |
47 | } else { |
48 | return -EAGAIN; | |
798bfe00 | 49 | } |
1c778ef7 DB |
50 | continue; |
51 | } | |
52 | if (len < 0) { | |
53 | TRACE("I/O error: %s", error_get_pretty(local_err)); | |
54 | error_free(local_err); | |
55 | /* XXX handle Error objects */ | |
56 | done = -EIO; | |
57 | goto cleanup; | |
798bfe00 FZ |
58 | } |
59 | ||
1c778ef7 | 60 | if (do_read && len == 0) { |
798bfe00 FZ |
61 | break; |
62 | } | |
63 | ||
1c778ef7 DB |
64 | iov_discard_front(&local_iov, &nlocal_iov, len); |
65 | done += len; | |
798bfe00 FZ |
66 | } |
67 | ||
1c778ef7 DB |
68 | cleanup: |
69 | g_free(local_iov_head); | |
70 | return done; | |
798bfe00 | 71 | } |
f95910fe DB |
72 | |
73 | ||
60e705c5 | 74 | void nbd_tls_handshake(QIOTask *task, |
f95910fe DB |
75 | void *opaque) |
76 | { | |
77 | struct NBDTLSHandshakeData *data = opaque; | |
78 | ||
60e705c5 DB |
79 | if (qio_task_propagate_error(task, &data->error)) { |
80 | TRACE("TLS failed %s", error_get_pretty(data->error)); | |
f95910fe DB |
81 | } |
82 | data->complete = true; | |
83 | g_main_loop_quit(data->loop); | |
84 | } |