Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/vfs_vnops.c
Show First 20 Lines • Show All 950 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* Decode vn_io_fault_args and perform the corresponding i/o. | * Decode vn_io_fault_args and perform the corresponding i/o. | ||||
*/ | */ | ||||
static int | static int | ||||
vn_io_fault_doio(struct vn_io_fault_args *args, struct uio *uio, | vn_io_fault_doio(struct vn_io_fault_args *args, struct uio *uio, | ||||
struct thread *td) | struct thread *td) | ||||
{ | { | ||||
int error, save; | |||||
error = 0; | |||||
save = vm_fault_disable_pagefaults(); | |||||
switch (args->kind) { | switch (args->kind) { | ||||
case VN_IO_FAULT_FOP: | case VN_IO_FAULT_FOP: | ||||
return ((args->args.fop_args.doio)(args->args.fop_args.fp, | error = (args->args.fop_args.doio)(args->args.fop_args.fp, | ||||
uio, args->cred, args->flags, td)); | uio, args->cred, args->flags, td); | ||||
break; | |||||
case VN_IO_FAULT_VOP: | case VN_IO_FAULT_VOP: | ||||
if (uio->uio_rw == UIO_READ) { | if (uio->uio_rw == UIO_READ) { | ||||
return (VOP_READ(args->args.vop_args.vp, uio, | error = VOP_READ(args->args.vop_args.vp, uio, | ||||
args->flags, args->cred)); | args->flags, args->cred); | ||||
} else if (uio->uio_rw == UIO_WRITE) { | } else if (uio->uio_rw == UIO_WRITE) { | ||||
return (VOP_WRITE(args->args.vop_args.vp, uio, | error = VOP_WRITE(args->args.vop_args.vp, uio, | ||||
args->flags, args->cred)); | args->flags, args->cred); | ||||
} | } | ||||
break; | 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, | vm_fault_enable_pagefaults(save); | ||||
uio->uio_rw); | return (error); | ||||
} | } | ||||
static int | static int | ||||
vn_io_fault_touch(char *base, const struct uio *uio) | vn_io_fault_touch(char *base, const struct uio *uio) | ||||
{ | { | ||||
int r; | int r; | ||||
r = fubyte(base); | r = fubyte(base); | ||||
▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | vn_io_fault1(struct vnode *vp, struct uio *uio, struct vn_io_fault_args *args, | ||||
vm_page_t ma[io_hold_cnt + 2]; | vm_page_t ma[io_hold_cnt + 2]; | ||||
struct uio *uio_clone, short_uio; | struct uio *uio_clone, short_uio; | ||||
struct iovec short_iovec[1]; | struct iovec short_iovec[1]; | ||||
vm_page_t *prev_td_ma; | vm_page_t *prev_td_ma; | ||||
vm_prot_t prot; | vm_prot_t prot; | ||||
vm_offset_t addr, end; | vm_offset_t addr, end; | ||||
size_t len, resid; | size_t len, resid; | ||||
ssize_t adv; | 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) { | if (vn_io_fault_prefault) { | ||||
error = vn_io_fault_prefault_user(uio); | error = vn_io_fault_prefault_user(uio); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); /* Or ignore ? */ | return (error); /* Or ignore ? */ | ||||
} | } | ||||
prot = uio->uio_rw == UIO_READ ? VM_PROT_WRITE : VM_PROT_READ; | prot = uio->uio_rw == UIO_READ ? VM_PROT_WRITE : VM_PROT_READ; | ||||
Show All 9 Lines | vn_io_fault1(struct vnode *vp, struct uio *uio, struct vn_io_fault_args *args, | ||||
*/ | */ | ||||
uio_clone = cloneuio(uio); | uio_clone = cloneuio(uio); | ||||
resid = uio->uio_resid; | resid = uio->uio_resid; | ||||
short_uio.uio_segflg = UIO_USERSPACE; | short_uio.uio_segflg = UIO_USERSPACE; | ||||
short_uio.uio_rw = uio->uio_rw; | short_uio.uio_rw = uio->uio_rw; | ||||
short_uio.uio_td = uio->uio_td; | short_uio.uio_td = uio->uio_td; | ||||
save = vm_fault_disable_pagefaults(); | |||||
error = vn_io_fault_doio(args, uio, td); | error = vn_io_fault_doio(args, uio, td); | ||||
if (error != EFAULT) | if (error != EFAULT) | ||||
goto out; | goto out; | ||||
atomic_add_long(&vn_io_faults_cnt, 1); | atomic_add_long(&vn_io_faults_cnt, 1); | ||||
uio_clone->uio_segflg = UIO_NOCOPY; | uio_clone->uio_segflg = UIO_NOCOPY; | ||||
uiomove(NULL, resid - uio->uio_resid, uio_clone); | uiomove(NULL, resid - uio->uio_resid, uio_clone); | ||||
uio_clone->uio_segflg = uio->uio_segflg; | uio_clone->uio_segflg = uio->uio_segflg; | ||||
▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | while (uio_clone->uio_resid != 0) { | ||||
if (error != 0 || adv == 0) | if (error != 0 || adv == 0) | ||||
break; | break; | ||||
} | } | ||||
td->td_ma = prev_td_ma; | td->td_ma = prev_td_ma; | ||||
td->td_ma_cnt = prev_td_ma_cnt; | td->td_ma_cnt = prev_td_ma_cnt; | ||||
curthread_pflags_restore(saveheld); | curthread_pflags_restore(saveheld); | ||||
out: | out: | ||||
vm_fault_enable_pagefaults(save); | |||||
free(uio_clone, M_IOV); | free(uio_clone, M_IOV); | ||||
return (error); | return (error); | ||||
} | } | ||||
static int | static int | ||||
vn_io_fault(struct file *fp, struct uio *uio, struct ucred *active_cred, | vn_io_fault(struct file *fp, struct uio *uio, struct ucred *active_cred, | ||||
int flags, struct thread *td) | int flags, struct thread *td) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 1,353 Lines • Show Last 20 Lines |