diff options
| -rw-r--r-- | drivers/nvme/host/core.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index bc288990fd50..d4226c18eb71 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c | |||
| @@ -1394,14 +1394,31 @@ static int nvme_ioctl(struct block_device *bdev, fmode_t mode, | |||
| 1394 | if (unlikely(!ns)) | 1394 | if (unlikely(!ns)) |
| 1395 | return -EWOULDBLOCK; | 1395 | return -EWOULDBLOCK; |
| 1396 | 1396 | ||
| 1397 | /* | ||
| 1398 | * Handle ioctls that apply to the controller instead of the namespace | ||
| 1399 | * seperately and drop the ns SRCU reference early. This avoids a | ||
| 1400 | * deadlock when deleting namespaces using the passthrough interface. | ||
| 1401 | */ | ||
| 1402 | if (cmd == NVME_IOCTL_ADMIN_CMD || is_sed_ioctl(cmd)) { | ||
| 1403 | struct nvme_ctrl *ctrl = ns->ctrl; | ||
| 1404 | |||
| 1405 | nvme_get_ctrl(ns->ctrl); | ||
| 1406 | nvme_put_ns_from_disk(head, srcu_idx); | ||
| 1407 | |||
| 1408 | if (cmd == NVME_IOCTL_ADMIN_CMD) | ||
| 1409 | ret = nvme_user_cmd(ctrl, NULL, argp); | ||
| 1410 | else | ||
| 1411 | ret = sed_ioctl(ctrl->opal_dev, cmd, argp); | ||
| 1412 | |||
| 1413 | nvme_put_ctrl(ctrl); | ||
| 1414 | return ret; | ||
| 1415 | } | ||
| 1416 | |||
| 1397 | switch (cmd) { | 1417 | switch (cmd) { |
| 1398 | case NVME_IOCTL_ID: | 1418 | case NVME_IOCTL_ID: |
| 1399 | force_successful_syscall_return(); | 1419 | force_successful_syscall_return(); |
| 1400 | ret = ns->head->ns_id; | 1420 | ret = ns->head->ns_id; |
| 1401 | break; | 1421 | break; |
| 1402 | case NVME_IOCTL_ADMIN_CMD: | ||
| 1403 | ret = nvme_user_cmd(ns->ctrl, NULL, argp); | ||
| 1404 | break; | ||
| 1405 | case NVME_IOCTL_IO_CMD: | 1422 | case NVME_IOCTL_IO_CMD: |
| 1406 | ret = nvme_user_cmd(ns->ctrl, ns, argp); | 1423 | ret = nvme_user_cmd(ns->ctrl, ns, argp); |
| 1407 | break; | 1424 | break; |
| @@ -1411,8 +1428,6 @@ static int nvme_ioctl(struct block_device *bdev, fmode_t mode, | |||
| 1411 | default: | 1428 | default: |
| 1412 | if (ns->ndev) | 1429 | if (ns->ndev) |
| 1413 | ret = nvme_nvm_ioctl(ns, cmd, arg); | 1430 | ret = nvme_nvm_ioctl(ns, cmd, arg); |
| 1414 | else if (is_sed_ioctl(cmd)) | ||
| 1415 | ret = sed_ioctl(ns->ctrl->opal_dev, cmd, argp); | ||
| 1416 | else | 1431 | else |
| 1417 | ret = -ENOTTY; | 1432 | ret = -ENOTTY; |
| 1418 | } | 1433 | } |
