@@ -600,6 +600,40 @@ int nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd,
600
600
}
601
601
EXPORT_SYMBOL_GPL (nvme_submit_sync_cmd );
602
602
603
+ static void * nvme_add_user_metadata (struct bio * bio , void __user * ubuf ,
604
+ unsigned len , u32 seed , bool write )
605
+ {
606
+ struct bio_integrity_payload * bip ;
607
+ int ret = - ENOMEM ;
608
+ void * buf ;
609
+
610
+ buf = kmalloc (len , GFP_KERNEL );
611
+ if (!buf )
612
+ goto out ;
613
+
614
+ ret = - EFAULT ;
615
+ if (write && copy_from_user (buf , ubuf , len ))
616
+ goto out_free_meta ;
617
+
618
+ bip = bio_integrity_alloc (bio , GFP_KERNEL , 1 );
619
+ if (IS_ERR (bip )) {
620
+ ret = PTR_ERR (bip );
621
+ goto out_free_meta ;
622
+ }
623
+
624
+ bip -> bip_iter .bi_size = len ;
625
+ bip -> bip_iter .bi_sector = seed ;
626
+ ret = bio_integrity_add_page (bio , virt_to_page (buf ), len ,
627
+ offset_in_page (buf ));
628
+ if (ret == len )
629
+ return buf ;
630
+ ret = - ENOMEM ;
631
+ out_free_meta :
632
+ kfree (buf );
633
+ out :
634
+ return ERR_PTR (ret );
635
+ }
636
+
603
637
int __nvme_submit_user_cmd (struct request_queue * q , struct nvme_command * cmd ,
604
638
void __user * ubuffer , unsigned bufflen ,
605
639
void __user * meta_buffer , unsigned meta_len , u32 meta_seed ,
@@ -625,46 +659,17 @@ int __nvme_submit_user_cmd(struct request_queue *q, struct nvme_command *cmd,
625
659
if (ret )
626
660
goto out ;
627
661
bio = req -> bio ;
628
-
629
- if (!disk )
630
- goto submit ;
631
662
bio -> bi_disk = disk ;
632
-
633
- if (meta_buffer && meta_len ) {
634
- struct bio_integrity_payload * bip ;
635
-
636
- meta = kmalloc (meta_len , GFP_KERNEL );
637
- if (!meta ) {
638
- ret = - ENOMEM ;
663
+ if (disk && meta_buffer && meta_len ) {
664
+ meta = nvme_add_user_metadata (bio , meta_buffer , meta_len ,
665
+ meta_seed , write );
666
+ if (IS_ERR (meta )) {
667
+ ret = PTR_ERR (meta );
639
668
goto out_unmap ;
640
669
}
641
-
642
- if (write ) {
643
- if (copy_from_user (meta , meta_buffer ,
644
- meta_len )) {
645
- ret = - EFAULT ;
646
- goto out_free_meta ;
647
- }
648
- }
649
-
650
- bip = bio_integrity_alloc (bio , GFP_KERNEL , 1 );
651
- if (IS_ERR (bip )) {
652
- ret = PTR_ERR (bip );
653
- goto out_free_meta ;
654
- }
655
-
656
- bip -> bip_iter .bi_size = meta_len ;
657
- bip -> bip_iter .bi_sector = meta_seed ;
658
-
659
- ret = bio_integrity_add_page (bio , virt_to_page (meta ),
660
- meta_len , offset_in_page (meta ));
661
- if (ret != meta_len ) {
662
- ret = - ENOMEM ;
663
- goto out_free_meta ;
664
- }
665
670
}
666
671
}
667
- submit :
672
+
668
673
blk_execute_rq (req -> q , disk , req , 0 );
669
674
if (nvme_req (req )-> flags & NVME_REQ_CANCELLED )
670
675
ret = - EINTR ;
@@ -676,7 +681,6 @@ int __nvme_submit_user_cmd(struct request_queue *q, struct nvme_command *cmd,
676
681
if (copy_to_user (meta_buffer , meta , meta_len ))
677
682
ret = - EFAULT ;
678
683
}
679
- out_free_meta :
680
684
kfree (meta );
681
685
out_unmap :
682
686
if (bio )
0 commit comments