nvmet: don't report 0-bytes in serial number
authorMartin Wilck <mwilck@suse.com>
Thu, 13 Jul 2017 22:25:31 +0000 (00:25 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 16 Jun 2018 07:52:32 +0000 (09:52 +0200)
commit 42de82a8b544fa55670feef7d6f85085fba48fc0 upstream.

The NVME standard mandates that the SN, MN, and FR fields of the Identify
Controller Data Structure be "ASCII strings".  That means that they may
not contain 0-bytes, not even string terminators.

Signed-off-by: Martin Wilck <mwilck@suse.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
[hch: fixed for the move of the serial field, updated description]
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/nvme/target/admin-cmd.c

index 347a1ec..5cddab5 100644 (file)
@@ -166,11 +166,21 @@ out:
        nvmet_req_complete(req, status);
 }
 
+static void copy_and_pad(char *dst, int dst_len, const char *src, int src_len)
+{
+       int len = min(src_len, dst_len);
+
+       memcpy(dst, src, len);
+       if (dst_len > len)
+               memset(dst + len, ' ', dst_len - len);
+}
+
 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;
+       const char model[] = "Linux";
 
        id = kzalloc(sizeof(*id), GFP_KERNEL);
        if (!id) {
@@ -182,8 +192,10 @@ static void nvmet_execute_identify_ctrl(struct nvmet_req *req)
        id->vid = 0;
        id->ssvid = 0;
 
-       memset(id->sn, ' ', sizeof(id->sn));
-       snprintf(id->sn, sizeof(id->sn), "%llx", ctrl->subsys->serial);
+       bin2hex(id->sn, &ctrl->subsys->serial,
+               min(sizeof(ctrl->subsys->serial), sizeof(id->sn) / 2));
+       copy_and_pad(id->mn, sizeof(id->mn), model, sizeof(model) - 1);
+       copy_and_pad(id->fr, sizeof(id->fr), UTS_RELEASE, strlen(UTS_RELEASE));
 
        memset(id->mn, ' ', sizeof(id->mn));
        strncpy((char *)id->mn, "Linux", sizeof(id->mn));