@@ -954,11 +954,31 @@ pub fn user_accessible_len(addr: VirtAddr, size: usize, check_write: bool) -> us
954954 break ;
955955 } ;
956956
957- let ( region_end, vm_flags) = {
957+ // 获取地址所在内存页的起始地址 和结束地址,以及访问权限标志 和文件后备长度
958+ let ( region_start, region_end, vm_flags, file_backed_len) = {
958959 let guard = vma. lock_irqsave ( ) ;
960+ let region_start = guard. region ( ) . start ( ) . data ( ) ;
959961 let region_end = guard. region ( ) . end ( ) . data ( ) ;
960962 let vm_flags = * guard. vm_flags ( ) ;
961- ( region_end, vm_flags)
963+ let vma_size = region_end. saturating_sub ( region_start) ;
964+
965+ let file_backed_len = guard. vm_file ( ) . and_then ( |file| {
966+ let file_offset_pages = guard. file_page_offset ( ) . unwrap_or ( 0 ) ;
967+ let file_offset_bytes = file_offset_pages. saturating_mul ( MMArch :: PAGE_SIZE ) ;
968+ let file_size = match file. metadata ( ) {
969+ Ok ( md) if md. size > 0 => {
970+ let capped = core:: cmp:: min ( md. size as u128 , usize:: MAX as u128 ) ;
971+ capped as usize
972+ }
973+ Ok ( _) => 0 ,
974+ Err ( _) => return None ,
975+ } ;
976+
977+ let backed = file_size. saturating_sub ( file_offset_bytes) ;
978+ Some ( core:: cmp:: min ( backed, vma_size) )
979+ } ) ;
980+
981+ ( region_start, region_end, vm_flags, file_backed_len)
962982 } ;
963983
964984 // 根据 vm_flags 判断是否具备访问权限
@@ -973,7 +993,14 @@ pub fn user_accessible_len(addr: VirtAddr, size: usize, check_write: bool) -> us
973993 }
974994
975995 let current_addr = current. data ( ) ;
976- let available = region_end. saturating_sub ( current_addr) ;
996+ let mut available = region_end. saturating_sub ( current_addr) ;
997+
998+ if let Some ( backed_len) = file_backed_len {
999+ let offset_in_vma = current_addr. saturating_sub ( region_start) ;
1000+ let backed_available = backed_len. saturating_sub ( offset_in_vma) ;
1001+ // Clamp to the range actually backed by the file to avoid walking into holes.
1002+ available = min ( available, backed_available) ;
1003+ }
9771004 if available == 0 {
9781005 break ;
9791006 }
0 commit comments