Ejemplo n.º 1
0
/*
 * 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;
}
Ejemplo n.º 2
0
/*
 * 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;
}