@@ -519,13 +519,253 @@ static void __init iov_kunit_copy_from_xarray(struct kunit *test)
519519 KUNIT_SUCCEED ();
520520}
521521
522+ /*
523+ * Test the extraction of ITER_KVEC-type iterators.
524+ */
525+ static void __init iov_kunit_extract_pages_kvec (struct kunit * test )
526+ {
527+ const struct kvec_test_range * pr ;
528+ struct iov_iter iter ;
529+ struct page * * bpages , * pagelist [8 ], * * pages = pagelist ;
530+ struct kvec kvec [8 ];
531+ u8 * buffer ;
532+ ssize_t len ;
533+ size_t bufsize , size = 0 , npages ;
534+ int i , from ;
535+
536+ bufsize = 0x100000 ;
537+ npages = bufsize / PAGE_SIZE ;
538+
539+ buffer = iov_kunit_create_buffer (test , & bpages , npages );
540+
541+ iov_kunit_load_kvec (test , & iter , READ , kvec , ARRAY_SIZE (kvec ),
542+ buffer , bufsize , kvec_test_ranges );
543+ size = iter .count ;
544+
545+ pr = kvec_test_ranges ;
546+ from = pr -> from ;
547+ do {
548+ size_t offset0 = LONG_MAX ;
549+
550+ for (i = 0 ; i < ARRAY_SIZE (pagelist ); i ++ )
551+ pagelist [i ] = (void * )(unsigned long )0xaa55aa55aa55aa55ULL ;
552+
553+ len = iov_iter_extract_pages (& iter , & pages , 100 * 1024 ,
554+ ARRAY_SIZE (pagelist ), 0 , & offset0 );
555+ KUNIT_EXPECT_GE (test , len , 0 );
556+ if (len < 0 )
557+ break ;
558+ KUNIT_EXPECT_GE (test , (ssize_t )offset0 , 0 );
559+ KUNIT_EXPECT_LT (test , offset0 , PAGE_SIZE );
560+ KUNIT_EXPECT_LE (test , len , size );
561+ KUNIT_EXPECT_EQ (test , iter .count , size - len );
562+ size -= len ;
563+
564+ if (len == 0 )
565+ break ;
566+
567+ for (i = 0 ; i < ARRAY_SIZE (pagelist ); i ++ ) {
568+ struct page * p ;
569+ ssize_t part = min_t (ssize_t , len , PAGE_SIZE - offset0 );
570+ int ix ;
571+
572+ KUNIT_ASSERT_GE (test , part , 0 );
573+ while (from == pr -> to ) {
574+ pr ++ ;
575+ from = pr -> from ;
576+ if (from < 0 )
577+ goto stop ;
578+ }
579+ ix = from / PAGE_SIZE ;
580+ KUNIT_ASSERT_LT (test , ix , npages );
581+ p = bpages [ix ];
582+ KUNIT_EXPECT_PTR_EQ (test , pagelist [i ], p );
583+ KUNIT_EXPECT_EQ (test , offset0 , from % PAGE_SIZE );
584+ from += part ;
585+ len -= part ;
586+ KUNIT_ASSERT_GE (test , len , 0 );
587+ if (len == 0 )
588+ break ;
589+ offset0 = 0 ;
590+ }
591+
592+ if (test -> status == KUNIT_FAILURE )
593+ break ;
594+ } while (iov_iter_count (& iter ) > 0 );
595+
596+ stop :
597+ KUNIT_EXPECT_EQ (test , size , 0 );
598+ KUNIT_EXPECT_EQ (test , iter .count , 0 );
599+ KUNIT_SUCCEED ();
600+ }
601+
602+ /*
603+ * Test the extraction of ITER_BVEC-type iterators.
604+ */
605+ static void __init iov_kunit_extract_pages_bvec (struct kunit * test )
606+ {
607+ const struct bvec_test_range * pr ;
608+ struct iov_iter iter ;
609+ struct page * * bpages , * pagelist [8 ], * * pages = pagelist ;
610+ struct bio_vec bvec [8 ];
611+ ssize_t len ;
612+ size_t bufsize , size = 0 , npages ;
613+ int i , from ;
614+
615+ bufsize = 0x100000 ;
616+ npages = bufsize / PAGE_SIZE ;
617+
618+ iov_kunit_create_buffer (test , & bpages , npages );
619+ iov_kunit_load_bvec (test , & iter , READ , bvec , ARRAY_SIZE (bvec ),
620+ bpages , npages , bufsize , bvec_test_ranges );
621+ size = iter .count ;
622+
623+ pr = bvec_test_ranges ;
624+ from = pr -> from ;
625+ do {
626+ size_t offset0 = LONG_MAX ;
627+
628+ for (i = 0 ; i < ARRAY_SIZE (pagelist ); i ++ )
629+ pagelist [i ] = (void * )(unsigned long )0xaa55aa55aa55aa55ULL ;
630+
631+ len = iov_iter_extract_pages (& iter , & pages , 100 * 1024 ,
632+ ARRAY_SIZE (pagelist ), 0 , & offset0 );
633+ KUNIT_EXPECT_GE (test , len , 0 );
634+ if (len < 0 )
635+ break ;
636+ KUNIT_EXPECT_GE (test , (ssize_t )offset0 , 0 );
637+ KUNIT_EXPECT_LT (test , offset0 , PAGE_SIZE );
638+ KUNIT_EXPECT_LE (test , len , size );
639+ KUNIT_EXPECT_EQ (test , iter .count , size - len );
640+ size -= len ;
641+
642+ if (len == 0 )
643+ break ;
644+
645+ for (i = 0 ; i < ARRAY_SIZE (pagelist ); i ++ ) {
646+ struct page * p ;
647+ ssize_t part = min_t (ssize_t , len , PAGE_SIZE - offset0 );
648+ int ix ;
649+
650+ KUNIT_ASSERT_GE (test , part , 0 );
651+ while (from == pr -> to ) {
652+ pr ++ ;
653+ from = pr -> from ;
654+ if (from < 0 )
655+ goto stop ;
656+ }
657+ ix = pr -> page + from / PAGE_SIZE ;
658+ KUNIT_ASSERT_LT (test , ix , npages );
659+ p = bpages [ix ];
660+ KUNIT_EXPECT_PTR_EQ (test , pagelist [i ], p );
661+ KUNIT_EXPECT_EQ (test , offset0 , from % PAGE_SIZE );
662+ from += part ;
663+ len -= part ;
664+ KUNIT_ASSERT_GE (test , len , 0 );
665+ if (len == 0 )
666+ break ;
667+ offset0 = 0 ;
668+ }
669+
670+ if (test -> status == KUNIT_FAILURE )
671+ break ;
672+ } while (iov_iter_count (& iter ) > 0 );
673+
674+ stop :
675+ KUNIT_EXPECT_EQ (test , size , 0 );
676+ KUNIT_EXPECT_EQ (test , iter .count , 0 );
677+ KUNIT_SUCCEED ();
678+ }
679+
680+ /*
681+ * Test the extraction of ITER_XARRAY-type iterators.
682+ */
683+ static void __init iov_kunit_extract_pages_xarray (struct kunit * test )
684+ {
685+ const struct kvec_test_range * pr ;
686+ struct iov_iter iter ;
687+ struct xarray * xarray ;
688+ struct page * * bpages , * pagelist [8 ], * * pages = pagelist ;
689+ ssize_t len ;
690+ size_t bufsize , size = 0 , npages ;
691+ int i , from ;
692+
693+ bufsize = 0x100000 ;
694+ npages = bufsize / PAGE_SIZE ;
695+
696+ xarray = iov_kunit_create_xarray (test );
697+
698+ iov_kunit_create_buffer (test , & bpages , npages );
699+ iov_kunit_load_xarray (test , & iter , READ , xarray , bpages , npages );
700+
701+ for (pr = kvec_test_ranges ; pr -> from >= 0 ; pr ++ ) {
702+ from = pr -> from ;
703+ size = pr -> to - from ;
704+ KUNIT_ASSERT_LE (test , pr -> to , bufsize );
705+
706+ iov_iter_xarray (& iter , WRITE , xarray , from , size );
707+
708+ do {
709+ size_t offset0 = LONG_MAX ;
710+
711+ for (i = 0 ; i < ARRAY_SIZE (pagelist ); i ++ )
712+ pagelist [i ] = (void * )(unsigned long )0xaa55aa55aa55aa55ULL ;
713+
714+ len = iov_iter_extract_pages (& iter , & pages , 100 * 1024 ,
715+ ARRAY_SIZE (pagelist ), 0 , & offset0 );
716+ KUNIT_EXPECT_GE (test , len , 0 );
717+ if (len < 0 )
718+ break ;
719+ KUNIT_EXPECT_LE (test , len , size );
720+ KUNIT_EXPECT_EQ (test , iter .count , size - len );
721+ if (len == 0 )
722+ break ;
723+ size -= len ;
724+ KUNIT_EXPECT_GE (test , (ssize_t )offset0 , 0 );
725+ KUNIT_EXPECT_LT (test , offset0 , PAGE_SIZE );
726+
727+ for (i = 0 ; i < ARRAY_SIZE (pagelist ); i ++ ) {
728+ struct page * p ;
729+ ssize_t part = min_t (ssize_t , len , PAGE_SIZE - offset0 );
730+ int ix ;
731+
732+ KUNIT_ASSERT_GE (test , part , 0 );
733+ ix = from / PAGE_SIZE ;
734+ KUNIT_ASSERT_LT (test , ix , npages );
735+ p = bpages [ix ];
736+ KUNIT_EXPECT_PTR_EQ (test , pagelist [i ], p );
737+ KUNIT_EXPECT_EQ (test , offset0 , from % PAGE_SIZE );
738+ from += part ;
739+ len -= part ;
740+ KUNIT_ASSERT_GE (test , len , 0 );
741+ if (len == 0 )
742+ break ;
743+ offset0 = 0 ;
744+ }
745+
746+ if (test -> status == KUNIT_FAILURE )
747+ goto stop ;
748+ } while (iov_iter_count (& iter ) > 0 );
749+
750+ KUNIT_EXPECT_EQ (test , size , 0 );
751+ KUNIT_EXPECT_EQ (test , iter .count , 0 );
752+ KUNIT_EXPECT_EQ (test , iter .iov_offset , pr -> to - pr -> from );
753+ }
754+
755+ stop :
756+ KUNIT_SUCCEED ();
757+ }
758+
522759static struct kunit_case __refdata iov_kunit_cases [] = {
523760 KUNIT_CASE (iov_kunit_copy_to_kvec ),
524761 KUNIT_CASE (iov_kunit_copy_from_kvec ),
525762 KUNIT_CASE (iov_kunit_copy_to_bvec ),
526763 KUNIT_CASE (iov_kunit_copy_from_bvec ),
527764 KUNIT_CASE (iov_kunit_copy_to_xarray ),
528765 KUNIT_CASE (iov_kunit_copy_from_xarray ),
766+ KUNIT_CASE (iov_kunit_extract_pages_kvec ),
767+ KUNIT_CASE (iov_kunit_extract_pages_bvec ),
768+ KUNIT_CASE (iov_kunit_extract_pages_xarray ),
529769 {}
530770};
531771
0 commit comments