/* SPDX-License-Identifier: GPL-2.0-or-later */1/*2* RDMA Network Block Driver3*4* Copyright (c) 2014 - 2018 ProfitBricks GmbH. All rights reserved.5* Copyright (c) 2018 - 2019 1&1 IONOS Cloud GmbH. All rights reserved.6* Copyright (c) 2019 - 2020 1&1 IONOS SE. All rights reserved.7*/8#ifndef RNBD_PROTO_H9#define RNBD_PROTO_H1011#include <linux/types.h>12#include <linux/blk-mq.h>13#include <linux/limits.h>14#include <linux/inet.h>15#include <linux/in.h>16#include <linux/in6.h>17#include <rdma/ib.h>1819#define RNBD_PROTO_VER_MAJOR 220#define RNBD_PROTO_VER_MINOR 02122/* The default port number the RTRS server is listening on. */23#define RTRS_PORT 12342425/**26* enum rnbd_msg_types - RNBD message types27* @RNBD_MSG_SESS_INFO: initial session info from client to server28* @RNBD_MSG_SESS_INFO_RSP: initial session info from server to client29* @RNBD_MSG_OPEN: open (map) device request30* @RNBD_MSG_OPEN_RSP: response to an @RNBD_MSG_OPEN31* @RNBD_MSG_IO: block IO request operation32* @RNBD_MSG_CLOSE: close (unmap) device request33*/34enum rnbd_msg_type {35RNBD_MSG_SESS_INFO,36RNBD_MSG_SESS_INFO_RSP,37RNBD_MSG_OPEN,38RNBD_MSG_OPEN_RSP,39RNBD_MSG_IO,40RNBD_MSG_CLOSE,41};4243/**44* struct rnbd_msg_hdr - header of RNBD messages45* @type: Message type, valid values see: enum rnbd_msg_types46*/47struct rnbd_msg_hdr {48__le16 type;49__le16 __padding;50};5152/**53* We allow to map RO many times and RW only once. We allow to map yet another54* time RW, if MIGRATION is provided (second RW export can be required for55* example for VM migration)56*/57enum rnbd_access_mode {58RNBD_ACCESS_RO,59RNBD_ACCESS_RW,60RNBD_ACCESS_MIGRATION,61};6263static const __maybe_unused struct {64enum rnbd_access_mode mode;65const char *str;66} rnbd_access_modes[] = {67[RNBD_ACCESS_RO] = {RNBD_ACCESS_RO, "ro"},68[RNBD_ACCESS_RW] = {RNBD_ACCESS_RW, "rw"},69[RNBD_ACCESS_MIGRATION] = {RNBD_ACCESS_MIGRATION, "migration"},70};7172/**73* struct rnbd_msg_sess_info - initial session info from client to server74* @hdr: message header75* @ver: RNBD protocol version76*/77struct rnbd_msg_sess_info {78struct rnbd_msg_hdr hdr;79u8 ver;80u8 reserved[31];81};8283/**84* struct rnbd_msg_sess_info_rsp - initial session info from server to client85* @hdr: message header86* @ver: RNBD protocol version87*/88struct rnbd_msg_sess_info_rsp {89struct rnbd_msg_hdr hdr;90u8 ver;91u8 reserved[31];92};9394/**95* struct rnbd_msg_open - request to open a remote device.96* @hdr: message header97* @access_mode: the mode to open remote device, valid values see:98* enum rnbd_access_mode99* @device_name: device path on remote side100*/101struct rnbd_msg_open {102struct rnbd_msg_hdr hdr;103u8 access_mode;104u8 resv1;105s8 dev_name[NAME_MAX];106u8 reserved[3];107};108109/**110* struct rnbd_msg_close - request to close a remote device.111* @hdr: message header112* @device_id: device_id on server side to identify the device113*/114struct rnbd_msg_close {115struct rnbd_msg_hdr hdr;116__le32 device_id;117};118119enum rnbd_cache_policy {120RNBD_FUA = 1 << 0,121RNBD_WRITEBACK = 1 << 1,122};123124/**125* struct rnbd_msg_open_rsp - response message to RNBD_MSG_OPEN126* @hdr: message header127* @device_id: device_id on server side to identify the device128* @nsectors: number of sectors in the usual 512b unit129* @max_hw_sectors: max hardware sectors in the usual 512b unit130* @max_write_zeroes_sectors: max sectors for WRITE ZEROES in the 512b unit131* @max_discard_sectors: max. sectors that can be discarded at once in 512b132* unit.133* @discard_granularity: size of the internal discard allocation unit in bytes134* @discard_alignment: offset from internal allocation assignment in bytes135* @physical_block_size: physical block size device supports in bytes136* @logical_block_size: logical block size device supports in bytes137* @max_segments: max segments hardware support in one transfer138* @secure_discard: supports secure discard139* @obsolete_rotational: obsolete, not in used.140* @cache_policy: support write-back caching or FUA?141*/142struct rnbd_msg_open_rsp {143struct rnbd_msg_hdr hdr;144__le32 device_id;145__le64 nsectors;146__le32 max_hw_sectors;147__le32 max_write_zeroes_sectors;148__le32 max_discard_sectors;149__le32 discard_granularity;150__le32 discard_alignment;151__le16 physical_block_size;152__le16 logical_block_size;153__le16 max_segments;154__le16 secure_discard;155u8 obsolete_rotational;156u8 cache_policy;157u8 reserved[10];158};159160/**161* struct rnbd_msg_io - message for I/O read/write162* @hdr: message header163* @device_id: device_id on server side to find the right device164* @sector: bi_sector attribute from struct bio165* @rw: valid values are defined in enum rnbd_io_flags166* @bi_size: number of bytes for I/O read/write167* @prio: priority168*/169struct rnbd_msg_io {170struct rnbd_msg_hdr hdr;171__le32 device_id;172__le64 sector;173__le32 rw;174__le32 bi_size;175__le16 prio;176};177178#define RNBD_OP_BITS 8179#define RNBD_OP_MASK ((1 << RNBD_OP_BITS) - 1)180181/**182* enum rnbd_io_flags - RNBD request types from rq_flag_bits183* @RNBD_OP_READ: read sectors from the device184* @RNBD_OP_WRITE: write sectors to the device185* @RNBD_OP_FLUSH: flush the volatile write cache186* @RNBD_OP_DISCARD: discard sectors187* @RNBD_OP_SECURE_ERASE: securely erase sectors188* @RNBD_OP_WRITE_ZEROES: write zeroes sectors189190* @RNBD_F_SYNC: request is sync (sync write or read)191* @RNBD_F_FUA: forced unit access192*/193enum rnbd_io_flags {194195/* Operations */196RNBD_OP_READ = 0,197RNBD_OP_WRITE = 1,198RNBD_OP_FLUSH = 2,199RNBD_OP_DISCARD = 3,200RNBD_OP_SECURE_ERASE = 4,201RNBD_OP_WRITE_ZEROES = 5,202203/* Flags */204RNBD_F_SYNC = 1<<(RNBD_OP_BITS + 0),205RNBD_F_FUA = 1<<(RNBD_OP_BITS + 1),206};207208static inline u32 rnbd_op(u32 flags)209{210return flags & RNBD_OP_MASK;211}212213static inline u32 rnbd_flags(u32 flags)214{215return flags & ~RNBD_OP_MASK;216}217218static inline blk_opf_t rnbd_to_bio_flags(u32 rnbd_opf)219{220blk_opf_t bio_opf;221222switch (rnbd_op(rnbd_opf)) {223case RNBD_OP_READ:224bio_opf = REQ_OP_READ;225break;226case RNBD_OP_WRITE:227bio_opf = REQ_OP_WRITE;228break;229case RNBD_OP_FLUSH:230bio_opf = REQ_OP_WRITE | REQ_PREFLUSH;231break;232case RNBD_OP_DISCARD:233bio_opf = REQ_OP_DISCARD;234break;235case RNBD_OP_SECURE_ERASE:236bio_opf = REQ_OP_SECURE_ERASE;237break;238case RNBD_OP_WRITE_ZEROES:239bio_opf = REQ_OP_WRITE_ZEROES;240break;241default:242WARN(1, "Unknown RNBD type: %d (flags %d)\n",243rnbd_op(rnbd_opf), rnbd_opf);244bio_opf = 0;245}246247if (rnbd_opf & RNBD_F_SYNC)248bio_opf |= REQ_SYNC;249250if (rnbd_opf & RNBD_F_FUA)251bio_opf |= REQ_FUA;252253return bio_opf;254}255256static inline u32 rq_to_rnbd_flags(struct request *rq)257{258u32 rnbd_opf;259260switch (req_op(rq)) {261case REQ_OP_READ:262rnbd_opf = RNBD_OP_READ;263break;264case REQ_OP_WRITE:265rnbd_opf = RNBD_OP_WRITE;266break;267case REQ_OP_DISCARD:268rnbd_opf = RNBD_OP_DISCARD;269break;270case REQ_OP_SECURE_ERASE:271rnbd_opf = RNBD_OP_SECURE_ERASE;272break;273case REQ_OP_WRITE_ZEROES:274rnbd_opf = RNBD_OP_WRITE_ZEROES;275break;276case REQ_OP_FLUSH:277rnbd_opf = RNBD_OP_FLUSH;278break;279default:280WARN(1, "Unknown request type %d (flags %llu)\n",281(__force u32)req_op(rq),282(__force unsigned long long)rq->cmd_flags);283rnbd_opf = 0;284}285286if (op_is_sync(rq->cmd_flags))287rnbd_opf |= RNBD_F_SYNC;288289if (op_is_flush(rq->cmd_flags))290rnbd_opf |= RNBD_F_FUA;291292return rnbd_opf;293}294295const char *rnbd_access_mode_str(enum rnbd_access_mode mode);296297#endif /* RNBD_PROTO_H */298299300