| .. | .. |
|---|
| 57 | 57 | P_PROTOCOL_UPDATE = 0x2d, /* data sock: is used in established connections */ |
|---|
| 58 | 58 | /* 0x2e to 0x30 reserved, used in drbd 9 */ |
|---|
| 59 | 59 | |
|---|
| 60 | | - /* REQ_DISCARD. We used "discard" in different contexts before, |
|---|
| 60 | + /* REQ_OP_DISCARD. We used "discard" in different contexts before, |
|---|
| 61 | 61 | * which is why I chose TRIM here, to disambiguate. */ |
|---|
| 62 | 62 | P_TRIM = 0x31, |
|---|
| 63 | 63 | |
|---|
| .. | .. |
|---|
| 69 | 69 | * On a receiving side without REQ_WRITE_SAME, |
|---|
| 70 | 70 | * we may fall back to an opencoded loop instead. */ |
|---|
| 71 | 71 | P_WSAME = 0x34, |
|---|
| 72 | + |
|---|
| 73 | + /* 0x35 already claimed in DRBD 9 */ |
|---|
| 74 | + P_ZEROES = 0x36, /* data sock: zero-out, WRITE_ZEROES */ |
|---|
| 75 | + |
|---|
| 76 | + /* 0x40 .. 0x48 already claimed in DRBD 9 */ |
|---|
| 72 | 77 | |
|---|
| 73 | 78 | P_MAY_IGNORE = 0x100, /* Flag to test if (cmd > P_MAY_IGNORE) ... */ |
|---|
| 74 | 79 | P_MAX_OPT_CMD = 0x101, |
|---|
| .. | .. |
|---|
| 126 | 131 | #define DP_UNPLUG 8 /* not used anymore */ |
|---|
| 127 | 132 | #define DP_FUA 16 /* equals REQ_FUA */ |
|---|
| 128 | 133 | #define DP_FLUSH 32 /* equals REQ_PREFLUSH */ |
|---|
| 129 | | -#define DP_DISCARD 64 /* equals REQ_DISCARD */ |
|---|
| 134 | +#define DP_DISCARD 64 /* equals REQ_OP_DISCARD */ |
|---|
| 130 | 135 | #define DP_SEND_RECEIVE_ACK 128 /* This is a proto B write request */ |
|---|
| 131 | 136 | #define DP_SEND_WRITE_ACK 256 /* This is a proto C write request */ |
|---|
| 132 | 137 | #define DP_WSAME 512 /* equiv. REQ_WRITE_SAME */ |
|---|
| 138 | +#define DP_ZEROES 1024 /* equiv. REQ_OP_WRITE_ZEROES */ |
|---|
| 139 | + |
|---|
| 140 | +/* possible combinations: |
|---|
| 141 | + * REQ_OP_WRITE_ZEROES: DP_DISCARD | DP_ZEROES |
|---|
| 142 | + * REQ_OP_WRITE_ZEROES + REQ_NOUNMAP: DP_ZEROES |
|---|
| 143 | + */ |
|---|
| 133 | 144 | |
|---|
| 134 | 145 | struct p_data { |
|---|
| 135 | 146 | u64 sector; /* 64 bits sector number */ |
|---|
| .. | .. |
|---|
| 197 | 208 | */ |
|---|
| 198 | 209 | #define DRBD_FF_WSAME 4 |
|---|
| 199 | 210 | |
|---|
| 211 | +/* supports REQ_OP_WRITE_ZEROES on the "wire" protocol. |
|---|
| 212 | + * |
|---|
| 213 | + * We used to map that to "discard" on the sending side, and if we cannot |
|---|
| 214 | + * guarantee that discard zeroes data, the receiving side would map discard |
|---|
| 215 | + * back to zero-out. |
|---|
| 216 | + * |
|---|
| 217 | + * With the introduction of REQ_OP_WRITE_ZEROES, |
|---|
| 218 | + * we started to use that for both WRITE_ZEROES and DISCARDS, |
|---|
| 219 | + * hoping that WRITE_ZEROES would "do what we want", |
|---|
| 220 | + * UNMAP if possible, zero-out the rest. |
|---|
| 221 | + * |
|---|
| 222 | + * The example scenario is some LVM "thin" backend. |
|---|
| 223 | + * |
|---|
| 224 | + * While an un-allocated block on dm-thin reads as zeroes, on a dm-thin |
|---|
| 225 | + * with "skip_block_zeroing=true", after a partial block write allocated |
|---|
| 226 | + * that block, that same block may well map "undefined old garbage" from |
|---|
| 227 | + * the backends on LBAs that have not yet been written to. |
|---|
| 228 | + * |
|---|
| 229 | + * If we cannot distinguish between zero-out and discard on the receiving |
|---|
| 230 | + * side, to avoid "undefined old garbage" to pop up randomly at later times |
|---|
| 231 | + * on supposedly zero-initialized blocks, we'd need to map all discards to |
|---|
| 232 | + * zero-out on the receiving side. But that would potentially do a full |
|---|
| 233 | + * alloc on thinly provisioned backends, even when the expectation was to |
|---|
| 234 | + * unmap/trim/discard/de-allocate. |
|---|
| 235 | + * |
|---|
| 236 | + * We need to distinguish on the protocol level, whether we need to guarantee |
|---|
| 237 | + * zeroes (and thus use zero-out, potentially doing the mentioned full-alloc), |
|---|
| 238 | + * or if we want to put the emphasis on discard, and only do a "best effort |
|---|
| 239 | + * zeroing" (by "discarding" blocks aligned to discard-granularity, and zeroing |
|---|
| 240 | + * only potential unaligned head and tail clippings), to at least *try* to |
|---|
| 241 | + * avoid "false positives" in an online-verify later, hoping that someone |
|---|
| 242 | + * set skip_block_zeroing=false. |
|---|
| 243 | + */ |
|---|
| 244 | +#define DRBD_FF_WZEROES 8 |
|---|
| 245 | + |
|---|
| 246 | + |
|---|
| 200 | 247 | struct p_connection_features { |
|---|
| 201 | 248 | u32 protocol_min; |
|---|
| 202 | 249 | u32 feature_flags; |
|---|
| .. | .. |
|---|
| 224 | 271 | u32 resync_rate; |
|---|
| 225 | 272 | |
|---|
| 226 | 273 | /* Since protocol version 88 and higher. */ |
|---|
| 227 | | - char verify_alg[0]; |
|---|
| 274 | + char verify_alg[]; |
|---|
| 228 | 275 | } __packed; |
|---|
| 229 | 276 | |
|---|
| 230 | 277 | struct p_rs_param_89 { |
|---|
| .. | .. |
|---|
| 258 | 305 | u32 two_primaries; |
|---|
| 259 | 306 | |
|---|
| 260 | 307 | /* Since protocol version 87 and higher. */ |
|---|
| 261 | | - char integrity_alg[0]; |
|---|
| 308 | + char integrity_alg[]; |
|---|
| 262 | 309 | |
|---|
| 263 | 310 | } __packed; |
|---|
| 264 | 311 | |
|---|
| .. | .. |
|---|
| 313 | 360 | u16 dds_flags; /* use enum dds_flags here. */ |
|---|
| 314 | 361 | |
|---|
| 315 | 362 | /* optional queue_limits if (agreed_features & DRBD_FF_WSAME) */ |
|---|
| 316 | | - struct o_qlim qlim[0]; |
|---|
| 363 | + struct o_qlim qlim[]; |
|---|
| 317 | 364 | } __packed; |
|---|
| 318 | 365 | |
|---|
| 319 | 366 | struct p_state { |
|---|
| .. | .. |
|---|
| 362 | 409 | */ |
|---|
| 363 | 410 | u8 encoding; |
|---|
| 364 | 411 | |
|---|
| 365 | | - u8 code[0]; |
|---|
| 412 | + u8 code[]; |
|---|
| 366 | 413 | } __packed; |
|---|
| 367 | 414 | |
|---|
| 368 | 415 | struct p_delay_probe93 { |
|---|