mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-26 19:19:32 +03:00
Fix a logic bug in the FreeBSD getpages VOP
In commit cd32b4f5b7
("Fix a deadlock in the FreeBSD getpages VOP") I
introduced a bug while porting the patch originally committed to
FreeBSD: the rangelock pointer may be NULL if the try operation failed,
so we must avoid calling zfs_rangelock_unlock() in that case.
Reviewed-by: Allan Jude <allan@klarasystems.com>
Reviewed-by: Ryan Moeller <ryan@ixsystems.com>
Reviewed-by: Matt Macy <mmacy@FreeBSD.org>
Reported-by: Steve Wills <swills@FreeBSD.org>
Signed-off-by: Mark Johnston <markj@FreeBSD.org>
Closes #10519
Closes #10960
This commit is contained in:
parent
5f8a9e6a02
commit
0daa0320e9
@ -4859,6 +4859,7 @@ zfs_getpages(struct vnode *vp, vm_page_t *ma, int count, int *rbehind,
|
|||||||
obj_size = object->un_pager.vnp.vnp_size;
|
obj_size = object->un_pager.vnp.vnp_size;
|
||||||
zfs_vmobject_wunlock(object);
|
zfs_vmobject_wunlock(object);
|
||||||
if (IDX_TO_OFF(ma[count - 1]->pindex) >= obj_size) {
|
if (IDX_TO_OFF(ma[count - 1]->pindex) >= obj_size) {
|
||||||
|
if (lr != NULL)
|
||||||
zfs_rangelock_exit(lr);
|
zfs_rangelock_exit(lr);
|
||||||
ZFS_EXIT(zfsvfs);
|
ZFS_EXIT(zfsvfs);
|
||||||
return (zfs_vm_pagerret_bad);
|
return (zfs_vm_pagerret_bad);
|
||||||
@ -4887,6 +4888,7 @@ zfs_getpages(struct vnode *vp, vm_page_t *ma, int count, int *rbehind,
|
|||||||
error = dmu_read_pages(os, zp->z_id, ma, count, &pgsin_b, &pgsin_a,
|
error = dmu_read_pages(os, zp->z_id, ma, count, &pgsin_b, &pgsin_a,
|
||||||
MIN(end, obj_size) - (end - PAGE_SIZE));
|
MIN(end, obj_size) - (end - PAGE_SIZE));
|
||||||
|
|
||||||
|
if (lr != NULL)
|
||||||
zfs_rangelock_exit(lr);
|
zfs_rangelock_exit(lr);
|
||||||
ZFS_ACCESSTIME_STAMP(zfsvfs, zp);
|
ZFS_ACCESSTIME_STAMP(zfsvfs, zp);
|
||||||
ZFS_EXIT(zfsvfs);
|
ZFS_EXIT(zfsvfs);
|
||||||
|
Loading…
Reference in New Issue
Block a user