/* * uio_pushback - undo uncommitted I/O by subtracting from the * current base address and offset, and incrementing the residiual * IO. If the UIO was previously exhausted, this call will panic. * New code should not use this functionality. */ __private_extern__ void uio_pushback( uio_t a_uio, user_size_t a_count ) { #if LP64_DEBUG if (a_uio == NULL) { panic("%s :%d - invalid uio_t\n", __FILE__, __LINE__); } if (UIO_IS_32_BIT_SPACE(a_uio) && a_count > 0xFFFFFFFFull) { panic("%s :%d - invalid count value \n", __FILE__, __LINE__); } #endif /* LP64_DEBUG */ if (a_uio == NULL || a_count == 0) { return; } if (a_uio->uio_iovcnt < 1) { panic("Invalid uio for pushback"); } if (UIO_IS_USER_SPACE(a_uio)) { a_uio->uio_iovs.uiovp->iov_base -= a_count; a_uio->uio_iovs.uiovp->iov_len += a_count; } else { a_uio->uio_iovs.kiovp->iov_base -= a_count; a_uio->uio_iovs.kiovp->iov_len += a_count; } a_uio->uio_offset -= a_count; a_uio->uio_resid_64 += a_count; return; }
/* * uio_update - update the given uio_t for a_count of completed IO. * This call decrements the current iovec length and residual IO value * and increments the current iovec base address and offset value. * If the current iovec length is 0 then advance to the next * iovec (if any). * If the a_count passed in is 0, than only do the advancement * over any 0 length iovec's. */ void uio_update( uio_t a_uio, user_size_t a_count ) { #if LP64_DEBUG if (a_uio == NULL) { panic("%s :%d - invalid uio_t\n", __FILE__, __LINE__); } if (UIO_IS_32_BIT_SPACE(a_uio) && a_count > 0xFFFFFFFFull) { panic("%s :%d - invalid count value \n", __FILE__, __LINE__); } #endif /* LP64_DEBUG */ if (a_uio == NULL || a_uio->uio_iovcnt < 1) { return; } if (UIO_IS_64_BIT_SPACE(a_uio)) { /* * if a_count == 0, then we are asking to skip over * any empty iovs */ if (a_count) { if (a_count > a_uio->uio_iovs.uiovp->iov_len) { a_uio->uio_iovs.uiovp->iov_base += a_uio->uio_iovs.uiovp->iov_len; a_uio->uio_iovs.uiovp->iov_len = 0; } else { a_uio->uio_iovs.uiovp->iov_base += a_count; a_uio->uio_iovs.uiovp->iov_len -= a_count; } #if 1 // LP64todo - remove this temp workaround once we go live with uio KPI if (a_uio->uio_resid < 0) { a_uio->uio_resid = 0; } if (a_count > (user_size_t)a_uio->uio_resid) { a_uio->uio_offset += a_uio->uio_resid; a_uio->uio_resid = 0; } else { a_uio->uio_offset += a_count; a_uio->uio_resid -= a_count; } #else if (a_uio->uio_resid_64 < 0) { a_uio->uio_resid_64 = 0; } if (a_count > (user_size_t)a_uio->uio_resid_64) { a_uio->uio_offset += a_uio->uio_resid_64; a_uio->uio_resid_64 = 0; } else { a_uio->uio_offset += a_count; a_uio->uio_resid_64 -= a_count; } #endif // LP64todo } /* * advance to next iovec if current one is totally consumed */ while (a_uio->uio_iovcnt > 0 && a_uio->uio_iovs.uiovp->iov_len == 0) { a_uio->uio_iovcnt--; if (a_uio->uio_iovcnt > 0) { a_uio->uio_iovs.uiovp++; } } } else { /* * if a_count == 0, then we are asking to skip over * any empty iovs */ if (a_count) { if (a_count > a_uio->uio_iovs.kiovp->iov_len) { a_uio->uio_iovs.kiovp->iov_base += a_uio->uio_iovs.kiovp->iov_len; a_uio->uio_iovs.kiovp->iov_len = 0; } else { a_uio->uio_iovs.kiovp->iov_base += a_count; a_uio->uio_iovs.kiovp->iov_len -= a_count; } if (a_uio->uio_resid < 0) { a_uio->uio_resid = 0; } if (a_count > (user_size_t)a_uio->uio_resid) { a_uio->uio_offset += a_uio->uio_resid; a_uio->uio_resid = 0; } else { a_uio->uio_offset += a_count; a_uio->uio_resid -= a_count; } } /* * advance to next iovec if current one is totally consumed */ while (a_uio->uio_iovcnt > 0 && a_uio->uio_iovs.kiovp->iov_len == 0) { a_uio->uio_iovcnt--; if (a_uio->uio_iovcnt > 0) { a_uio->uio_iovs.kiovp++; } } } return; }