static uint16_t nvme_get_feature(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req)
{
- NvmeNamespace *ns = req->ns;
-
uint32_t dw10 = le32_to_cpu(cmd->cdw10);
uint32_t dw11 = le32_to_cpu(cmd->cdw11);
uint32_t result;
+ uint32_t nsid;
+
trace_nvme_getfeat(dw10);
switch (dw10) {
result = cpu_to_le32(n->features.err_rec);
break;
case NVME_VOLATILE_WRITE_CACHE:
- result = blk_enable_write_cache(ns->conf.blk);
+ nsid = le32_to_cpu(cmd->nsid);
+ if (unlikely(nsid == 0 || nsid > n->num_namespaces)) {
+ trace_nvme_err_invalid_ns(nsid, n->num_namespaces);
+ return NVME_INVALID_NSID | NVME_DNR;
+ }
+
+ result = blk_enable_write_cache(n->namespaces[nsid - 1]->conf.blk);
trace_nvme_getfeat_vwcache(result ? "enabled" : "disabled");
break;
case NVME_NUMBER_OF_QUEUES:
static uint16_t nvme_set_feature(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req)
{
- NvmeNamespace *ns = req->ns;
-
uint32_t dw10 = le32_to_cpu(cmd->cdw10);
uint32_t dw11 = le32_to_cpu(cmd->cdw11);
+ uint32_t nsid;
+
trace_nvme_setfeat(dw10, dw11);
switch (dw10) {
}
break;
case NVME_VOLATILE_WRITE_CACHE:
- blk_set_enable_write_cache(ns->conf.blk, dw11 & 1);
+ nsid = le32_to_cpu(cmd->nsid);
+ if (unlikely(nsid == 0 || nsid > n->num_namespaces)) {
+ trace_nvme_err_invalid_ns(nsid, n->num_namespaces);
+ return NVME_INVALID_NSID | NVME_DNR;
+ }
+
+ blk_set_enable_write_cache(n->namespaces[nsid - 1]->conf.blk, dw11 & 1);
break;
case NVME_NUMBER_OF_QUEUES:
if (n->qs_created > 2) {