]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
nvmet: implement rotational media information log
authorKeith Busch <kbusch@kernel.org>
Fri, 1 Nov 2024 20:48:47 +0000 (13:48 -0700)
committerKeith Busch <kbusch@kernel.org>
Mon, 11 Nov 2024 17:49:49 +0000 (09:49 -0800)
Most of the information is stubbed. Supporting these commands is a
requirement for supporting rotational media.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Keith Busch <kbusch@kernel.org>
drivers/nvme/host/core.c
drivers/nvme/target/admin-cmd.c
include/linux/nvme.h

index 426d4b90ecd7e77a6884c8e3cdcffe8a7bfc510b..279b0f445904dff14399bdd1d0547fb837002546 100644 (file)
@@ -5002,6 +5002,7 @@ static inline void _nvme_check_size(void)
        BUILD_BUG_ON(sizeof(struct nvme_lba_range_type) != 64);
        BUILD_BUG_ON(sizeof(struct nvme_smart_log) != 512);
        BUILD_BUG_ON(sizeof(struct nvme_endurance_group_log) != 512);
+       BUILD_BUG_ON(sizeof(struct nvme_rotational_media_log) != 512);
        BUILD_BUG_ON(sizeof(struct nvme_dbbuf) != 64);
        BUILD_BUG_ON(sizeof(struct nvme_directive_cmd) != 64);
        BUILD_BUG_ON(sizeof(struct nvme_feat_host_behavior) != 512);
index 366582f52200ba2d6e7ed1f97d9d04d5d3fd5471..33b7ecfee3fec5452db19ca6b4dc60b08cd5d264 100644 (file)
@@ -91,6 +91,7 @@ static void nvmet_execute_get_supported_log_pages(struct nvmet_req *req)
        logs->lids[NVME_LOG_ENDURANCE_GROUP] = cpu_to_le32(NVME_LIDS_LSUPP);
        logs->lids[NVME_LOG_ANA] = cpu_to_le32(NVME_LIDS_LSUPP);
        logs->lids[NVME_LOG_FEATURES] = cpu_to_le32(NVME_LIDS_LSUPP);
+       logs->lids[NVME_LOG_RMI] = cpu_to_le32(NVME_LIDS_LSUPP);
        logs->lids[NVME_LOG_RESERVATION] = cpu_to_le32(NVME_LIDS_LSUPP);
 
        status = nvmet_copy_to_sgl(req, 0, logs, sizeof(*logs));
@@ -158,6 +159,45 @@ static u16 nvmet_get_smart_log_all(struct nvmet_req *req,
        return NVME_SC_SUCCESS;
 }
 
+static void nvmet_execute_get_log_page_rmi(struct nvmet_req *req)
+{
+       struct nvme_rotational_media_log *log;
+       struct gendisk *disk;
+       u16 status;
+
+       req->cmd->common.nsid = cpu_to_le32(le16_to_cpu(
+                                           req->cmd->get_log_page.lsi));
+       status = nvmet_req_find_ns(req);
+       if (status)
+               goto out;
+
+       if (!req->ns->bdev || bdev_nonrot(req->ns->bdev)) {
+               status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR;
+               goto out;
+       }
+
+       if (req->transfer_len != sizeof(*log)) {
+               status = NVME_SC_SGL_INVALID_DATA | NVME_STATUS_DNR;
+               goto out;
+       }
+
+       log = kzalloc(sizeof(*log), GFP_KERNEL);
+       if (!log)
+               goto out;
+
+       log->endgid = req->cmd->get_log_page.lsi;
+       disk = req->ns->bdev->bd_disk;
+       if (disk && disk->ia_ranges)
+               log->numa = cpu_to_le16(disk->ia_ranges->nr_ia_ranges);
+       else
+               log->numa = cpu_to_le16(1);
+
+       status = nvmet_copy_to_sgl(req, 0, log, sizeof(*log));
+       kfree(log);
+out:
+       nvmet_req_complete(req, status);
+}
+
 static void nvmet_execute_get_log_page_smart(struct nvmet_req *req)
 {
        struct nvme_smart_log *log;
@@ -451,6 +491,8 @@ static void nvmet_execute_get_log_page(struct nvmet_req *req)
                return nvmet_execute_get_log_page_ana(req);
        case NVME_LOG_FEATURES:
                return nvmet_execute_get_log_page_features(req);
+       case NVME_LOG_RMI:
+               return nvmet_execute_get_log_page_rmi(req);
        case NVME_LOG_RESERVATION:
                return nvmet_execute_get_log_page_resv(req);
        }
index 6d5b4299a1b2dca4e5d6df14d4b4682b3307a8f1..99cf0ee73714201f70fa810820bf93a3767754f8 100644 (file)
@@ -642,6 +642,18 @@ struct nvme_endurance_group_log {
        __u8    rsvd192[320];
 };
 
+struct nvme_rotational_media_log {
+       __le16  endgid;
+       __le16  numa;
+       __le16  nrs;
+       __u8    rsvd6[2];
+       __le32  spinc;
+       __le32  fspinc;
+       __le32  ldc;
+       __le32  fldc;
+       __u8    rsvd24[488];
+};
+
 struct nvme_smart_log {
        __u8                    critical_warning;
        __u8                    temperature[2];
@@ -1281,6 +1293,7 @@ enum {
        NVME_LOG_ENDURANCE_GROUP = 0x09,
        NVME_LOG_ANA            = 0x0c,
        NVME_LOG_FEATURES       = 0x12,
+       NVME_LOG_RMI            = 0x16,
        NVME_LOG_DISC           = 0x70,
        NVME_LOG_RESERVATION    = 0x80,
        NVME_FWACT_REPL         = (0 << 3),
@@ -1435,7 +1448,7 @@ struct nvme_get_log_page_command {
        __u8                    lsp; /* upper 4 bits reserved */
        __le16                  numdl;
        __le16                  numdu;
-       __u16                   rsvd11;
+       __le16                  lsi;
        union {
                struct {
                        __le32 lpol;