/* 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 22122/* The default port number the RTRS server is listening on. */23#define RTRS_PORT 12342425/**26* enum rnbd_msg_type - 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/* private: */50__le16 __padding;51};5253/*54* We allow to map RO many times and RW only once. We allow to map yet another55* time RW, if MIGRATION is provided (second RW export can be required for56* example for VM migration)57*/58enum rnbd_access_mode {59RNBD_ACCESS_RO,60RNBD_ACCESS_RW,61RNBD_ACCESS_MIGRATION,62};6364static const __maybe_unused struct {65enum rnbd_access_mode mode;66const char *str;67} rnbd_access_modes[] = {68[RNBD_ACCESS_RO] = {RNBD_ACCESS_RO, "ro"},69[RNBD_ACCESS_RW] = {RNBD_ACCESS_RW, "rw"},70[RNBD_ACCESS_MIGRATION] = {RNBD_ACCESS_MIGRATION, "migration"},71};7273/**74* struct rnbd_msg_sess_info - initial session info from client to server75* @hdr: message header76* @ver: RNBD protocol version77*/78struct rnbd_msg_sess_info {79struct rnbd_msg_hdr hdr;80u8 ver;81/* private: */82u8 reserved[31];83};8485/**86* struct rnbd_msg_sess_info_rsp - initial session info from server to client87* @hdr: message header88* @ver: RNBD protocol version89*/90struct rnbd_msg_sess_info_rsp {91struct rnbd_msg_hdr hdr;92u8 ver;93/* private: */94u8 reserved[31];95};9697/**98* struct rnbd_msg_open - request to open a remote device.99* @hdr: message header100* @access_mode: the mode to open remote device, valid values see:101* enum rnbd_access_mode102* @dev_name: device path on remote side103*/104struct rnbd_msg_open {105struct rnbd_msg_hdr hdr;106u8 access_mode;107/* private: */108u8 resv1;109/* public: */110s8 dev_name[NAME_MAX];111/* private: */112u8 reserved[3];113};114115/**116* struct rnbd_msg_close - request to close a remote device.117* @hdr: message header118* @device_id: device_id on server side to identify the device119*/120struct rnbd_msg_close {121struct rnbd_msg_hdr hdr;122__le32 device_id;123};124125enum rnbd_cache_policy {126RNBD_FUA = 1 << 0,127RNBD_WRITEBACK = 1 << 1,128};129130/**131* struct rnbd_msg_open_rsp - response message to RNBD_MSG_OPEN132* @hdr: message header133* @device_id: device_id on server side to identify the device134* @nsectors: number of sectors in the usual 512b unit135* @max_hw_sectors: max hardware sectors in the usual 512b unit136* @max_write_zeroes_sectors: max sectors for WRITE ZEROES in the 512b unit137* @max_discard_sectors: max. sectors that can be discarded at once in 512b138* unit.139* @discard_granularity: size of the internal discard allocation unit in bytes140* @discard_alignment: offset from internal allocation assignment in bytes141* @physical_block_size: physical block size device supports in bytes142* @logical_block_size: logical block size device supports in bytes143* @max_segments: max segments hardware support in one transfer144* @secure_discard: supports secure discard145* @obsolete_rotational: obsolete, not in used.146* @cache_policy: support write-back caching or FUA?147*/148struct rnbd_msg_open_rsp {149struct rnbd_msg_hdr hdr;150__le32 device_id;151__le64 nsectors;152__le32 max_hw_sectors;153__le32 max_write_zeroes_sectors;154__le32 max_discard_sectors;155__le32 discard_granularity;156__le32 discard_alignment;157__le16 physical_block_size;158__le16 logical_block_size;159__le16 max_segments;160__le16 secure_discard;161u8 obsolete_rotational;162u8 cache_policy;163/* private: */164u8 reserved[10];165};166167/**168* struct rnbd_msg_io - message for I/O read/write169* @hdr: message header170* @device_id: device_id on server side to find the right device171* @sector: bi_sector attribute from struct bio172* @rw: valid values are defined in enum rnbd_io_flags173* @bi_size: number of bytes for I/O read/write174* @prio: priority175*/176struct rnbd_msg_io {177struct rnbd_msg_hdr hdr;178__le32 device_id;179__le64 sector;180__le32 rw;181__le32 bi_size;182__le16 prio;183};184185#define RNBD_OP_BITS 8186#define RNBD_OP_MASK ((1 << RNBD_OP_BITS) - 1)187188/**189* enum rnbd_io_flags - RNBD request types from rq_flag_bits190* @RNBD_OP_READ: read sectors from the device191* @RNBD_OP_WRITE: write sectors to the device192* @RNBD_OP_FLUSH: flush the volatile write cache193* @RNBD_OP_DISCARD: discard sectors194* @RNBD_OP_SECURE_ERASE: securely erase sectors195* @RNBD_OP_WRITE_ZEROES: write zeroes sectors196*197* @RNBD_F_SYNC: request is sync (sync write or read)198* @RNBD_F_FUA: forced unit access199* @RNBD_F_PREFLUSH: request for cache flush200* @RNBD_F_NOUNMAP: do not free blocks when zeroing201*/202enum rnbd_io_flags {203204/* Operations */205RNBD_OP_READ = 0,206RNBD_OP_WRITE = 1,207RNBD_OP_FLUSH = 2,208RNBD_OP_DISCARD = 3,209RNBD_OP_SECURE_ERASE = 4,210RNBD_OP_WRITE_ZEROES = 5,211212/* Flags */213RNBD_F_SYNC = 1<<(RNBD_OP_BITS + 0),214RNBD_F_FUA = 1<<(RNBD_OP_BITS + 1),215RNBD_F_PREFLUSH = 1<<(RNBD_OP_BITS + 2),216RNBD_F_NOUNMAP = 1<<(RNBD_OP_BITS + 3)217};218219static inline u32 rnbd_op(u32 flags)220{221return flags & RNBD_OP_MASK;222}223224static inline u32 rnbd_flags(u32 flags)225{226return flags & ~RNBD_OP_MASK;227}228229static inline blk_opf_t rnbd_to_bio_flags(u32 rnbd_opf)230{231blk_opf_t bio_opf;232233switch (rnbd_op(rnbd_opf)) {234case RNBD_OP_READ:235bio_opf = REQ_OP_READ;236break;237case RNBD_OP_WRITE:238bio_opf = REQ_OP_WRITE;239break;240case RNBD_OP_FLUSH:241bio_opf = REQ_OP_WRITE | REQ_PREFLUSH;242break;243case RNBD_OP_DISCARD:244bio_opf = REQ_OP_DISCARD;245break;246case RNBD_OP_SECURE_ERASE:247bio_opf = REQ_OP_SECURE_ERASE;248break;249case RNBD_OP_WRITE_ZEROES:250bio_opf = REQ_OP_WRITE_ZEROES;251252if (rnbd_opf & RNBD_F_NOUNMAP)253bio_opf |= REQ_NOUNMAP;254break;255default:256WARN(1, "Unknown RNBD type: %d (flags %d)\n",257rnbd_op(rnbd_opf), rnbd_opf);258bio_opf = 0;259}260261if (rnbd_opf & RNBD_F_SYNC)262bio_opf |= REQ_SYNC;263264if (rnbd_opf & RNBD_F_FUA)265bio_opf |= REQ_FUA;266267if (rnbd_opf & RNBD_F_PREFLUSH)268bio_opf |= REQ_PREFLUSH;269270return bio_opf;271}272273static inline u32 rq_to_rnbd_flags(struct request *rq)274{275u32 rnbd_opf;276277switch (req_op(rq)) {278case REQ_OP_READ:279rnbd_opf = RNBD_OP_READ;280break;281case REQ_OP_WRITE:282rnbd_opf = RNBD_OP_WRITE;283break;284case REQ_OP_DISCARD:285rnbd_opf = RNBD_OP_DISCARD;286break;287case REQ_OP_SECURE_ERASE:288rnbd_opf = RNBD_OP_SECURE_ERASE;289break;290case REQ_OP_WRITE_ZEROES:291rnbd_opf = RNBD_OP_WRITE_ZEROES;292293if (rq->cmd_flags & REQ_NOUNMAP)294rnbd_opf |= RNBD_F_NOUNMAP;295break;296case REQ_OP_FLUSH:297rnbd_opf = RNBD_OP_FLUSH;298break;299default:300WARN(1, "Unknown request type %d (flags %llu)\n",301(__force u32)req_op(rq),302(__force unsigned long long)rq->cmd_flags);303rnbd_opf = 0;304}305306if (op_is_sync(rq->cmd_flags))307rnbd_opf |= RNBD_F_SYNC;308309if (op_is_flush(rq->cmd_flags))310rnbd_opf |= RNBD_F_FUA;311312if (rq->cmd_flags & REQ_PREFLUSH)313rnbd_opf |= RNBD_F_PREFLUSH;314315return rnbd_opf;316}317318const char *rnbd_access_mode_str(enum rnbd_access_mode mode);319320#endif /* RNBD_PROTO_H */321322323