nvmet: export I/O characteristics attributes in Identify
Make the NVMe NAWUN, NAWUPF, NACWU, NPWG, NPWA, NPDG and NOWS attributes available to initator systems for the block backend. Signed-off-by: Bart Van Assche <bvanassche@acm.org> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com> Reviewed-by: Hannes Reinecke <hare@suse.com> Signed-off-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
Родитель
4c0181bf6c
Коммит
9d05a96e29
|
@ -442,6 +442,9 @@ static void nvmet_execute_identify_ns(struct nvmet_req *req)
|
|||
break;
|
||||
}
|
||||
|
||||
if (ns->bdev)
|
||||
nvmet_bdev_set_limits(ns->bdev, id);
|
||||
|
||||
/*
|
||||
* We just provide a single LBA format that matches what the
|
||||
* underlying device reports.
|
||||
|
|
|
@ -8,6 +8,45 @@
|
|||
#include <linux/module.h>
|
||||
#include "nvmet.h"
|
||||
|
||||
void nvmet_bdev_set_limits(struct block_device *bdev, struct nvme_id_ns *id)
|
||||
{
|
||||
const struct queue_limits *ql = &bdev_get_queue(bdev)->limits;
|
||||
/* Number of physical blocks per logical block. */
|
||||
const u32 ppl = ql->physical_block_size / ql->logical_block_size;
|
||||
/* Physical blocks per logical block, 0's based. */
|
||||
const __le16 ppl0b = to0based(ppl);
|
||||
|
||||
/*
|
||||
* For NVMe 1.2 and later, bit 1 indicates that the fields NAWUN,
|
||||
* NAWUPF, and NACWU are defined for this namespace and should be
|
||||
* used by the host for this namespace instead of the AWUN, AWUPF,
|
||||
* and ACWU fields in the Identify Controller data structure. If
|
||||
* any of these fields are zero that means that the corresponding
|
||||
* field from the identify controller data structure should be used.
|
||||
*/
|
||||
id->nsfeat |= 1 << 1;
|
||||
id->nawun = ppl0b;
|
||||
id->nawupf = ppl0b;
|
||||
id->nacwu = ppl0b;
|
||||
|
||||
/*
|
||||
* Bit 4 indicates that the fields NPWG, NPWA, NPDG, NPDA, and
|
||||
* NOWS are defined for this namespace and should be used by
|
||||
* the host for I/O optimization.
|
||||
*/
|
||||
id->nsfeat |= 1 << 4;
|
||||
/* NPWG = Namespace Preferred Write Granularity. 0's based */
|
||||
id->npwg = ppl0b;
|
||||
/* NPWA = Namespace Preferred Write Alignment. 0's based */
|
||||
id->npwa = id->npwg;
|
||||
/* NPDG = Namespace Preferred Deallocate Granularity. 0's based */
|
||||
id->npdg = to0based(ql->discard_granularity / ql->logical_block_size);
|
||||
/* NPDG = Namespace Preferred Deallocate Alignment */
|
||||
id->npda = id->npdg;
|
||||
/* NOWS = Namespace Optimal Write Size */
|
||||
id->nows = to0based(ql->io_opt / ql->logical_block_size);
|
||||
}
|
||||
|
||||
int nvmet_bdev_ns_enable(struct nvmet_ns *ns)
|
||||
{
|
||||
int ret;
|
||||
|
|
|
@ -365,6 +365,7 @@ u16 nvmet_set_feat_async_event(struct nvmet_req *req, u32 mask);
|
|||
void nvmet_execute_async_event(struct nvmet_req *req);
|
||||
|
||||
u16 nvmet_parse_connect_cmd(struct nvmet_req *req);
|
||||
void nvmet_bdev_set_limits(struct block_device *bdev, struct nvme_id_ns *id);
|
||||
u16 nvmet_bdev_parse_io_cmd(struct nvmet_req *req);
|
||||
u16 nvmet_file_parse_io_cmd(struct nvmet_req *req);
|
||||
u16 nvmet_parse_admin_cmd(struct nvmet_req *req);
|
||||
|
@ -492,4 +493,11 @@ static inline u32 nvmet_rw_len(struct nvmet_req *req)
|
|||
}
|
||||
|
||||
u16 errno_to_nvme_status(struct nvmet_req *req, int errno);
|
||||
|
||||
/* Convert a 32-bit number to a 16-bit 0's based number */
|
||||
static inline __le16 to0based(u32 a)
|
||||
{
|
||||
return cpu_to_le16(max(1U, min(1U << 16, a)) - 1);
|
||||
}
|
||||
|
||||
#endif /* _NVMET_H */
|
||||
|
|
Загрузка…
Ссылка в новой задаче