@@ -3930,6 +3930,7 @@ zfs_getpages(struct vnode *vp, vm_page_t *ma, int count, int *rbehind,
3930
3930
if (zfs_enter_verify_zp (zfsvfs , zp , FTAG ) != 0 )
3931
3931
return (zfs_vm_pagerret_error );
3932
3932
3933
+ object = ma [0 ]-> object ;
3933
3934
start = IDX_TO_OFF (ma [0 ]-> pindex );
3934
3935
end = IDX_TO_OFF (ma [count - 1 ]-> pindex + 1 );
3935
3936
@@ -3938,33 +3939,47 @@ zfs_getpages(struct vnode *vp, vm_page_t *ma, int count, int *rbehind,
3938
3939
* Note that we need to handle the case of the block size growing.
3939
3940
*/
3940
3941
for (;;) {
3942
+ uint64_t len ;
3943
+
3941
3944
blksz = zp -> z_blksz ;
3945
+ len = roundup (end , blksz ) - rounddown (start , blksz );
3946
+
3942
3947
lr = zfs_rangelock_tryenter (& zp -> z_rangelock ,
3943
- rounddown (start , blksz ),
3944
- roundup (end , blksz ) - rounddown (start , blksz ), RL_READER );
3948
+ rounddown (start , blksz ), len , RL_READER );
3945
3949
if (lr == NULL ) {
3946
- if (rahead != NULL ) {
3947
- * rahead = 0 ;
3948
- rahead = NULL ;
3949
- }
3950
- if (rbehind != NULL ) {
3951
- * rbehind = 0 ;
3952
- rbehind = NULL ;
3950
+ /*
3951
+ * Avoid a deadlock with update_pages(). We need to
3952
+ * hold the range lock when copying from the DMU, so
3953
+ * give up the busy lock to allow update_pages() to
3954
+ * proceed. We might need to allocate new pages, which
3955
+ * isn't quite right since this allocation isn't subject
3956
+ * to the page fault handler's OOM logic, but this is
3957
+ * the best we can do for now.
3958
+ */
3959
+ for (int i = 0 ; i < count ; i ++ ) {
3960
+ ASSERT (vm_page_none_valid (ma [i ]));
3961
+ vm_page_xunbusy (ma [i ]);
3953
3962
}
3954
- break ;
3963
+
3964
+ lr = zfs_rangelock_enter (& zp -> z_rangelock ,
3965
+ rounddown (start , blksz ), len , RL_READER );
3966
+
3967
+ zfs_vmobject_wlock (object );
3968
+ (void ) vm_page_grab_pages (object , OFF_TO_IDX (start ),
3969
+ VM_ALLOC_NORMAL | VM_ALLOC_WAITOK | VM_ALLOC_ZERO ,
3970
+ ma , count );
3971
+ zfs_vmobject_wunlock (object );
3955
3972
}
3956
3973
if (blksz == zp -> z_blksz )
3957
3974
break ;
3958
3975
zfs_rangelock_exit (lr );
3959
3976
}
3960
3977
3961
- object = ma [0 ]-> object ;
3962
3978
zfs_vmobject_wlock (object );
3963
3979
obj_size = object -> un_pager .vnp .vnp_size ;
3964
3980
zfs_vmobject_wunlock (object );
3965
3981
if (IDX_TO_OFF (ma [count - 1 ]-> pindex ) >= obj_size ) {
3966
- if (lr != NULL )
3967
- zfs_rangelock_exit (lr );
3982
+ zfs_rangelock_exit (lr );
3968
3983
zfs_exit (zfsvfs , FTAG );
3969
3984
return (zfs_vm_pagerret_bad );
3970
3985
}
@@ -3989,11 +4004,30 @@ zfs_getpages(struct vnode *vp, vm_page_t *ma, int count, int *rbehind,
3989
4004
* ZFS will panic if we request DMU to read beyond the end of the last
3990
4005
* allocated block.
3991
4006
*/
3992
- error = dmu_read_pages ( zfsvfs -> z_os , zp -> z_id , ma , count , & pgsin_b ,
3993
- & pgsin_a , MIN ( end , obj_size ) - ( end - PAGE_SIZE )) ;
4007
+ for ( int i = 0 ; i < count ; i ++ ) {
4008
+ int count1 , j , last_size ;
3994
4009
3995
- if (lr != NULL )
3996
- zfs_rangelock_exit (lr );
4010
+ if (vm_page_any_valid (ma [i ])) {
4011
+ ASSERT (vm_page_all_valid (ma [i ]));
4012
+ continue ;
4013
+ }
4014
+ for (j = i + 1 ; j < count ; j ++ ) {
4015
+ if (vm_page_any_valid (ma [j ])) {
4016
+ ASSERT (vm_page_all_valid (ma [j ]));
4017
+ break ;
4018
+ }
4019
+ }
4020
+ count1 = j - i ;
4021
+ last_size = j == count ?
4022
+ MIN (end , obj_size ) - (end - PAGE_SIZE ) : PAGE_SIZE ;
4023
+ error = dmu_read_pages (zfsvfs -> z_os , zp -> z_id , & ma [i ], count1 ,
4024
+ i == 0 ? & pgsin_b : NULL , j == count ? & pgsin_a : NULL ,
4025
+ last_size );
4026
+ if (error != 0 )
4027
+ break ;
4028
+ }
4029
+
4030
+ zfs_rangelock_exit (lr );
3997
4031
ZFS_ACCESSTIME_STAMP (zfsvfs , zp );
3998
4032
3999
4033
dataset_kstats_update_read_kstats (& zfsvfs -> z_kstat , count * PAGE_SIZE );
0 commit comments