FreeBSD/sys/kern/kern_sendfile.c
/*
 * I/O completion callback.
 */
I/O completion callback.
I / O completion callback .
static void
sendfile_iodone(void *arg, vm_page_t *pg, int count, int error)
{
	struct sf_io *sfio = arg;
	struct socket *so;
	for (int i = 0; i < count; i++)
		vm_page_xunbusy(pg[i]);
	if (error)
		sfio->error = error;
	if (!refcount_release(&sfio->nios))
		return;
	so = sfio->sock_fp->f_data;
	if (sfio->error) {
		struct mbuf *m;
		so->so_proto->pr_usrreqs->pru_abort(so);
		so->so_error = EIO;
		m = sfio->m;
		for (int i = 0; i < sfio->npages; i++)
			m = m_free(m);
	} else {
		CURVNET_SET(so->so_vnet);
		(void )(so->so_proto->pr_usrreqs->pru_ready)(so, sfio->m,
		    sfio->npages);
		CURVNET_RESTORE();
	}
	fdrop(sfio->sock_fp, curthread);
	free(sfio, M_TEMP);
}
static void sendfile_iodone ( void * arg , vm_page_t * pg , int count , int error ) { struct sf_io * sfio = arg ; struct socket * so ; for ( int i = 0 ; i < count ; i ++ ) vm_page_xunbusy ( pg [ i ] ) ; if ( error ) sfio -> error = error ; if ( ! refcount_release ( & sfio -> nios ) ) return ; so = sfio -> sock_fp -> f_data ; if ( sfio -> error ) { struct mbuf * m ; so -> so_proto -> pr_usrreqs -> pru_abort ( so ) ; so -> so_error = EIO ; m = sfio -> m ; for ( int i = 0 ; i < sfio -> npages ; i ++ ) m = m_free ( m ) ; } else { CURVNET_SET ( so -> so_vnet ) ; ( void ) ( so -> so_proto -> pr_usrreqs -> pru_ready ) ( so , sfio -> m , sfio -> npages ) ; CURVNET_RESTORE ( ) ; } fdrop ( sfio -> sock_fp , curthread ) ; free ( sfio , M_TEMP ) ; }
I/O completion callback.
I / O completion callback .
/*
		 * I/O operation failed.  The state of data in the socket
		 * is now inconsistent, and all what we can do is to tear
		 * it down. Protocol abort method would tear down protocol
		 * state, free all ready mbufs and detach not ready ones.
		 * We will free the mbufs corresponding to this I/O manually.
		 *
		 * The socket would be marked with EIO and made available
		 * for read, so that application receives EIO on next
		 * syscall and eventually closes the socket.
		 */ /* XXXGL: curthread */