FreeBSD/sys/dev/xen/blkback/blkback.c
/**
 * Completion handler for buffer I/O requests issued by the device
 * backend driver.
 *
 * \param bio  The buffer I/O request on which to perform completion
 *             processing.
 */
Completion handler for buffer I/O requests issued by the device
backend driver.

\param bio  The buffer I/O request on which to perform completion
processing.
Completion handler for buffer I / O requests issued by the device backend driver . \ param bio The buffer I / O request on which to perform completion processing .
static void
xbb_bio_done(struct bio *bio)
{
	struct xbb_softc       *xbb;
	struct xbb_xen_reqlist *reqlist;
	reqlist = bio->bio_caller1;
	xbb     = reqlist->xbb;
	reqlist->residual_512b_sectors += bio->bio_resid >> 9;
	if (bio->bio_error) {
		DPRINTF("BIO returned error %d for operation on device %s\n",
			bio->bio_error, xbb->dev_name);
		reqlist->status = BLKIF_RSP_ERROR;
		if (bio->bio_error == ENXIO
		 && xenbus_get_state(xbb->dev) == XenbusStateConnected) {
			xenbus_set_state(xbb->dev, XenbusStateClosing);
		}
	}
#ifdef XBB_USE_BOUNCE_BUFFERS
	if (bio->bio_cmd == BIO_READ) {
		vm_offset_t kva_offset;
		kva_offset = (vm_offset_t)bio->bio_data
			   - (vm_offset_t)reqlist->bounce;
		memcpy((uint8_t *)reqlist->kva + kva_offset,
		       bio->bio_data, bio->bio_bcount);
	}
#endif 
	if (atomic_fetchadd_int(&reqlist->pendcnt, -1) == 1)
		xbb_complete_reqlist(xbb, reqlist);
	g_destroy_bio(bio);
}
static void xbb_bio_done ( struct bio * bio ) { struct xbb_softc * xbb ; struct xbb_xen_reqlist * reqlist ; reqlist = bio -> bio_caller1 ; xbb = reqlist -> xbb ; reqlist -> residual_512b_sectors += bio -> bio_resid >> 9 ; if ( bio -> bio_error ) { DPRINTF ( " \n " , bio -> bio_error , xbb -> dev_name ) ; reqlist -> status = BLKIF_RSP_ERROR ; if ( bio -> bio_error == ENXIO && xenbus_get_state ( xbb -> dev ) == XenbusStateConnected ) { xenbus_set_state ( xbb -> dev , XenbusStateClosing ) ; } } #ifdef XBB_USE_BOUNCE_BUFFERS if ( bio -> bio_cmd == BIO_READ ) { vm_offset_t kva_offset ; kva_offset = ( vm_offset_t ) bio -> bio_data - ( vm_offset_t ) reqlist -> bounce ; memcpy ( ( uint8_t * ) reqlist -> kva + kva_offset , bio -> bio_data , bio -> bio_bcount ) ; } #endif if ( atomic_fetchadd_int ( & reqlist -> pendcnt , -1 ) == 1 ) xbb_complete_reqlist ( xbb , reqlist ) ; g_destroy_bio ( bio ) ; }
Completion handler for buffer I/O requests issued by the device
 backend driver.
Completion handler for buffer I / O requests issued by the device backend driver .
/*
	 * This is a bit imprecise.  With aggregated I/O a single
	 * request list can contain multiple front-end requests and
	 * a multiple bios may point to a single request.  By carefully
	 * walking the request list, we could map residuals and errors
	 * back to the original front-end request, but the interface
	 * isn't sufficiently rich for us to properly report the error.
	 * So, we just treat the entire request list as having failed if an
	 * error occurs on any part.  And, if an error occurs, we treat
	 * the amount of data transferred as 0.
	 *
	 * For residuals, we report it on the overall aggregated device,
	 * but not on the individual requests, since we don't currently
	 * do the work to determine which front-end request to which the
	 * residual applies.
	 */ /*
			 * Backend device has disappeared.  Signal the
			 * front-end that we (the device proxy) want to
			 * go away.
			 */ /* XBB_USE_BOUNCE_BUFFERS */ /*
	 * Decrement the pending count for the request list.  When we're
	 * done with the requests, send status back for all of them.
	 */