Skip to content

Commit 43043c9

Browse files
damien-lemoalkeithbusch
authored andcommitted
nvmet: Introduce nvmet_req_transfer_len()
Add the new function nvmet_req_transfer_len() to parse a request command to extract the transfer length of the command. This function implementation relies on multiple helper functions for parsing I/O commands (nvmet_io_cmd_transfer_len()), admin commands (nvmet_admin_cmd_data_len()) and fabrics connect commands (nvmet_connect_cmd_data_len). Signed-off-by: Damien Le Moal <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Tested-by: Rick Wertenbroek <[email protected]> Tested-by: Manivannan Sadhasivam <[email protected]> Signed-off-by: Keith Busch <[email protected]>
1 parent 6202783 commit 43043c9

File tree

6 files changed

+135
-2
lines changed

6 files changed

+135
-2
lines changed

drivers/nvme/target/admin-cmd.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1296,6 +1296,27 @@ void nvmet_execute_keep_alive(struct nvmet_req *req)
12961296
nvmet_req_complete(req, status);
12971297
}
12981298

1299+
u32 nvmet_admin_cmd_data_len(struct nvmet_req *req)
1300+
{
1301+
struct nvme_command *cmd = req->cmd;
1302+
1303+
if (nvme_is_fabrics(cmd))
1304+
return nvmet_fabrics_admin_cmd_data_len(req);
1305+
if (nvmet_is_disc_subsys(nvmet_req_subsys(req)))
1306+
return nvmet_discovery_cmd_data_len(req);
1307+
1308+
switch (cmd->common.opcode) {
1309+
case nvme_admin_get_log_page:
1310+
return nvmet_get_log_page_len(cmd);
1311+
case nvme_admin_identify:
1312+
return NVME_IDENTIFY_DATA_SIZE;
1313+
case nvme_admin_get_features:
1314+
return nvmet_feat_data_len(req, le32_to_cpu(cmd->common.cdw10));
1315+
default:
1316+
return 0;
1317+
}
1318+
}
1319+
12991320
u16 nvmet_parse_admin_cmd(struct nvmet_req *req)
13001321
{
13011322
struct nvme_command *cmd = req->cmd;

drivers/nvme/target/core.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -911,6 +911,33 @@ static inline u16 nvmet_io_cmd_check_access(struct nvmet_req *req)
911911
return 0;
912912
}
913913

914+
static u32 nvmet_io_cmd_transfer_len(struct nvmet_req *req)
915+
{
916+
struct nvme_command *cmd = req->cmd;
917+
u32 metadata_len = 0;
918+
919+
if (nvme_is_fabrics(cmd))
920+
return nvmet_fabrics_io_cmd_data_len(req);
921+
922+
if (!req->ns)
923+
return 0;
924+
925+
switch (req->cmd->common.opcode) {
926+
case nvme_cmd_read:
927+
case nvme_cmd_write:
928+
case nvme_cmd_zone_append:
929+
if (req->sq->ctrl->pi_support && nvmet_ns_has_pi(req->ns))
930+
metadata_len = nvmet_rw_metadata_len(req);
931+
return nvmet_rw_data_len(req) + metadata_len;
932+
case nvme_cmd_dsm:
933+
return nvmet_dsm_len(req);
934+
case nvme_cmd_zone_mgmt_recv:
935+
return (le32_to_cpu(req->cmd->zmr.numd) + 1) << 2;
936+
default:
937+
return 0;
938+
}
939+
}
940+
914941
static u16 nvmet_parse_io_cmd(struct nvmet_req *req)
915942
{
916943
struct nvme_command *cmd = req->cmd;
@@ -1059,6 +1086,16 @@ void nvmet_req_uninit(struct nvmet_req *req)
10591086
}
10601087
EXPORT_SYMBOL_GPL(nvmet_req_uninit);
10611088

