99
99
#include <geom/geom.h>
100
100
#include <sys/zvol.h>
101
101
#include <sys/zvol_impl.h>
102
+ #include <cityhash.h>
102
103
103
104
#include "zfs_namecheck.h"
104
105
@@ -169,7 +170,7 @@ static d_close_t zvol_cdev_close;
169
170
static d_ioctl_t zvol_cdev_ioctl ;
170
171
static d_read_t zvol_cdev_read ;
171
172
static d_write_t zvol_cdev_write ;
172
- static d_strategy_t zvol_geom_bio_strategy ;
173
+ static d_strategy_t zvol_bio_strategy ;
173
174
static d_kqfilter_t zvol_cdev_kqfilter ;
174
175
175
176
static struct cdevsw zvol_cdevsw = {
@@ -181,7 +182,7 @@ static struct cdevsw zvol_cdevsw = {
181
182
.d_ioctl = zvol_cdev_ioctl ,
182
183
.d_read = zvol_cdev_read ,
183
184
.d_write = zvol_cdev_write ,
184
- .d_strategy = zvol_geom_bio_strategy ,
185
+ .d_strategy = zvol_bio_strategy ,
185
186
.d_kqfilter = zvol_cdev_kqfilter ,
186
187
};
187
188
@@ -211,7 +212,8 @@ static int zvol_geom_access(struct g_provider *pp, int acr, int acw, int ace);
211
212
static void zvol_geom_worker (void * arg );
212
213
static void zvol_geom_bio_start (struct bio * bp );
213
214
static int zvol_geom_bio_getattr (struct bio * bp );
214
- /* static d_strategy_t zvol_geom_bio_strategy; (declared elsewhere) */
215
+ /* static d_strategy_t zvol_bio_strategy; (declared elsewhere) */
216
+ static void zvol_geom_bio_strategy (struct bio * bp , boolean_t sync );
215
217
216
218
/*
217
219
* GEOM mode implementation
@@ -544,7 +546,7 @@ zvol_geom_worker(void *arg)
544
546
continue ;
545
547
}
546
548
mtx_unlock (& zsg -> zsg_queue_mtx );
547
- zvol_geom_bio_strategy (bp );
549
+ zvol_geom_bio_strategy (bp , B_FALSE );
548
550
}
549
551
}
550
552
@@ -576,7 +578,7 @@ zvol_geom_bio_start(struct bio *bp)
576
578
return ;
577
579
}
578
580
579
- zvol_geom_bio_strategy (bp );
581
+ zvol_geom_bio_strategy (bp , B_TRUE );
580
582
}
581
583
582
584
static int
@@ -660,9 +662,10 @@ zvol_cdev_kqfilter(struct cdev *dev, struct knote *kn)
660
662
}
661
663
662
664
static void
663
- zvol_geom_bio_strategy ( struct bio * bp )
665
+ zvol_strategy_impl ( zv_request_t * zvr )
664
666
{
665
667
zvol_state_t * zv ;
668
+ struct bio * bp ;
666
669
uint64_t off , volsize ;
667
670
size_t resid ;
668
671
char * addr ;
@@ -673,11 +676,8 @@ zvol_geom_bio_strategy(struct bio *bp)
673
676
boolean_t is_dumpified ;
674
677
boolean_t commit ;
675
678
676
- if (bp -> bio_to )
677
- zv = bp -> bio_to -> private ;
678
- else
679
- zv = bp -> bio_dev -> si_drv2 ;
680
-
679
+ bp = zvr -> bio ;
680
+ zv = zvr -> zv ;
681
681
if (zv == NULL ) {
682
682
error = SET_ERROR (ENXIO );
683
683
goto out ;
@@ -813,6 +813,64 @@ zvol_geom_bio_strategy(struct bio *bp)
813
813
biofinish (bp , NULL , error );
814
814
}
815
815
816
+ static void
817
+ zvol_strategy_task (void * arg )
818
+ {
819
+ zv_request_task_t * task = arg ;
820
+
821
+ zvol_strategy_impl (& task -> zvr );
822
+ zv_request_task_free (task );
823
+ }
824
+
825
+ static void
826
+ zvol_geom_bio_strategy (struct bio * bp , boolean_t sync )
827
+ {
828
+ zv_taskq_t * ztqs = & zvol_taskqs ;
829
+ zv_request_task_t * task ;
830
+ zvol_state_t * zv ;
831
+ uint64_t taskq_hash ;
832
+ uint32_t tq_idx ;
833
+ int error ;
834
+
835
+ if (bp -> bio_to )
836
+ zv = bp -> bio_to -> private ;
837
+ else
838
+ zv = bp -> bio_dev -> si_drv2 ;
839
+
840
+ if (zv == NULL ) {
841
+ error = SET_ERROR (ENXIO );
842
+ if (bp -> bio_to )
843
+ g_io_deliver (bp , error );
844
+ else
845
+ biofinish (bp , NULL , error );
846
+
847
+ return ;
848
+ }
849
+
850
+ zv_request_t zvr = {
851
+ .zv = zv ,
852
+ .bio = bp ,
853
+ };
854
+
855
+ if (sync || zvol_request_sync ) {
856
+ zvol_strategy_impl (& zvr );
857
+ return ;
858
+ }
859
+
860
+ taskq_hash = cityhash3 ((uintptr_t )zv , curcpu , bp -> bio_offset >>
861
+ ZVOL_TASKQ_OFFSET_SHIFT );
862
+ tq_idx = taskq_hash % ztqs -> tqs_cnt ;
863
+ task = zv_request_task_create (zvr );
864
+ taskq_dispatch_ent (ztqs -> tqs_taskq [tq_idx ], zvol_strategy_task , task ,
865
+ 0 , & task -> ent );
866
+ }
867
+
868
+ static void
869
+ zvol_bio_strategy (struct bio * bp )
870
+ {
871
+ zvol_geom_bio_strategy (bp , B_FALSE );
872
+ }
873
+
816
874
/*
817
875
* Character device mode implementation
818
876
*/
@@ -1606,8 +1664,7 @@ zvol_busy(void)
1606
1664
int
1607
1665
zvol_init (void )
1608
1666
{
1609
- zvol_init_impl ();
1610
- return (0 );
1667
+ return (zvol_init_impl (mp_ncpus , zvol_num_taskqs , zvol_threads ));
1611
1668
}
1612
1669
1613
1670
void
0 commit comments