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
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
43 #include "byte-swapping.h"
46 /* eflags calculation is the same between oldstyle and newstyle
50 protocol_compute_eflags (struct connection
*conn
, uint16_t *flags
)
52 uint16_t eflags
= NBD_FLAG_HAS_FLAGS
;
55 fl
= backend
->can_write (backend
, conn
);
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
);
67 eflags
|= NBD_FLAG_SEND_WRITE_ZEROES
;
68 conn
->can_zero
= true;
71 fl
= backend
->can_trim (backend
, conn
);
75 eflags
|= NBD_FLAG_SEND_TRIM
;
76 conn
->can_trim
= true;
79 fl
= backend
->can_fua (backend
, conn
);
83 eflags
|= NBD_FLAG_SEND_FUA
;
88 fl
= backend
->can_flush (backend
, conn
);
92 eflags
|= NBD_FLAG_SEND_FLUSH
;
93 conn
->can_flush
= true;
96 fl
= backend
->is_rotational (backend
, conn
);
100 eflags
|= NBD_FLAG_ROTATIONAL
;
101 conn
->is_rotational
= true;
104 fl
= backend
->can_multi_conn (backend
, conn
);
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
);
121 conn
->can_extents
= true;
123 if (conn
->structured_replies
)
124 eflags
|= NBD_FLAG_SEND_DF
;
131 protocol_handshake (struct connection
*conn
)
137 r
= protocol_handshake_oldstyle (conn
);
139 r
= protocol_handshake_newstyle (conn
);
140 unlock_request (conn
);