* File table vnode write routine. */
| 1045 | * File table vnode write routine. |
| 1046 | */ |
| 1047 | static int |
| 1048 | vn_write(struct file *fp, struct uio *uio, struct ucred *active_cred, int flags, |
| 1049 | struct thread *td) |
| 1050 | { |
| 1051 | struct vnode *vp; |
| 1052 | struct mount *mp; |
| 1053 | off_t orig_offset; |
| 1054 | int error, ioflag, lock_flags; |
| 1055 | int advice; |
| 1056 | |
| 1057 | KASSERT(uio->uio_td == td, ("uio_td %p is not td %p", |
| 1058 | uio->uio_td, td)); |
| 1059 | KASSERT(flags & FOF_OFFSET, ("No FOF_OFFSET")); |
| 1060 | vp = fp->f_vnode; |
| 1061 | if (vp->v_type == VREG) |
| 1062 | bwillwrite(); |
| 1063 | ioflag = IO_UNIT; |
| 1064 | if (vp->v_type == VREG && (fp->f_flag & O_APPEND)) |
| 1065 | ioflag |= IO_APPEND; |
| 1066 | if (fp->f_flag & FNONBLOCK) |
| 1067 | ioflag |= IO_NDELAY; |
| 1068 | if (fp->f_flag & O_DIRECT) |
| 1069 | ioflag |= IO_DIRECT; |
| 1070 | if ((fp->f_flag & O_FSYNC) || |
| 1071 | (vp->v_mount && (vp->v_mount->mnt_flag & MNT_SYNCHRONOUS))) |
| 1072 | ioflag |= IO_SYNC; |
| 1073 | /* |
| 1074 | * For O_DSYNC we set both IO_SYNC and IO_DATASYNC, so that VOP_WRITE() |
| 1075 | * implementations that don't understand IO_DATASYNC fall back to full |
| 1076 | * O_SYNC behavior. |
| 1077 | */ |
| 1078 | if (fp->f_flag & O_DSYNC) |
| 1079 | ioflag |= IO_SYNC | IO_DATASYNC; |
| 1080 | mp = NULL; |
| 1081 | if (vp->v_type != VCHR && |
| 1082 | (error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) |
| 1083 | goto unlock; |
| 1084 | |
| 1085 | advice = get_advice(fp, uio); |
| 1086 | |
| 1087 | if (MNT_SHARED_WRITES(mp) || |
| 1088 | (mp == NULL && MNT_SHARED_WRITES(vp->v_mount))) { |
| 1089 | lock_flags = LK_SHARED; |
| 1090 | } else { |
| 1091 | lock_flags = LK_EXCLUSIVE; |
| 1092 | } |
| 1093 | |
| 1094 | vn_lock(vp, lock_flags | LK_RETRY); |
| 1095 | switch (advice) { |
| 1096 | case POSIX_FADV_NORMAL: |
| 1097 | case POSIX_FADV_SEQUENTIAL: |
| 1098 | case POSIX_FADV_NOREUSE: |
| 1099 | ioflag |= sequential_heuristic(uio, fp); |
| 1100 | break; |
| 1101 | case POSIX_FADV_RANDOM: |
| 1102 | /* XXX: Is this correct? */ |
| 1103 | break; |
| 1104 | } |
nothing calls this directly
no test coverage detected