summaryrefslogtreecommitdiffstats
path: root/drivers/nvme/target/core.c
diff options
context:
space:
mode:
authorChaitanya Kulkarni2018-08-08 08:01:07 +0200
committerChristoph Hellwig2018-08-08 12:00:53 +0200
commitdedf0be544614b6d9d395e78d72cc8c30d03e440 (patch)
tree3d1fb89742e040317621eb41f3b3f670ec3c198a /drivers/nvme/target/core.c
parentnvme: set gendisk read only based on nsattr (diff)
downloadkernel-qcow2-linux-dedf0be544614b6d9d395e78d72cc8c30d03e440.tar.gz
kernel-qcow2-linux-dedf0be544614b6d9d395e78d72cc8c30d03e440.tar.xz
kernel-qcow2-linux-dedf0be544614b6d9d395e78d72cc8c30d03e440.zip
nvmet: add ns write protect support
This patch implements the Namespace Write Protect feature described in "NVMe TP 4005a Namespace Write Protect". In this version, we implement No Write Protect and Write Protect states for target ns which can be toggled by set-features commands from the host side. For write-protect state transition, we need to flush the ns specified as a part of command so we also add helpers for carrying out synchronous flush operations. Signed-off-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com> [hch: fixed an incorrect endianess conversion, minor cleanups] Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'drivers/nvme/target/core.c')
-rw-r--r--drivers/nvme/target/core.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
index 3ceb7a03bb2a..14b4c4916a8e 100644
--- a/drivers/nvme/target/core.c
+++ b/drivers/nvme/target/core.c
@@ -180,7 +180,7 @@ out_unlock:
mutex_unlock(&ctrl->lock);
}
-static void nvmet_ns_changed(struct nvmet_subsys *subsys, u32 nsid)
+void nvmet_ns_changed(struct nvmet_subsys *subsys, u32 nsid)
{
struct nvmet_ctrl *ctrl;
@@ -609,6 +609,21 @@ static inline u16 nvmet_check_ana_state(struct nvmet_port *port,
return 0;
}
+static inline u16 nvmet_io_cmd_check_access(struct nvmet_req *req)
+{
+ if (unlikely(req->ns->readonly)) {
+ switch (req->cmd->common.opcode) {
+ case nvme_cmd_read:
+ case nvme_cmd_flush:
+ break;
+ default:
+ return NVME_SC_NS_WRITE_PROTECTED;
+ }
+ }
+
+ return 0;
+}
+
static u16 nvmet_parse_io_cmd(struct nvmet_req *req)
{
struct nvme_command *cmd = req->cmd;
@@ -624,6 +639,9 @@ static u16 nvmet_parse_io_cmd(struct nvmet_req *req)
ret = nvmet_check_ana_state(req->port, req->ns);
if (unlikely(ret))
return ret;
+ ret = nvmet_io_cmd_check_access(req);
+ if (unlikely(ret))
+ return ret;
if (req->ns->file)
return nvmet_file_parse_io_cmd(req);