Version 1.13.0.
[nbdkit/ericb.git] / server / protocol-handshake.c
blob03377a91d412ee16237fa492297bbbd6697707f1
1 /* nbdkit
2 * Copyright (C) 2013-2019 Red Hat Inc.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
8 * * Redistributions of source code must retain the above copyright
9 * 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.
15 * * Neither the name of Red Hat nor the names of its contributors may be
16 * used to endorse or promote products derived from this software without
17 * specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
29 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
33 #include <config.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <stdint.h>
38 #include <inttypes.h>
39 #include <string.h>
40 #include <unistd.h>
42 #include "internal.h"
43 #include "byte-swapping.h"
44 #include "protocol.h"
46 /* eflags calculation is the same between oldstyle and newstyle
47 * protocols.
49 int
50 protocol_compute_eflags (struct connection *conn, uint16_t *flags)
52 uint16_t eflags = NBD_FLAG_HAS_FLAGS;
53 int fl;
55 fl = backend->can_write (backend, conn);
56 if (fl == -1)
57 return -1;
58 if (readonly || !fl) {
59 eflags |= NBD_FLAG_READ_ONLY;
60 conn->readonly = true;
62 if (!conn->readonly) {
63 fl = backend->can_zero (backend, conn);
64 if (fl == -1)
65 return -1;
66 if (fl) {
67 eflags |= NBD_FLAG_SEND_WRITE_ZEROES;
68 conn->can_zero = true;
71 fl = backend->can_trim (backend, conn);
72 if (fl == -1)
73 return -1;
74 if (fl) {
75 eflags |= NBD_FLAG_SEND_TRIM;
76 conn->can_trim = true;
79 fl = backend->can_fua (backend, conn);
80 if (fl == -1)
81 return -1;
82 if (fl) {
83 eflags |= NBD_FLAG_SEND_FUA;
84 conn->can_fua = true;
88 fl = backend->can_flush (backend, conn);
89 if (fl == -1)
90 return -1;
91 if (fl) {
92 eflags |= NBD_FLAG_SEND_FLUSH;
93 conn->can_flush = true;
96 fl = backend->is_rotational (backend, conn);
97 if (fl == -1)
98 return -1;
99 if (fl) {
100 eflags |= NBD_FLAG_ROTATIONAL;
101 conn->is_rotational = true;
104 fl = backend->can_multi_conn (backend, conn);
105 if (fl == -1)
106 return -1;
107 if (fl) {
108 eflags |= NBD_FLAG_CAN_MULTI_CONN;
109 conn->can_multi_conn = true;
112 /* The result of this is not returned to callers here (or at any
113 * time during the handshake). However it makes sense to do it once
114 * per connection and store the result in the handle anyway. This
115 * protocol_compute_eflags function is a bit misnamed XXX.
117 fl = backend->can_extents (backend, conn);
118 if (fl == -1)
119 return -1;
120 if (fl)
121 conn->can_extents = true;
123 if (conn->structured_replies)
124 eflags |= NBD_FLAG_SEND_DF;
126 *flags = eflags;
127 return 0;
131 protocol_handshake (struct connection *conn)
133 int r;
135 lock_request (conn);
136 if (!newstyle)
137 r = protocol_handshake_oldstyle (conn);
138 else
139 r = protocol_handshake_newstyle (conn);
140 unlock_request (conn);
142 return r;