@@ -44,13 +44,69 @@ void nvmet_bdev_ns_disable(struct nvmet_ns *ns)
44
44
}
45
45
}
46
46
47
+ static u16 blk_to_nvme_status (struct nvmet_req * req , blk_status_t blk_sts )
48
+ {
49
+ u16 status = NVME_SC_SUCCESS ;
50
+
51
+ if (likely (blk_sts == BLK_STS_OK ))
52
+ return status ;
53
+ /*
54
+ * Right now there exists M : 1 mapping between block layer error
55
+ * to the NVMe status code (see nvme_error_status()). For consistency,
56
+ * when we reverse map we use most appropriate NVMe Status code from
57
+ * the group of the NVMe staus codes used in the nvme_error_status().
58
+ */
59
+ switch (blk_sts ) {
60
+ case BLK_STS_NOSPC :
61
+ status = NVME_SC_CAP_EXCEEDED | NVME_SC_DNR ;
62
+ req -> error_loc = offsetof(struct nvme_rw_command , length );
63
+ break ;
64
+ case BLK_STS_TARGET :
65
+ status = NVME_SC_LBA_RANGE | NVME_SC_DNR ;
66
+ req -> error_loc = offsetof(struct nvme_rw_command , slba );
67
+ break ;
68
+ case BLK_STS_NOTSUPP :
69
+ req -> error_loc = offsetof(struct nvme_common_command , opcode );
70
+ switch (req -> cmd -> common .opcode ) {
71
+ case nvme_cmd_dsm :
72
+ case nvme_cmd_write_zeroes :
73
+ status = NVME_SC_ONCS_NOT_SUPPORTED | NVME_SC_DNR ;
74
+ break ;
75
+ default :
76
+ status = NVME_SC_INVALID_OPCODE | NVME_SC_DNR ;
77
+ }
78
+ break ;
79
+ case BLK_STS_MEDIUM :
80
+ status = NVME_SC_ACCESS_DENIED ;
81
+ req -> error_loc = offsetof(struct nvme_rw_command , nsid );
82
+ break ;
83
+ case BLK_STS_IOERR :
84
+ /* fallthru */
85
+ default :
86
+ status = NVME_SC_INTERNAL | NVME_SC_DNR ;
87
+ req -> error_loc = offsetof(struct nvme_common_command , opcode );
88
+ }
89
+
90
+ switch (req -> cmd -> common .opcode ) {
91
+ case nvme_cmd_read :
92
+ case nvme_cmd_write :
93
+ req -> error_slba = le64_to_cpu (req -> cmd -> rw .slba );
94
+ break ;
95
+ case nvme_cmd_write_zeroes :
96
+ req -> error_slba =
97
+ le64_to_cpu (req -> cmd -> write_zeroes .slba );
98
+ break ;
99
+ default :
100
+ req -> error_slba = 0 ;
101
+ }
102
+ return status ;
103
+ }
104
+
47
105
static void nvmet_bio_done (struct bio * bio )
48
106
{
49
107
struct nvmet_req * req = bio -> bi_private ;
50
108
51
- nvmet_req_complete (req ,
52
- bio -> bi_status ? NVME_SC_INTERNAL | NVME_SC_DNR : 0 );
53
-
109
+ nvmet_req_complete (req , blk_to_nvme_status (req , bio -> bi_status ));
54
110
if (bio != & req -> b .inline_bio )
55
111
bio_put (bio );
56
112
}
@@ -136,18 +192,21 @@ u16 nvmet_bdev_flush(struct nvmet_req *req)
136
192
return 0 ;
137
193
}
138
194
139
- static u16 nvmet_bdev_discard_range (struct nvmet_ns * ns ,
195
+ static u16 nvmet_bdev_discard_range (struct nvmet_req * req ,
140
196
struct nvme_dsm_range * range , struct bio * * bio )
141
197
{
198
+ struct nvmet_ns * ns = req -> ns ;
142
199
int ret ;
143
200
144
201
ret = __blkdev_issue_discard (ns -> bdev ,
145
202
le64_to_cpu (range -> slba ) << (ns -> blksize_shift - 9 ),
146
203
le32_to_cpu (range -> nlb ) << (ns -> blksize_shift - 9 ),
147
204
GFP_KERNEL , 0 , bio );
148
- if (ret && ret != - EOPNOTSUPP )
149
- return NVME_SC_INTERNAL | NVME_SC_DNR ;
150
- return 0 ;
205
+
206
+ if (ret )
207
+ req -> error_slba = le64_to_cpu (range -> slba );
208
+
209
+ return blk_to_nvme_status (req , errno_to_blk_status (ret ));
151
210
}
152
211
153
212
static void nvmet_bdev_execute_discard (struct nvmet_req * req )
@@ -163,7 +222,7 @@ static void nvmet_bdev_execute_discard(struct nvmet_req *req)
163
222
if (status )
164
223
break ;
165
224
166
- status = nvmet_bdev_discard_range (req -> ns , & range , & bio );
225
+ status = nvmet_bdev_discard_range (req , & range , & bio );
167
226
if (status )
168
227
break ;
169
228
}
@@ -204,16 +263,16 @@ static void nvmet_bdev_execute_write_zeroes(struct nvmet_req *req)
204
263
u16 status = NVME_SC_SUCCESS ;
205
264
sector_t sector ;
206
265
sector_t nr_sector ;
266
+ int ret ;
207
267
208
268
sector = le64_to_cpu (write_zeroes -> slba ) <<
209
269
(req -> ns -> blksize_shift - 9 );
210
270
nr_sector = (((sector_t )le16_to_cpu (write_zeroes -> length ) + 1 ) <<
211
271
(req -> ns -> blksize_shift - 9 ));
212
272
213
- if (__blkdev_issue_zeroout (req -> ns -> bdev , sector , nr_sector ,
214
- GFP_KERNEL , & bio , 0 ))
215
- status = NVME_SC_INTERNAL | NVME_SC_DNR ;
216
-
273
+ ret = __blkdev_issue_zeroout (req -> ns -> bdev , sector , nr_sector ,
274
+ GFP_KERNEL , & bio , 0 );
275
+ status = blk_to_nvme_status (req , errno_to_blk_status (ret ));
217
276
if (bio ) {
218
277
bio -> bi_private = req ;
219
278
bio -> bi_end_io = nvmet_bio_done ;
@@ -248,6 +307,7 @@ u16 nvmet_bdev_parse_io_cmd(struct nvmet_req *req)
248
307
default :
249
308
pr_err ("unhandled cmd %d on qid %d\n" , cmd -> common .opcode ,
250
309
req -> sq -> qid );
310
+ req -> error_loc = offsetof(struct nvme_common_command , opcode );
251
311
return NVME_SC_INVALID_OPCODE | NVME_SC_DNR ;
252
312
}
253
313
}
0 commit comments