[PATCH 17/20] nvmet: override identify for file backed ns
Chaitanya Kulkarni
chaitanya.kulkarni at wdc.com
Wed Apr 18 12:00:08 PDT 2018
Update identify ctrl/ns to initialize file backed namespaces fields.
Signed-off-by: Chaitanya Kulkarni <chaitanya.kulkarni at wdc.com>
---
drivers/nvme/target/admin-cmd.c | 75 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 75 insertions(+)
diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c
index b60477c50880..19b93952bd16 100644
--- a/drivers/nvme/target/admin-cmd.c
+++ b/drivers/nvme/target/admin-cmd.c
@@ -319,11 +319,39 @@ static void nvmet_identify_ctrl_init(struct nvmet_ctrl *ctrl,
id->psd[0].exit_lat = cpu_to_le32(0x4);
}
+static u16 nvmet_identify_ctrl_init_file(struct nvmet_req *req,
+ struct nvme_id_ctrl *id)
+{
+ struct nvmet_ctrl *ctrl = req->sq->ctrl;
+ struct nvmet_subsys *subsys = ctrl->subsys;
+ struct kstatfs fsstat;
+ __le64 tnvmcap;
+ __le64 unvmcap;
+ u16 status = NVME_SC_SUCCESS;
+
+ if (nvmet_vfs_statfs(subsys->mount_path, &fsstat)) {
+ status = NVME_SC_INTERNAL | NVME_SC_DNR;
+ goto out;
+ }
+
+ id->oacs = 1 << 3; /* we support namespace management */
+
+ tnvmcap = cpu_to_le64(fsstat.f_blocks * fsstat.f_bsize);
+ memcpy(id->tnvmcap, &tnvmcap, sizeof(tnvmcap));
+
+ unvmcap = cpu_to_le64(fsstat.f_bfree * fsstat.f_bsize);
+ memcpy(id->unvmcap, &tnvmcap, sizeof(unvmcap));
+
+out:
+ return status;
+}
+
static void nvmet_execute_identify_ctrl(struct nvmet_req *req)
{
struct nvmet_ctrl *ctrl = req->sq->ctrl;
struct nvme_id_ctrl *id;
u16 status = 0;
+ u16 file_status = 0;
id = kzalloc(sizeof(*id), GFP_KERNEL);
if (!id) {
@@ -333,8 +361,14 @@ static void nvmet_execute_identify_ctrl(struct nvmet_req *req)
nvmet_identify_ctrl_init(ctrl, id);
+ if (req->sq->ctrl->subsys->mount_path)
+ file_status = nvmet_identify_ctrl_init_file(req, id);
+
status = nvmet_copy_to_sgl(req, 0, id, sizeof(*id));
+ if (req->sq->ctrl->subsys->mount_path && file_status)
+ status = file_status;
+
kfree(id);
out:
nvmet_req_complete(req, status);
@@ -367,11 +401,46 @@ static void nvmet_identify_ns_init(struct nvmet_ns *ns, struct nvme_id_ns *id)
id->lbaf[0].ds = ns->blksize_shift;
}
+static int nvmet_identify_ns_file_stats(struct nvmet_ns *ns,
+ struct nvme_id_ns *id)
+{
+ u64 alloc_blk;
+ u64 blk_size = (1 << ns->blksize_shift);
+ struct kstat stat;
+ __le64 size;
+
+ if (nvmet_vfs_stat(ns->device_path, &stat))
+ return -1;
+
+ alloc_blk = DIV_ROUND_UP((stat.blocks * (1 << 9)), blk_size);
+
+ id->nsze = cpu_to_le64(DIV_ROUND_UP(stat.size, blk_size));
+ id->ncap = id->nuse = cpu_to_le64(alloc_blk);
+
+ memcpy(id->nvmcap, &size, sizeof(size));
+
+ return 0;
+}
+
+static int nvmet_identify_ns_init_file(struct nvmet_ns *ns,
+ struct nvme_id_ns *id)
+{
+ int ret;
+
+ ret = nvmet_identify_ns_file_stats(ns, id);
+ if (ret)
+ return NVME_SC_INVALID_NS;
+
+ id->nsfeat = 1 << 0;
+ return 0;
+}
+
static void nvmet_execute_identify_ns(struct nvmet_req *req)
{
struct nvmet_ns *ns;
struct nvme_id_ns *id;
u16 status = 0;
+ u16 file_status = 0;
ns = nvmet_find_namespace(req->sq->ctrl, req->cmd->identify.nsid);
if (!ns) {
@@ -387,8 +456,14 @@ static void nvmet_execute_identify_ns(struct nvmet_req *req)
nvmet_identify_ns_init(ns, id);
+ if (req->sq->ctrl->subsys->mount_path)
+ file_status = nvmet_identify_ns_init_file(ns, id);
+
status = nvmet_copy_to_sgl(req, 0, id, sizeof(*id));
+ if (req->sq->ctrl->subsys->mount_path && file_status)
+ status = file_status;
+
kfree(id);
out_put_ns:
nvmet_put_namespace(ns);
--
2.14.1
More information about the Linux-nvme
mailing list