* File table vnode read routine. */
| 974 | * File table vnode read routine. |
| 975 | */ |
| 976 | static int |
| 977 | vn_read(struct file *fp, struct uio *uio, struct ucred *active_cred, int flags, |
| 978 | struct thread *td) |
| 979 | { |
| 980 | struct vnode *vp; |
| 981 | off_t orig_offset; |
| 982 | int error, ioflag; |
| 983 | int advice; |
| 984 | |
| 985 | KASSERT(uio->uio_td == td, ("uio_td %p is not td %p", |
| 986 | uio->uio_td, td)); |
| 987 | KASSERT(flags & FOF_OFFSET, ("No FOF_OFFSET")); |
| 988 | vp = fp->f_vnode; |
| 989 | ioflag = 0; |
| 990 | if (fp->f_flag & FNONBLOCK) |
| 991 | ioflag |= IO_NDELAY; |
| 992 | if (fp->f_flag & O_DIRECT) |
| 993 | ioflag |= IO_DIRECT; |
| 994 | |
| 995 | /* |
| 996 | * Try to read from page cache. VIRF_DOOMED check is racy but |
| 997 | * allows us to avoid unneeded work outright. |
| 998 | */ |
| 999 | if (vn_io_pgcache_read_enable && !mac_vnode_check_read_enabled() && |
| 1000 | (vn_irflag_read(vp) & (VIRF_DOOMED | VIRF_PGREAD)) == VIRF_PGREAD) { |
| 1001 | error = VOP_READ_PGCACHE(vp, uio, ioflag, fp->f_cred); |
| 1002 | if (error == 0) { |
| 1003 | fp->f_nextoff[UIO_READ] = uio->uio_offset; |
| 1004 | return (0); |
| 1005 | } |
| 1006 | if (error != EJUSTRETURN) |
| 1007 | return (error); |
| 1008 | } |
| 1009 | |
| 1010 | advice = get_advice(fp, uio); |
| 1011 | vn_lock(vp, LK_SHARED | LK_RETRY); |
| 1012 | |
| 1013 | switch (advice) { |
| 1014 | case POSIX_FADV_NORMAL: |
| 1015 | case POSIX_FADV_SEQUENTIAL: |
| 1016 | case POSIX_FADV_NOREUSE: |
| 1017 | ioflag |= sequential_heuristic(uio, fp); |
| 1018 | break; |
| 1019 | case POSIX_FADV_RANDOM: |
| 1020 | /* Disable read-ahead for random I/O. */ |
| 1021 | break; |
| 1022 | } |
| 1023 | orig_offset = uio->uio_offset; |
| 1024 | |
| 1025 | #ifdef MAC |
| 1026 | error = mac_vnode_check_read(active_cred, fp->f_cred, vp); |
| 1027 | if (error == 0) |
| 1028 | #endif |
| 1029 | error = VOP_READ(vp, uio, ioflag, fp->f_cred); |
| 1030 | fp->f_nextoff[UIO_READ] = uio->uio_offset; |
| 1031 | VOP_UNLOCK(vp); |
| 1032 | if (error == 0 && advice == POSIX_FADV_NOREUSE && |
| 1033 | orig_offset != uio->uio_offset) |
nothing calls this directly
no test coverage detected