aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2018-03-24 13:13:52 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2018-03-24 13:13:52 +0000
commit161bf65f8a3db9f8e8bc4f7afde54f32f2d95a23 (patch)
treee9f6f0a69c9232d08e79faa4e2823229f360322f /sys
parenta37d4032edf1245d5a5ef8ba3ac46c8ac175b54e (diff)
downloadsrc-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.c27
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);
}