| 1181 | } |
| 1182 | |
| 1183 | static void |
| 1184 | ktr_writerequest(struct thread *td, struct ktr_request *req) |
| 1185 | { |
| 1186 | struct ktr_header *kth; |
| 1187 | struct vnode *vp; |
| 1188 | struct proc *p; |
| 1189 | struct ucred *cred; |
| 1190 | struct uio auio; |
| 1191 | struct iovec aiov[3]; |
| 1192 | struct mount *mp; |
| 1193 | int datalen, buflen, vrele_count; |
| 1194 | int error; |
| 1195 | |
| 1196 | /* |
| 1197 | * We hold the vnode and credential for use in I/O in case ktrace is |
| 1198 | * disabled on the process as we write out the request. |
| 1199 | * |
| 1200 | * XXXRW: This is not ideal: we could end up performing a write after |
| 1201 | * the vnode has been closed. |
| 1202 | */ |
| 1203 | mtx_lock(&ktrace_mtx); |
| 1204 | vp = td->td_proc->p_tracevp; |
| 1205 | cred = td->td_proc->p_tracecred; |
| 1206 | |
| 1207 | /* |
| 1208 | * If vp is NULL, the vp has been cleared out from under this |
| 1209 | * request, so just drop it. Make sure the credential and vnode are |
| 1210 | * in sync: we should have both or neither. |
| 1211 | */ |
| 1212 | if (vp == NULL) { |
| 1213 | KASSERT(cred == NULL, ("ktr_writerequest: cred != NULL")); |
| 1214 | mtx_unlock(&ktrace_mtx); |
| 1215 | return; |
| 1216 | } |
| 1217 | VREF(vp); |
| 1218 | KASSERT(cred != NULL, ("ktr_writerequest: cred == NULL")); |
| 1219 | crhold(cred); |
| 1220 | mtx_unlock(&ktrace_mtx); |
| 1221 | |
| 1222 | kth = &req->ktr_header; |
| 1223 | KASSERT(((u_short)kth->ktr_type & ~KTR_DROP) < nitems(data_lengths), |
| 1224 | ("data_lengths array overflow")); |
| 1225 | datalen = data_lengths[(u_short)kth->ktr_type & ~KTR_DROP]; |
| 1226 | buflen = kth->ktr_len; |
| 1227 | auio.uio_iov = &aiov[0]; |
| 1228 | auio.uio_offset = 0; |
| 1229 | auio.uio_segflg = UIO_SYSSPACE; |
| 1230 | auio.uio_rw = UIO_WRITE; |
| 1231 | aiov[0].iov_base = (caddr_t)kth; |
| 1232 | aiov[0].iov_len = sizeof(struct ktr_header); |
| 1233 | auio.uio_resid = sizeof(struct ktr_header); |
| 1234 | auio.uio_iovcnt = 1; |
| 1235 | auio.uio_td = td; |
| 1236 | if (datalen != 0) { |
| 1237 | aiov[1].iov_base = (caddr_t)&req->ktr_data; |
| 1238 | aiov[1].iov_len = datalen; |
| 1239 | auio.uio_resid += datalen; |
| 1240 | auio.uio_iovcnt++; |
no test coverage detected