diff options
author | Konstantin Belousov <kib@FreeBSD.org> | 2018-03-24 13:13:52 +0000 |
---|---|---|
committer | Konstantin Belousov <kib@FreeBSD.org> | 2018-03-24 13:13:52 +0000 |
commit | 161bf65f8a3db9f8e8bc4f7afde54f32f2d95a23 (patch) | |
tree | e9f6f0a69c9232d08e79faa4e2823229f360322f /sys | |
parent | a37d4032edf1245d5a5ef8ba3ac46c8ac175b54e (diff) | |
download | src-161bf65f8a3db9f8e8bc4f7afde54f32f2d95a23.tar.gz src-161bf65f8a3db9f8e8bc4f7afde54f32f2d95a23.zip |
In vn_io_fault1(), reduce the scope where pagefaults are disabled.
Most important for the future use, do not call
vm_fault_quick_hold_pages() with disabled pagefaults.
Reported and tested by: pho (as part of the larger patch)
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Notes
Notes:
svn path=/head/; revision=331487
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/vfs_vnops.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 40618cac8a8d..5d3efc7a8204 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -956,23 +956,30 @@ static int vn_io_fault_doio(struct vn_io_fault_args *args, struct uio *uio, struct thread *td) { + int error, save; + error = 0; + save = vm_fault_disable_pagefaults(); switch (args->kind) { case VN_IO_FAULT_FOP: - return ((args->args.fop_args.doio)(args->args.fop_args.fp, - uio, args->cred, args->flags, td)); + error = (args->args.fop_args.doio)(args->args.fop_args.fp, + uio, args->cred, args->flags, td); + break; case VN_IO_FAULT_VOP: if (uio->uio_rw == UIO_READ) { - return (VOP_READ(args->args.vop_args.vp, uio, - args->flags, args->cred)); + error = VOP_READ(args->args.vop_args.vp, uio, + args->flags, args->cred); } else if (uio->uio_rw == UIO_WRITE) { - return (VOP_WRITE(args->args.vop_args.vp, uio, - args->flags, args->cred)); + error = VOP_WRITE(args->args.vop_args.vp, uio, + args->flags, args->cred); } break; + default: + panic("vn_io_fault_doio: unknown kind of io %d %d", + args->kind, uio->uio_rw); } - panic("vn_io_fault_doio: unknown kind of io %d %d", args->kind, - uio->uio_rw); + vm_fault_enable_pagefaults(save); + return (error); } static int @@ -1047,7 +1054,7 @@ vn_io_fault1(struct vnode *vp, struct uio *uio, struct vn_io_fault_args *args, vm_offset_t addr, end; size_t len, resid; ssize_t adv; - int error, cnt, save, saveheld, prev_td_ma_cnt; + int error, cnt, saveheld, prev_td_ma_cnt; if (vn_io_fault_prefault) { error = vn_io_fault_prefault_user(uio); @@ -1073,7 +1080,6 @@ vn_io_fault1(struct vnode *vp, struct uio *uio, struct vn_io_fault_args *args, short_uio.uio_rw = uio->uio_rw; short_uio.uio_td = uio->uio_td; - save = vm_fault_disable_pagefaults(); error = vn_io_fault_doio(args, uio, td); if (error != EFAULT) goto out; @@ -1144,7 +1150,6 @@ vn_io_fault1(struct vnode *vp, struct uio *uio, struct vn_io_fault_args *args, td->td_ma_cnt = prev_td_ma_cnt; curthread_pflags_restore(saveheld); out: - vm_fault_enable_pagefaults(save); free(uio_clone, M_IOV); return (error); } |