1089+
size_t nvmet_req_transfer_len(struct nvmet_req *req)
1090+
{
1091+
if (likely(req->sq->qid != 0))
1092+
return nvmet_io_cmd_transfer_len(req);
1093+
if (unlikely(!req->sq->ctrl))
1094+
return nvmet_connect_cmd_data_len(req);
1095+
return nvmet_admin_cmd_data_len(req);
1096+
}
1097+
EXPORT_SYMBOL_GPL(nvmet_req_transfer_len);
1098+
10621099
bool nvmet_check_transfer_len(struct nvmet_req *req, size_t len)
10631100
{
10641101
if (unlikely(len != req->transfer_len)) {

drivers/nvme/target/discovery.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,20 @@ static void nvmet_execute_disc_get_features(struct nvmet_req *req)
355355
nvmet_req_complete(req, stat);
356356
}
357357

358+
u32 nvmet_discovery_cmd_data_len(struct nvmet_req *req)
359+
{
360+
struct nvme_command *cmd = req->cmd;
361+
362+
switch (cmd->common.opcode) {
363+
case nvme_admin_get_log_page:
364+
return nvmet_get_log_page_len(req->cmd);
365+
case nvme_admin_identify:
366+
return NVME_IDENTIFY_DATA_SIZE;
367+
default:
368+
return 0;
369+
}
370+
}
371+
358372
u16 nvmet_parse_discovery_cmd(struct nvmet_req *req)
359373
{
360374
struct nvme_command *cmd = req->cmd;

drivers/nvme/target/fabrics-cmd-auth.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,11 @@ static u8 nvmet_auth_failure2(void *d)
179179
return data->rescode_exp;
180180
}
181181

182+
u32 nvmet_auth_send_data_len(struct nvmet_req *req)
183+
{
184+
return le32_to_cpu(req->cmd->auth_send.tl);
185+
}
186+
182187
void nvmet_execute_auth_send(struct nvmet_req *req)
183188
{
184189
struct nvmet_ctrl *ctrl = req->sq->ctrl;
@@ -206,7 +211,7 @@ void nvmet_execute_auth_send(struct nvmet_req *req)
206211
offsetof(struct nvmf_auth_send_command, spsp1);
207212
goto done;
208213
}
209-
tl = le32_to_cpu(req->cmd->auth_send.tl);
214+
tl = nvmet_auth_send_data_len(req);
210215
if (!tl) {
211216
status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR;
212217
req->error_loc =
@@ -429,6 +434,11 @@ static void nvmet_auth_failure1(struct nvmet_req *req, void *d, int al)
429434
data->rescode_exp = req->sq->dhchap_status;
430435
}
431436

437+
u32 nvmet_auth_receive_data_len(struct nvmet_req *req)
438+
{
439+
return le32_to_cpu(req->cmd->auth_receive.al);
440+
}
441+
432442
void nvmet_execute_auth_receive(struct nvmet_req *req)
433443
{
434444
struct nvmet_ctrl *ctrl = req->sq->ctrl;
@@ -454,7 +464,7 @@ void nvmet_execute_auth_receive(struct nvmet_req *req)
454464
offsetof(struct nvmf_auth_receive_command, spsp1);
455465
goto done;
456466
}
457-
al = le32_to_cpu(req->cmd->auth_receive.al);
467+
al = nvmet_auth_receive_data_len(req);
458468
if (!al) {
459469
status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR;
460470
req->error_loc =

drivers/nvme/target/fabrics-cmd.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,22 @@ static void nvmet_execute_prop_get(struct nvmet_req *req)
8585
nvmet_req_complete(req, status);
8686
}
8787

88+
u32 nvmet_fabrics_admin_cmd_data_len(struct nvmet_req *req)
89+
{
90+
struct nvme_command *cmd = req->cmd;
91+
92+
switch (cmd->fabrics.fctype) {
93+
#ifdef CONFIG_NVME_TARGET_AUTH
94+
case nvme_fabrics_type_auth_send:
95+
return nvmet_auth_send_data_len(req);
96+
case nvme_fabrics_type_auth_receive:
97+
return nvmet_auth_receive_data_len(req);
98+
#endif
99+
default:
100+
return 0;
101+
}
102+
}
103+
88104
u16 nvmet_parse_fabrics_admin_cmd(struct nvmet_req *req)
89105
{
90106
struct nvme_command *cmd = req->cmd;
@@ -114,6 +130,22 @@ u16 nvmet_parse_fabrics_admin_cmd(struct nvmet_req *req)
114130
return 0;
115131
}
116132

133+
u32 nvmet_fabrics_io_cmd_data_len(struct nvmet_req *req)
134+
{
135+
struct nvme_command *cmd = req->cmd;
136+
137+
switch (cmd->fabrics.fctype) {
138+
#ifdef CONFIG_NVME_TARGET_AUTH
139+
case nvme_fabrics_type_auth_send:
140+
return nvmet_auth_send_data_len(req);
141+
case nvme_fabrics_type_auth_receive:
142+
return nvmet_auth_receive_data_len(req);
143+
#endif
144+
default:
145+
return 0;
146+
}
147+
}
148+
117149
u16 nvmet_parse_fabrics_io_cmd(struct nvmet_req *req)
118150
{
119151
struct nvme_command *cmd = req->cmd;
@@ -337,6 +369,17 @@ static void nvmet_execute_io_connect(struct nvmet_req *req)
337369
goto out;
338370
}
339371

372+
u32 nvmet_connect_cmd_data_len(struct nvmet_req *req)
373+
{
374+
struct nvme_command *cmd = req->cmd;
375+
376+
if (!nvme_is_fabrics(cmd) ||
377+
cmd->fabrics.fctype != nvme_fabrics_type_connect)
378+
return 0;
379+
380+
return sizeof(struct nvmf_connect_data);
381+
}
382+
340383
u16 nvmet_parse_connect_cmd(struct nvmet_req *req)
341384
{
342385
struct nvme_command *cmd = req->cmd;

drivers/nvme/target/nvmet.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,18 +517,24 @@ void nvmet_start_keep_alive_timer(struct nvmet_ctrl *ctrl);
517517
void nvmet_stop_keep_alive_timer(struct nvmet_ctrl *ctrl);
518518

519519
u16 nvmet_parse_connect_cmd(struct nvmet_req *req);
520+
u32 nvmet_connect_cmd_data_len(struct nvmet_req *req);
520521
void nvmet_bdev_set_limits(struct block_device *bdev, struct nvme_id_ns *id);
521522
u16 nvmet_bdev_parse_io_cmd(struct nvmet_req *req);
522523
u16 nvmet_file_parse_io_cmd(struct nvmet_req *req);
523524
u16 nvmet_bdev_zns_parse_io_cmd(struct nvmet_req *req);
525+
u32 nvmet_admin_cmd_data_len(struct nvmet_req *req);
524526
u16 nvmet_parse_admin_cmd(struct nvmet_req *req);
527+
u32 nvmet_discovery_cmd_data_len(struct nvmet_req *req);
525528
u16 nvmet_parse_discovery_cmd(struct nvmet_req *req);
526529
u16 nvmet_parse_fabrics_admin_cmd(struct nvmet_req *req);
530+
u32 nvmet_fabrics_admin_cmd_data_len(struct nvmet_req *req);
527531
u16 nvmet_parse_fabrics_io_cmd(struct nvmet_req *req);
532+
u32 nvmet_fabrics_io_cmd_data_len(struct nvmet_req *req);
528533

529534
bool nvmet_req_init(struct nvmet_req *req, struct nvmet_cq *cq,
530535
struct nvmet_sq *sq, const struct nvmet_fabrics_ops *ops);
531536
void nvmet_req_uninit(struct nvmet_req *req);
537+
size_t nvmet_req_transfer_len(struct nvmet_req *req);
532538
bool nvmet_check_transfer_len(struct nvmet_req *req, size_t len);
533539
bool nvmet_check_data_len_lte(struct nvmet_req *req, size_t data_len);
534540
void nvmet_req_complete(struct nvmet_req *req, u16 status);
@@ -822,7 +828,9 @@ static inline void nvmet_req_bio_put(struct nvmet_req *req, struct bio *bio)
822828
}
823829

824830
#ifdef CONFIG_NVME_TARGET_AUTH
831+
u32 nvmet_auth_send_data_len(struct nvmet_req *req);
825832
void nvmet_execute_auth_send(struct nvmet_req *req);
833+
u32 nvmet_auth_receive_data_len(struct nvmet_req *req);
826834
void nvmet_execute_auth_receive(struct nvmet_req *req);
827835
int nvmet_auth_set_key(struct nvmet_host *host, const char *secret,
828836
bool set_ctrl);

0 commit comments

Comments
 (0)