[PATCHv2 1/4] nvme: factor metadata handling out of __nvme_submit_user_cmd

Max Gurtovoy maxg at mellanox.com
Tue Aug 29 15:20:11 PDT 2017



On 8/30/2017 12:46 AM, Keith Busch wrote:
> From: Christoph Hellwig <hch at lst.de>
> 
> Keep the metadata code in a separate helper instead of making the
> main function more complicated.
> 
> Signed-off-by: Christoph Hellwig <hch at lst.de>
> ---
>   drivers/nvme/host/core.c | 78 +++++++++++++++++++++++++-----------------------
>   1 file changed, 41 insertions(+), 37 deletions(-)

snip

> 
>   int __nvme_submit_user_cmd(struct request_queue *q, struct nvme_command *cmd,
>   		void __user *ubuffer, unsigned bufflen,
>   		void __user *meta_buffer, unsigned meta_len, u32 meta_seed,
> @@ -729,46 +763,17 @@ int __nvme_submit_user_cmd(struct request_queue *q, struct nvme_command *cmd,
>   		if (ret)
>   			goto out;
>   		bio = req->bio;
> -
> -		if (!disk)
> -			goto submit;
>   		bio->bi_disk = disk;
> -
> -		if (meta_buffer && meta_len) {
> -			struct bio_integrity_payload *bip;
> -
> -			meta = kmalloc(meta_len, GFP_KERNEL);
> -			if (!meta) {
> -				ret = -ENOMEM;
> +		if (disk && meta_buffer && meta_len) {
> +			meta = nvme_add_user_metadata(bio, meta_buffer, meta_len,
> +					meta_seed, write);
> +			if (IS_ERR(meta)) {
> +				ret = PTR_ERR(meta);
>   				goto out_unmap;
>   			}
> -
> -			if (write) {
> -				if (copy_from_user(meta, meta_buffer,
> -						meta_len)) {
> -					ret = -EFAULT;
> -					goto out_free_meta;
> -				}
> -			}
> -
> -			bip = bio_integrity_alloc(bio, GFP_KERNEL, 1);
> -			if (IS_ERR(bip)) {
> -				ret = PTR_ERR(bip);
> -				goto out_free_meta;
> -			}
> -
> -			bip->bip_iter.bi_size = meta_len;
> -			bip->bip_iter.bi_sector = meta_seed;
> -
> -			ret = bio_integrity_add_page(bio, virt_to_page(meta),
> -					meta_len, offset_in_page(meta));
> -			if (ret != meta_len) {
> -				ret = -ENOMEM;
> -				goto out_free_meta;
> -			}
>   		}
>   	}
> - submit:
> +
>   	blk_execute_rq(req->q, disk, req, 0);
>   	if (nvme_req(req)->flags & NVME_REQ_CANCELLED)
>   		ret = -EINTR;
> @@ -779,9 +784,8 @@ int __nvme_submit_user_cmd(struct request_queue *q, struct nvme_command *cmd,
>   	if (meta && !ret && !write) {
>   		if (copy_to_user(meta_buffer, meta, meta_len))
>   			ret = -EFAULT;
> +		kfree(meta);

did we move the kfree(meta) here in porpose ?
I think we'll leak in the "write" case.

In general, I prefer allocating and freeing the meta buffer in the same 
function but maybe it make sense to act otherwise here.

>   	}
> - out_free_meta:
> -	kfree(meta);
>    out_unmap:
>   	if (bio)
>   		blk_rq_unmap_user(bio);
> 



More information about the Linux-nvme mailing list