@@ -127,7 +127,7 @@ static u32 nvmet_max_nsid(struct nvmet_subsys *subsys)
127
127
unsigned long idx ;
128
128
u32 nsid = 0 ;
129
129
130
- xa_for_each (& subsys -> namespaces , idx , cur )
130
+ nvmet_for_each_enabled_ns (& subsys -> namespaces , idx , cur )
131
131
nsid = cur -> nsid ;
132
132
133
133
return nsid ;
@@ -441,11 +441,14 @@ u16 nvmet_req_find_ns(struct nvmet_req *req)
441
441
struct nvmet_subsys * subsys = nvmet_req_subsys (req );
442
442
443
443
req -> ns = xa_load (& subsys -> namespaces , nsid );
444
- if (unlikely (!req -> ns )) {
444
+ if (unlikely (!req -> ns || ! req -> ns -> enabled )) {
445
445
req -> error_loc = offsetof(struct nvme_common_command , nsid );
446
- if (nvmet_subsys_nsid_exists (subsys , nsid ))
447
- return NVME_SC_INTERNAL_PATH_ERROR ;
448
- return NVME_SC_INVALID_NS | NVME_STATUS_DNR ;
446
+ if (!req -> ns ) /* ns doesn't exist! */
447
+ return NVME_SC_INVALID_NS | NVME_STATUS_DNR ;
448
+
449
+ /* ns exists but it's disabled */
450
+ req -> ns = NULL ;
451
+ return NVME_SC_INTERNAL_PATH_ERROR ;
449
452
}
450
453
451
454
percpu_ref_get (& req -> ns -> ref );
@@ -583,8 +586,6 @@ int nvmet_ns_enable(struct nvmet_ns *ns)
583
586
goto out_unlock ;
584
587
585
588
ret = - EMFILE ;
586
- if (subsys -> nr_namespaces == NVMET_MAX_NAMESPACES )
587
- goto out_unlock ;
588
589
589
590
ret = nvmet_bdev_ns_enable (ns );
590
591
if (ret == - ENOTBLK )
@@ -599,38 +600,19 @@ int nvmet_ns_enable(struct nvmet_ns *ns)
599
600
list_for_each_entry (ctrl , & subsys -> ctrls , subsys_entry )
600
601
nvmet_p2pmem_ns_add_p2p (ctrl , ns );
601
602
602
- ret = percpu_ref_init (& ns -> ref , nvmet_destroy_namespace ,
603
- 0 , GFP_KERNEL );
604
- if (ret )
605
- goto out_dev_put ;
606
-
607
- if (ns -> nsid > subsys -> max_nsid )
608
- subsys -> max_nsid = ns -> nsid ;
609
-
610
- ret = xa_insert (& subsys -> namespaces , ns -> nsid , ns , GFP_KERNEL );
611
- if (ret )
612
- goto out_restore_subsys_maxnsid ;
613
-
614
603
if (ns -> pr .enable ) {
615
604
ret = nvmet_pr_init_ns (ns );
616
605
if (ret )
617
- goto out_remove_from_subsys ;
606
+ goto out_dev_put ;
618
607
}
619
608
620
- subsys -> nr_namespaces ++ ;
621
-
622
609
nvmet_ns_changed (subsys , ns -> nsid );
623
610
ns -> enabled = true;
611
+ xa_set_mark (& subsys -> namespaces , ns -> nsid , NVMET_NS_ENABLED );
624
612
ret = 0 ;
625
613
out_unlock :
626
614
mutex_unlock (& subsys -> lock );
627
615
return ret ;
628
-
629
- out_remove_from_subsys :
630
- xa_erase (& subsys -> namespaces , ns -> nsid );
631
- out_restore_subsys_maxnsid :
632
- subsys -> max_nsid = nvmet_max_nsid (subsys );
633
- percpu_ref_exit (& ns -> ref );
634
616
out_dev_put :
635
617
list_for_each_entry (ctrl , & subsys -> ctrls , subsys_entry )
636
618
pci_dev_put (radix_tree_delete (& ctrl -> p2p_ns_map , ns -> nsid ));
@@ -649,15 +631,37 @@ void nvmet_ns_disable(struct nvmet_ns *ns)
649
631
goto out_unlock ;
650
632
651
633
ns -> enabled = false;
652
- xa_erase (& ns -> subsys -> namespaces , ns -> nsid );
653
- if (ns -> nsid == subsys -> max_nsid )
654
- subsys -> max_nsid = nvmet_max_nsid (subsys );
634
+ xa_clear_mark (& subsys -> namespaces , ns -> nsid , NVMET_NS_ENABLED );
655
635
656
636
list_for_each_entry (ctrl , & subsys -> ctrls , subsys_entry )
657
637
pci_dev_put (radix_tree_delete (& ctrl -> p2p_ns_map , ns -> nsid ));
658
638
659
639
mutex_unlock (& subsys -> lock );
660
640
641
+ if (ns -> pr .enable )
642
+ nvmet_pr_exit_ns (ns );
643
+
644
+ mutex_lock (& subsys -> lock );
645
+ nvmet_ns_changed (subsys , ns -> nsid );
646
+ nvmet_ns_dev_disable (ns );
647
+ out_unlock :
648
+ mutex_unlock (& subsys -> lock );
649
+ }
650
+
651
+ void nvmet_ns_free (struct nvmet_ns * ns )
652
+ {
653
+ struct nvmet_subsys * subsys = ns -> subsys ;
654
+
655
+ nvmet_ns_disable (ns );
656
+
657
+ mutex_lock (& subsys -> lock );
658
+
659
+ xa_erase (& subsys -> namespaces , ns -> nsid );
660
+ if (ns -> nsid == subsys -> max_nsid )
661
+ subsys -> max_nsid = nvmet_max_nsid (subsys );
662
+
663
+ mutex_unlock (& subsys -> lock );
664
+
661
665
/*
662
666
* Now that we removed the namespaces from the lookup list, we
663
667
* can kill the per_cpu ref and wait for any remaining references
@@ -671,21 +675,9 @@ void nvmet_ns_disable(struct nvmet_ns *ns)
671
675
wait_for_completion (& ns -> disable_done );
672
676
percpu_ref_exit (& ns -> ref );
673
677
674
- if (ns -> pr .enable )
675
- nvmet_pr_exit_ns (ns );
676
-
677
678
mutex_lock (& subsys -> lock );
678
-
679
679
subsys -> nr_namespaces -- ;
680
- nvmet_ns_changed (subsys , ns -> nsid );
681
- nvmet_ns_dev_disable (ns );
682
- out_unlock :
683
680
mutex_unlock (& subsys -> lock );
684
- }
685
-
686
- void nvmet_ns_free (struct nvmet_ns * ns )
687
- {
688
- nvmet_ns_disable (ns );
689
681
690
682
down_write (& nvmet_ana_sem );
691
683
nvmet_ana_group_enabled [ns -> anagrpid ]-- ;
@@ -699,15 +691,33 @@ struct nvmet_ns *nvmet_ns_alloc(struct nvmet_subsys *subsys, u32 nsid)
699
691
{
700
692
struct nvmet_ns * ns ;
701
693
694
+ mutex_lock (& subsys -> lock );
695
+
696
+ if (subsys -> nr_namespaces == NVMET_MAX_NAMESPACES )
697
+ goto out_unlock ;
698
+
702
699
ns = kzalloc (sizeof (* ns ), GFP_KERNEL );
703
700
if (!ns )
704
- return NULL ;
701
+ goto out_unlock ;
705
702
706
703
init_completion (& ns -> disable_done );
707
704
708
705
ns -> nsid = nsid ;
709
706
ns -> subsys = subsys ;
710
707
708
+ if (percpu_ref_init (& ns -> ref , nvmet_destroy_namespace , 0 , GFP_KERNEL ))
709
+ goto out_free ;
710
+
711
+ if (ns -> nsid > subsys -> max_nsid )
712
+ subsys -> max_nsid = nsid ;
713
+
714
+ if (xa_insert (& subsys -> namespaces , ns -> nsid , ns , GFP_KERNEL ))
715
+ goto out_exit ;
716
+
717
+ subsys -> nr_namespaces ++ ;
718
+
719
+ mutex_unlock (& subsys -> lock );
720
+
711
721
down_write (& nvmet_ana_sem );
712
722
ns -> anagrpid = NVMET_DEFAULT_ANA_GRPID ;
713
723
nvmet_ana_group_enabled [ns -> anagrpid ]++ ;
@@ -718,6 +728,14 @@ struct nvmet_ns *nvmet_ns_alloc(struct nvmet_subsys *subsys, u32 nsid)
718
728
ns -> csi = NVME_CSI_NVM ;
719
729
720
730
return ns ;
731
+ out_exit :
732
+ subsys -> max_nsid = nvmet_max_nsid (subsys );
733
+ percpu_ref_exit (& ns -> ref );
734
+ out_free :
735
+ kfree (ns );
736
+ out_unlock :
737
+ mutex_unlock (& subsys -> lock );
738
+ return NULL ;
721
739
}
722
740
723
741
static void nvmet_update_sq_head (struct nvmet_req * req )
@@ -1394,7 +1412,7 @@ static void nvmet_setup_p2p_ns_map(struct nvmet_ctrl *ctrl,
1394
1412
1395
1413
ctrl -> p2p_client = get_device (req -> p2p_client );
1396
1414
1397
- xa_for_each (& ctrl -> subsys -> namespaces , idx , ns )
1415
+ nvmet_for_each_enabled_ns (& ctrl -> subsys -> namespaces , idx , ns )
1398
1416
nvmet_p2pmem_ns_add_p2p (ctrl , ns );
1399
1417
}
1400
1418
0 commit comments