@@ -950,100 +950,97 @@ static int z_erofs_read_fragment(struct super_block *sb, struct folio *folio,
950950 return 0 ;
951951}
952952
953- static int z_erofs_scan_folio (struct z_erofs_decompress_frontend * fe ,
953+ static int z_erofs_scan_folio (struct z_erofs_decompress_frontend * f ,
954954 struct folio * folio , bool ra )
955955{
956- struct inode * const inode = fe -> inode ;
957- struct erofs_map_blocks * const map = & fe -> map ;
956+ struct inode * const inode = f -> inode ;
957+ struct erofs_map_blocks * const map = & f -> map ;
958958 const loff_t offset = folio_pos (folio );
959- const unsigned int bs = i_blocksize (inode ), fs = folio_size ( folio ) ;
960- bool tight = true, exclusive ;
961- unsigned int cur , end , split ;
962- int err = 0 ;
959+ const unsigned int bs = i_blocksize (inode );
960+ unsigned int end = folio_size ( folio ), split = 0 , cur , pgs ;
961+ bool tight , excl ;
962+ int err ;
963963
964+ tight = (bs == PAGE_SIZE );
964965 z_erofs_onlinefolio_init (folio );
965- split = 0 ;
966- end = fs ;
967- repeat :
968- if (offset + end - 1 < map -> m_la ||
969- offset + end - 1 >= map -> m_la + map -> m_llen ) {
970- z_erofs_pcluster_end (fe );
971- map -> m_la = offset + end - 1 ;
972- map -> m_llen = 0 ;
973- err = z_erofs_map_blocks_iter (inode , map , 0 );
974- if (err )
975- goto out ;
976- }
977-
978- cur = offset > map -> m_la ? 0 : map -> m_la - offset ;
979- /* bump split parts first to avoid several separate cases */
980- ++ split ;
981-
982- if (!(map -> m_flags & EROFS_MAP_MAPPED )) {
983- folio_zero_segment (folio , cur , end );
984- tight = false;
985- goto next_part ;
986- }
987-
988- if (map -> m_flags & EROFS_MAP_FRAGMENT ) {
989- erofs_off_t fpos = offset + cur - map -> m_la ;
966+ do {
967+ if (offset + end - 1 < map -> m_la ||
968+ offset + end - 1 >= map -> m_la + map -> m_llen ) {
969+ z_erofs_pcluster_end (f );
970+ map -> m_la = offset + end - 1 ;
971+ map -> m_llen = 0 ;
972+ err = z_erofs_map_blocks_iter (inode , map , 0 );
973+ if (err )
974+ break ;
975+ }
990976
991- err = z_erofs_read_fragment (inode -> i_sb , folio , cur ,
992- cur + min (map -> m_llen - fpos , end - cur ),
993- EROFS_I (inode )-> z_fragmentoff + fpos );
994- if (err )
995- goto out ;
996- tight = false;
997- goto next_part ;
998- }
977+ cur = offset > map -> m_la ? 0 : map -> m_la - offset ;
978+ pgs = round_down (cur , PAGE_SIZE );
979+ /* bump split parts first to avoid several separate cases */
980+ ++ split ;
981+
982+ if (!(map -> m_flags & EROFS_MAP_MAPPED )) {
983+ folio_zero_segment (folio , cur , end );
984+ tight = false;
985+ } else if (map -> m_flags & EROFS_MAP_FRAGMENT ) {
986+ erofs_off_t fpos = offset + cur - map -> m_la ;
987+
988+ err = z_erofs_read_fragment (inode -> i_sb , folio , cur ,
989+ cur + min (map -> m_llen - fpos , end - cur ),
990+ EROFS_I (inode )-> z_fragmentoff + fpos );
991+ if (err )
992+ break ;
993+ tight = false;
994+ } else {
995+ if (!f -> pcl ) {
996+ err = z_erofs_pcluster_begin (f );
997+ if (err )
998+ break ;
999+ f -> pcl -> besteffort |= !ra ;
1000+ }
9991001
1000- if (!fe -> pcl ) {
1001- err = z_erofs_pcluster_begin (fe );
1002- if (err )
1003- goto out ;
1004- fe -> pcl -> besteffort |= !ra ;
1005- }
1002+ pgs = round_down (end - 1 , PAGE_SIZE );
1003+ /*
1004+ * Ensure this partial page belongs to this submit chain
1005+ * rather than other concurrent submit chains or
1006+ * noio(bypass) chains since those chains are handled
1007+ * asynchronously thus it cannot be used for inplace I/O
1008+ * or bvpage (should be processed in the strict order.)
1009+ */
1010+ tight &= (f -> mode >= Z_EROFS_PCLUSTER_FOLLOWED );
1011+ excl = false;
1012+ if (cur <= pgs ) {
1013+ excl = (split <= 1 ) || tight ;
1014+ cur = pgs ;
1015+ }
10061016
1007- /*
1008- * Ensure the current partial folio belongs to this submit chain rather
1009- * than other concurrent submit chains or the noio(bypass) chain since
1010- * those chains are handled asynchronously thus the folio cannot be used
1011- * for inplace I/O or bvpage (should be processed in a strict order.)
1012- */
1013- tight &= (fe -> mode > Z_EROFS_PCLUSTER_FOLLOWED_NOINPLACE );
1014- exclusive = (!cur && ((split <= 1 ) || (tight && bs == fs )));
1015- if (cur )
1016- tight &= (fe -> mode >= Z_EROFS_PCLUSTER_FOLLOWED );
1017-
1018- err = z_erofs_attach_page (fe , & ((struct z_erofs_bvec ) {
1019- .page = & folio -> page ,
1020- .offset = offset - map -> m_la ,
1021- .end = end ,
1022- }), exclusive );
1023- if (err )
1024- goto out ;
1025-
1026- z_erofs_onlinefolio_split (folio );
1027- if (fe -> pcl -> pageofs_out != (map -> m_la & ~PAGE_MASK ))
1028- fe -> pcl -> multibases = true;
1029- if (fe -> pcl -> length < offset + end - map -> m_la ) {
1030- fe -> pcl -> length = offset + end - map -> m_la ;
1031- fe -> pcl -> pageofs_out = map -> m_la & ~PAGE_MASK ;
1032- }
1033- if ((map -> m_flags & EROFS_MAP_FULL_MAPPED ) &&
1034- !(map -> m_flags & EROFS_MAP_PARTIAL_REF ) &&
1035- fe -> pcl -> length == map -> m_llen )
1036- fe -> pcl -> partial = false;
1037- next_part :
1038- /* shorten the remaining extent to update progress */
1039- map -> m_llen = offset + cur - map -> m_la ;
1040- map -> m_flags &= ~EROFS_MAP_FULL_MAPPED ;
1041-
1042- end = cur ;
1043- if (end > 0 )
1044- goto repeat ;
1017+ err = z_erofs_attach_page (f , & ((struct z_erofs_bvec ) {
1018+ .page = folio_page (folio , pgs >> PAGE_SHIFT ),
1019+ .offset = offset + pgs - map -> m_la ,
1020+ .end = end - pgs , }), excl );
1021+ if (err )
1022+ break ;
10451023
1046- out :
1024+ z_erofs_onlinefolio_split (folio );
1025+ if (f -> pcl -> pageofs_out != (map -> m_la & ~PAGE_MASK ))
1026+ f -> pcl -> multibases = true;
1027+ if (f -> pcl -> length < offset + end - map -> m_la ) {
1028+ f -> pcl -> length = offset + end - map -> m_la ;
1029+ f -> pcl -> pageofs_out = map -> m_la & ~PAGE_MASK ;
1030+ }
1031+ if ((map -> m_flags & EROFS_MAP_FULL_MAPPED ) &&
1032+ !(map -> m_flags & EROFS_MAP_PARTIAL_REF ) &&
1033+ f -> pcl -> length == map -> m_llen )
1034+ f -> pcl -> partial = false;
1035+ }
1036+ /* shorten the remaining extent to update progress */
1037+ map -> m_llen = offset + cur - map -> m_la ;
1038+ map -> m_flags &= ~EROFS_MAP_FULL_MAPPED ;
1039+ if (cur <= pgs ) {
1040+ split = cur < pgs ;
1041+ tight = (bs == PAGE_SIZE );
1042+ }
1043+ } while ((end = cur ) > 0 );
10471044 z_erofs_onlinefolio_end (folio , err );
10481045 return err ;
10491046}
0 commit comments