* [PATCH v2] nvme: check if the namespace supports metadata in nvme_map_user_request() @ 2024-08-27 13:23 ` Puranjay Mohan 2024-08-28 4:28 ` Christoph Hellwig ` (3 more replies) 0 siblings, 4 replies; 8+ messages in thread From: Puranjay Mohan @ 2024-08-27 13:23 UTC (permalink / raw) To: Keith Busch, Jens Axboe, Christoph Hellwig, Sagi Grimberg, linux-nvme, linux-kernel, puranjay On an NVMe namespace that does not support metadata, it is possible to send an IO command with metadata through io-passthru. nvme_map_user_request() doesn't check if the namespace supports metadata before sending it forward. Reject an IO command with metadata when the NVMe namespace doesn't support it. Suggested-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Puranjay Mohan <pjy@amazon.com> --- V1: https://lore.kernel.org/all/20240827121701.48792-1-pjy@amazon.com/ Changes in V2: - Add a flag called 'has_metadata' and use it for the support check and also for the check before calling bio_integrity_map_user() --- drivers/nvme/host/ioctl.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c index f1d58e70933f..74d963d425c4 100644 --- a/drivers/nvme/host/ioctl.c +++ b/drivers/nvme/host/ioctl.c @@ -4,6 +4,7 @@ * Copyright (c) 2017-2021 Christoph Hellwig. */ #include <linux/bio-integrity.h> +#include <linux/blk-integrity.h> #include <linux/ptrace.h> /* for force_successful_syscall_return */ #include <linux/nvme_ioctl.h> #include <linux/io_uring/cmd.h> @@ -119,9 +120,13 @@ static int nvme_map_user_request(struct request *req, u64 ubuffer, struct request_queue *q = req->q; struct nvme_ns *ns = q->queuedata; struct block_device *bdev = ns ? ns->disk->part0 : NULL; + bool has_metadata = bdev && meta_buffer && meta_len; struct bio *bio = NULL; int ret; + if (has_metadata && !blk_get_integrity(bdev->bd_disk)) + return -EINVAL; + if (ioucmd && (ioucmd->flags & IORING_URING_CMD_FIXED)) { struct iov_iter iter; @@ -143,15 +148,15 @@ static int nvme_map_user_request(struct request *req, u64 ubuffer, goto out; bio = req->bio; - if (bdev) { + if (bdev) bio_set_dev(bio, bdev); - if (meta_buffer && meta_len) { - ret = bio_integrity_map_user(bio, meta_buffer, meta_len, - meta_seed); - if (ret) - goto out_unmap; - req->cmd_flags |= REQ_INTEGRITY; - } + + if (has_metadata) { + ret = bio_integrity_map_user(bio, meta_buffer, meta_len, + meta_seed); + if (ret) + goto out_unmap; + req->cmd_flags |= REQ_INTEGRITY; } return ret; -- 2.40.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2] nvme: check if the namespace supports metadata in nvme_map_user_request() 2024-08-27 13:23 ` [PATCH v2] nvme: check if the namespace supports metadata in nvme_map_user_request() Puranjay Mohan @ 2024-08-28 4:28 ` Christoph Hellwig 2024-08-28 7:21 ` Sagi Grimberg ` (2 subsequent siblings) 3 siblings, 0 replies; 8+ messages in thread From: Christoph Hellwig @ 2024-08-28 4:28 UTC (permalink / raw) To: Puranjay Mohan Cc: Keith Busch, Jens Axboe, Christoph Hellwig, Sagi Grimberg, linux-nvme, linux-kernel, puranjay Looks good: Reviewed-by: Christoph Hellwig <hch@lst.de> ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] nvme: check if the namespace supports metadata in nvme_map_user_request() 2024-08-27 13:23 ` [PATCH v2] nvme: check if the namespace supports metadata in nvme_map_user_request() Puranjay Mohan 2024-08-28 4:28 ` Christoph Hellwig @ 2024-08-28 7:21 ` Sagi Grimberg 2024-08-28 9:45 ` Anuj Gupta 2024-08-28 14:44 ` [PATCH v2] " Keith Busch 3 siblings, 0 replies; 8+ messages in thread From: Sagi Grimberg @ 2024-08-28 7:21 UTC (permalink / raw) To: Puranjay Mohan, Keith Busch, Jens Axboe, Christoph Hellwig, linux-nvme, linux-kernel, puranjay Reviewed-by: Sagi Grimberg <sagi@grimberg.me> ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: nvme: check if the namespace supports metadata in nvme_map_user_request() 2024-08-27 13:23 ` [PATCH v2] nvme: check if the namespace supports metadata in nvme_map_user_request() Puranjay Mohan 2024-08-28 4:28 ` Christoph Hellwig 2024-08-28 7:21 ` Sagi Grimberg @ 2024-08-28 9:45 ` Anuj Gupta 2024-08-28 14:44 ` [PATCH v2] " Keith Busch 3 siblings, 0 replies; 8+ messages in thread From: Anuj Gupta @ 2024-08-28 9:45 UTC (permalink / raw) To: Puranjay Mohan Cc: Keith Busch, Jens Axboe, Christoph Hellwig, Sagi Grimberg, linux-nvme, linux-kernel, puranjay [-- Attachment #1: Type: text/plain, Size: 47 bytes --] Reviewed-by: Anuj Gupta <anuj20.g@samsung.com> [-- Attachment #2: Type: text/plain, Size: 0 bytes --] ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] nvme: check if the namespace supports metadata in nvme_map_user_request() 2024-08-27 13:23 ` [PATCH v2] nvme: check if the namespace supports metadata in nvme_map_user_request() Puranjay Mohan ` (2 preceding siblings ...) 2024-08-28 9:45 ` Anuj Gupta @ 2024-08-28 14:44 ` Keith Busch 2024-08-28 15:31 ` Puranjay Mohan 2024-08-29 4:28 ` Christoph Hellwig 3 siblings, 2 replies; 8+ messages in thread From: Keith Busch @ 2024-08-28 14:44 UTC (permalink / raw) To: Puranjay Mohan Cc: Jens Axboe, Christoph Hellwig, Sagi Grimberg, linux-nvme, linux-kernel, puranjay On Tue, Aug 27, 2024 at 01:23:27PM +0000, Puranjay Mohan wrote: > @@ -119,9 +120,13 @@ static int nvme_map_user_request(struct request *req, u64 ubuffer, > struct request_queue *q = req->q; > struct nvme_ns *ns = q->queuedata; > struct block_device *bdev = ns ? ns->disk->part0 : NULL; > + bool has_metadata = bdev && meta_buffer && meta_len; If this is an admin command, then bdev is NULL, so "has_metadata" is false. > struct bio *bio = NULL; > int ret; > > + if (has_metadata && !blk_get_integrity(bdev->bd_disk)) > + return -EINVAL; > + Since has_metadata is false, we continue on to process this admin command, but ignore the user's metadata settings. Do we want to return error there too? ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] nvme: check if the namespace supports metadata in nvme_map_user_request() 2024-08-28 14:44 ` [PATCH v2] " Keith Busch @ 2024-08-28 15:31 ` Puranjay Mohan 2024-08-28 15:52 ` Keith Busch 2024-08-29 4:28 ` Christoph Hellwig 1 sibling, 1 reply; 8+ messages in thread From: Puranjay Mohan @ 2024-08-28 15:31 UTC (permalink / raw) To: Keith Busch Cc: Jens Axboe, Christoph Hellwig, Sagi Grimberg, linux-nvme, linux-kernel, puranjay Keith Busch <kbusch@kernel.org> writes: > On Tue, Aug 27, 2024 at 01:23:27PM +0000, Puranjay Mohan wrote: >> @@ -119,9 +120,13 @@ static int nvme_map_user_request(struct request *req, u64 ubuffer, >> struct request_queue *q = req->q; >> struct nvme_ns *ns = q->queuedata; >> struct block_device *bdev = ns ? ns->disk->part0 : NULL; >> + bool has_metadata = bdev && meta_buffer && meta_len; > > If this is an admin command, then bdev is NULL, so "has_metadata" is > false. > >> struct bio *bio = NULL; >> int ret; >> >> + if (has_metadata && !blk_get_integrity(bdev->bd_disk)) >> + return -EINVAL; >> + > > Since has_metadata is false, we continue on to process this admin > command, but ignore the user's metadata settings. Do we want to return > error there too? As an admin command with metadata is an invalid configuration, we can ignore the metada and go ahead with the admin command or I can add the following after the above check: if (!bdev && (meta_buffer || meta_len)) return -EINVAL; I don't know what is the best approach here. Thanks, Puranjay ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] nvme: check if the namespace supports metadata in nvme_map_user_request() 2024-08-28 15:31 ` Puranjay Mohan @ 2024-08-28 15:52 ` Keith Busch 0 siblings, 0 replies; 8+ messages in thread From: Keith Busch @ 2024-08-28 15:52 UTC (permalink / raw) To: Puranjay Mohan Cc: Jens Axboe, Christoph Hellwig, Sagi Grimberg, linux-nvme, linux-kernel, puranjay On Wed, Aug 28, 2024 at 03:31:09PM +0000, Puranjay Mohan wrote: > Keith Busch <kbusch@kernel.org> writes: > > > On Tue, Aug 27, 2024 at 01:23:27PM +0000, Puranjay Mohan wrote: > >> @@ -119,9 +120,13 @@ static int nvme_map_user_request(struct request *req, u64 ubuffer, > >> struct request_queue *q = req->q; > >> struct nvme_ns *ns = q->queuedata; > >> struct block_device *bdev = ns ? ns->disk->part0 : NULL; > >> + bool has_metadata = bdev && meta_buffer && meta_len; > > > > If this is an admin command, then bdev is NULL, so "has_metadata" is > > false. > > > >> struct bio *bio = NULL; > >> int ret; > >> > >> + if (has_metadata && !blk_get_integrity(bdev->bd_disk)) > >> + return -EINVAL; > >> + > > > > Since has_metadata is false, we continue on to process this admin > > command, but ignore the user's metadata settings. Do we want to return > > error there too? > > As an admin command with metadata is an invalid configuration, we can It's not that it's an invalid configuration. The spec defines the common command format allowing admin commands to transfer metadata. There's just no existing spec defined command that makes use of it. Nothing stops a vendor specific command from using it. If someone tried, the kernel reports success, but we didn't execute the requested command. > ignore the metada and go ahead with the admin command or I can add the > following after the above check: > > if (!bdev && (meta_buffer || meta_len)) > return -EINVAL; > > I don't know what is the best approach here. Yeah, or just do it in one line with the bdev case too: bool has_metadata = meta_buffer && meta_len; ... if (has_metadata && (!bdev || !blk_get_integrity(bdev->bd_disk))) return -EINVAL ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] nvme: check if the namespace supports metadata in nvme_map_user_request() 2024-08-28 14:44 ` [PATCH v2] " Keith Busch 2024-08-28 15:31 ` Puranjay Mohan @ 2024-08-29 4:28 ` Christoph Hellwig 1 sibling, 0 replies; 8+ messages in thread From: Christoph Hellwig @ 2024-08-29 4:28 UTC (permalink / raw) To: Keith Busch Cc: Puranjay Mohan, Jens Axboe, Christoph Hellwig, Sagi Grimberg, linux-nvme, linux-kernel, puranjay On Wed, Aug 28, 2024 at 08:44:59AM -0600, Keith Busch wrote: > On Tue, Aug 27, 2024 at 01:23:27PM +0000, Puranjay Mohan wrote: > > @@ -119,9 +120,13 @@ static int nvme_map_user_request(struct request *req, u64 ubuffer, > > struct request_queue *q = req->q; > > struct nvme_ns *ns = q->queuedata; > > struct block_device *bdev = ns ? ns->disk->part0 : NULL; > > + bool has_metadata = bdev && meta_buffer && meta_len; > > If this is an admin command, then bdev is NULL, so "has_metadata" is > false. > > Since has_metadata is false, we continue on to process this admin > command, but ignore the user's metadata settings. Do we want to return > error there too? Ah yes. I had my brain wrapped around this the wrong way the entire time. Maybe a bool supports_metadata = bdev && blk_get_integrity(bdev->bd_disk); bool has_metadata = meta_buffer && meta_len; might help poor brains like mine. ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2024-08-29 4:28 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <CGME20240828095322epcas5p134935f60a199bc085198b06871cd33ba@epcas5p1.samsung.com>
2024-08-27 13:23 ` [PATCH v2] nvme: check if the namespace supports metadata in nvme_map_user_request() Puranjay Mohan
2024-08-28 4:28 ` Christoph Hellwig
2024-08-28 7:21 ` Sagi Grimberg
2024-08-28 9:45 ` Anuj Gupta
2024-08-28 14:44 ` [PATCH v2] " Keith Busch
2024-08-28 15:31 ` Puranjay Mohan
2024-08-28 15:52 ` Keith Busch
2024-08-29 4:28 ` Christoph Hellwig
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox