On 6/20/19 8:03 AM, Jack Wang wrote:
+#define ibnbd_log(fn, dev, fmt, ...) ({ \ + __builtin_choose_expr( \ + __builtin_types_compatible_p( \ + typeof(dev), struct ibnbd_clt_dev *), \ + fn("<%s@%s> " fmt, (dev)->pathname, \ + (dev)->sess->sessname, \ + ##__VA_ARGS__), \ + __builtin_choose_expr( \ + __builtin_types_compatible_p(typeof(dev), \ + struct ibnbd_srv_sess_dev *), \ + fn("<%s@%s>: " fmt, (dev)->pathname, \ + (dev)->sess->sessname, ##__VA_ARGS__), \ + unknown_type())); \ +})
Please remove the __builtin_choose_expr() / __builtin_types_compatible_p() construct and split this macro into two macros or inline functions: one for struct ibnbd_clt_dev and another one for struct ibnbd_srv_sess_dev.
+#define IBNBD_PROTO_VER_MAJOR 2 +#define IBNBD_PROTO_VER_MINOR 0 + +#define IBNBD_PROTO_VER_STRING __stringify(IBNBD_PROTO_VER_MAJOR) "." \ + __stringify(IBNBD_PROTO_VER_MINOR) + +#ifndef IBNBD_VER_STRING +#define IBNBD_VER_STRING __stringify(IBNBD_PROTO_VER_MAJOR) "." \ + __stringify(IBNBD_PROTO_VER_MINOR)
Upstream code should not have a version number.
+/* TODO: should be configurable */ +#define IBTRS_PORT 1234
How about converting this macro into a kernel module parameter?
+enum ibnbd_access_mode { + IBNBD_ACCESS_RO, + IBNBD_ACCESS_RW, + IBNBD_ACCESS_MIGRATION, +};
Some more information about what IBNBD_ACCESS_MIGRATION represents would be welcome.
+#define _IBNBD_FILEIO 0 +#define _IBNBD_BLOCKIO 1 +#define _IBNBD_AUTOIO 2
>
+enum ibnbd_io_mode { + IBNBD_FILEIO = _IBNBD_FILEIO, + IBNBD_BLOCKIO = _IBNBD_BLOCKIO, + IBNBD_AUTOIO = _IBNBD_AUTOIO, +};
Since the IBNBD_* and _IBNBD_* constants have the same numerical value, are the former constants really necessary?
+/** + * struct ibnbd_msg_sess_info - initial session info from client to server + * @hdr: message header + * @ver: IBNBD protocol version + */ +struct ibnbd_msg_sess_info { + struct ibnbd_msg_hdr hdr; + u8 ver; + u8 reserved[31]; +};
Since the wire protocol is versioned, is it really necessary to add 31 reserved bytes?
+struct ibnbd_msg_sess_info_rsp { + struct ibnbd_msg_hdr hdr; + u8 ver; + u8 reserved[31]; +};
Same comment here.
+/** + * struct ibnbd_msg_open_rsp - response message to IBNBD_MSG_OPEN + * @hdr: message header + * @nsectors: number of sectors
What is the size of a single sector?
+ * @device_id: device_id on server side to identify the device
Please use the same order for the members in the kernel-doc header as in the structure.
+ * @queue_flags: queue_flags of the device on server side
Where is the queue_flags member?
+ * @discard_granularity: size of the internal discard allocation unit + * @discard_alignment: offset from internal allocation assignment + * @physical_block_size: physical block size device supports + * @logical_block_size: logical block size device supports
What is the unit for these four members?
+ * @max_segments: max segments hardware support in one transfer
Does 'hardware' refer to the RDMA adapter that transfers the IBNBD message or to the storage device? In the latter case, I assume that transfer refers to a DMA transaction?
+ * @io_mode: io_mode device is opened.
Should a reference to enum ibnbd_io_mode be added?
+ u8 __padding[10];
Why ten padding bytes? Does alignment really matter for a data structure like this one?
+/** + * struct ibnbd_msg_io_old - message for I/O read/write for + * ver < IBNBD_PROTO_VER_MAJOR + * This structure is there only to know the size of the "old" message format + * @hdr: message header + * @device_id: device_id on server side to find the right device + * @sector: bi_sector attribute from struct bio + * @rw: bitmask, valid values are defined in enum ibnbd_io_flags + * @bi_size: number of bytes for I/O read/write + * @prio: priority + */ +struct ibnbd_msg_io_old { + struct ibnbd_msg_hdr hdr; + __le32 device_id; + __le64 sector; + __le32 rw; + __le32 bi_size; +};
Since this is the first version of IBNBD that is being sent upstream, I think that ibnbd_msg_io_old should be left out.
+ +/** + * struct ibnbd_msg_io - message for I/O read/write + * @hdr: message header + * @device_id: device_id on server side to find the right device + * @sector: bi_sector attribute from struct bio + * @rw: bitmask, valid values are defined in enum ibnbd_io_flags
enum ibnbd_io_flags doesn't look like a bitmask but rather like a bit field (https://en.wikipedia.org/wiki/Bit_field)?
+static inline u32 ibnbd_to_bio_flags(u32 ibnbd_flags) +{ + u32 bio_flags;
The names ibnbd_flags and bio_flags are confusing since these two variables not only contain flags but also an operation. How about changing 'flags' into 'opf' or 'op_flags'?
+static inline const char *ibnbd_io_mode_str(enum ibnbd_io_mode mode) +{ + switch (mode) { + case IBNBD_FILEIO: + return "fileio"; + case IBNBD_BLOCKIO: + return "blockio"; + case IBNBD_AUTOIO: + return "autoio"; + default: + return "unknown"; + } +} + +static inline const char *ibnbd_access_mode_str(enum ibnbd_access_mode mode) +{ + switch (mode) { + case IBNBD_ACCESS_RO: + return "ro"; + case IBNBD_ACCESS_RW: + return "rw"; + case IBNBD_ACCESS_MIGRATION: + return "migration"; + default: + return "unknown"; + } +}
These two functions are not in the hot path and hence should not be inline functions.
Note: I plan to review the entire patch series but it may take some time before I have finished reviewing the entire patch series.
Bart.