@@ -494,39 +494,73 @@ static int squashfs_read_folio(struct file *file, struct folio *folio)
494494}
495495
496496static int squashfs_readahead_fragment (struct page * * page ,
497- unsigned int pages , unsigned int expected )
497+ unsigned int pages , unsigned int expected , loff_t start )
498498{
499499 struct inode * inode = page [0 ]-> mapping -> host ;
500500 struct squashfs_cache_entry * buffer = squashfs_get_fragment (inode -> i_sb ,
501501 squashfs_i (inode )-> fragment_block ,
502502 squashfs_i (inode )-> fragment_size );
503503 struct squashfs_sb_info * msblk = inode -> i_sb -> s_fs_info ;
504- unsigned int n , mask = (1 << (msblk -> block_log - PAGE_SHIFT )) - 1 ;
505- int error = buffer -> error ;
504+ int i , bytes , copied ;
505+ struct squashfs_page_actor * actor ;
506+ unsigned int offset ;
507+ void * addr ;
508+ struct page * last_page ;
506509
507- if (error )
510+ if (buffer -> error )
508511 goto out ;
509512
510- expected += squashfs_i (inode )-> fragment_offset ;
513+ actor = squashfs_page_actor_init_special (msblk , page , pages ,
514+ expected , start );
515+ if (!actor )
516+ goto out ;
511517
512- for (n = 0 ; n < pages ; n ++ ) {
513- unsigned int base = (page [n ]-> index & mask ) << PAGE_SHIFT ;
514- unsigned int offset = base + squashfs_i (inode )-> fragment_offset ;
518+ squashfs_actor_nobuff (actor );
519+ addr = squashfs_first_page (actor );
515520
516- if (expected > offset ) {
517- unsigned int avail = min_t (unsigned int , expected -
518- offset , PAGE_SIZE );
521+ for (copied = offset = 0 ; offset < expected ; offset += PAGE_SIZE ) {
522+ int avail = min_t (int , expected - offset , PAGE_SIZE );
519523
520- squashfs_fill_page (page [n ], buffer , offset , avail );
524+ if (!IS_ERR (addr )) {
525+ bytes = squashfs_copy_data (addr , buffer , offset +
526+ squashfs_i (inode )-> fragment_offset , avail );
527+
528+ if (bytes != avail )
529+ goto failed ;
521530 }
522531
523- unlock_page ( page [ n ]) ;
524- put_page ( page [ n ] );
532+ copied += avail ;
533+ addr = squashfs_next_page ( actor );
525534 }
526535
536+ last_page = squashfs_page_actor_free (actor );
537+
538+ if (copied == expected ) {
539+ /* Last page (if present) may have trailing bytes not filled */
540+ bytes = copied % PAGE_SIZE ;
541+ if (bytes && last_page )
542+ memzero_page (last_page , bytes , PAGE_SIZE - bytes );
543+
544+ for (i = 0 ; i < pages ; i ++ ) {
545+ flush_dcache_page (page [i ]);
546+ SetPageUptodate (page [i ]);
547+ }
548+ }
549+
550+ for (i = 0 ; i < pages ; i ++ ) {
551+ unlock_page (page [i ]);
552+ put_page (page [i ]);
553+ }
554+
555+ squashfs_cache_put (buffer );
556+ return 0 ;
557+
558+ failed :
559+ squashfs_page_actor_free (actor );
560+
527561out :
528562 squashfs_cache_put (buffer );
529- return error ;
563+ return 1 ;
530564}
531565
532566static void squashfs_readahead (struct readahead_control * ractl )
@@ -572,7 +606,7 @@ static void squashfs_readahead(struct readahead_control *ractl)
572606 if (start >> msblk -> block_log == file_end &&
573607 squashfs_i (inode )-> fragment_block != SQUASHFS_INVALID_BLK ) {
574608 res = squashfs_readahead_fragment (pages , nr_pages ,
575- expected );
609+ expected , start );
576610 if (res )
577611 goto skip_pages ;
578612 continue ;
0 commit comments