(void) buf_cleanout(bp);
uvm_swap_io(pps, startslot, npages, flags)	struct vm_page **pps;	int startslot, npages, flags;{	daddr_t startblk;	struct	buf *bp;	vaddr_t kva;	int	error, s, mapinflags, pflag;	boolean_t write, async;#ifdef UVM_SWAP_ENCRYPT	vaddr_t dstkva;	struct vm_page *tpps[MAXBSIZE >> PAGE_SHIFT];	struct swapdev *sdp;	int	encrypt = 0;#endif	UVMHIST_FUNC("uvm_swap_io"); UVMHIST_CALLED(pdhist);	UVMHIST_LOG(pdhist, "<- called, startslot=%d, npages=%d, flags=%d",	    startslot, npages, flags, 0);	write = (flags & B_READ) == 0;	async = (flags & B_ASYNC) != 0;	/*	 * convert starting drum slot to block number	 */	startblk = btodb((u_int64_t)startslot << PAGE_SHIFT);	/*	 * first, map the pages into the kernel (XXX: currently required	 * by buffer system).	 */	mapinflags = !write ? UVMPAGER_MAPIN_READ : UVMPAGER_MAPIN_WRITE;	if (!async)		mapinflags |= UVMPAGER_MAPIN_WAITOK;	kva = uvm_pagermapin(pps, npages, mapinflags);	if (kva == 0)		return (EAGAIN);#ifdef UVM_SWAP_ENCRYPT	if (write) {		/*		 * Check if we need to do swap encryption on old pages.		 * Later we need a different scheme, that swap encrypts		 * all pages of a process that had at least one page swap		 * encrypted.  Then we might not need to copy all pages		 * in the cluster, and avoid the memory overheard in 		 * swapping.		 */		if (uvm_doswapencrypt)			encrypt = 1;	}	if (swap_encrypt_initalized  || encrypt) { 		/*		 * we need to know the swap device that we are swapping to/from		 * to see if the pages need to be marked for decryption or		 * actually need to be decrypted.		 * XXX - does this information stay the same over the whole 		 * execution of this function?		 */		simple_lock(&uvm.swap_data_lock);		sdp = swapdrum_getsdp(startslot);		simple_unlock(&uvm.swap_data_lock);	}	/* 	 * encrypt to swap	 */	if (write && encrypt) {		int i, opages;		caddr_t src, dst;		struct swap_key *key;		u_int64_t block;		int swmapflags;		/* We always need write access. */		swmapflags = UVMPAGER_MAPIN_READ;		if (!async)			swmapflags |= UVMPAGER_MAPIN_WAITOK;		if (!uvm_swap_allocpages(tpps, npages)) {			uvm_pagermapout(kva, npages);			return (EAGAIN);		}				dstkva = uvm_pagermapin(tpps, npages, swmapflags);		if (dstkva == NULL) {			uvm_pagermapout(kva, npages);			uvm_swap_freepages(tpps, npages);			return (EAGAIN);		}		src = (caddr_t) kva;		dst = (caddr_t) dstkva;		block = startblk;		for (i = 0; i < npages; i++) {			key = SWD_KEY(sdp, startslot + i);			SWAP_KEY_GET(sdp, key);	/* add reference */			/* mark for async writes */			tpps[i]->pqflags |= PQ_ENCRYPT;			swap_encrypt(key, src, dst, block, 1 << PAGE_SHIFT);			src += 1 << PAGE_SHIFT;			dst += 1 << PAGE_SHIFT;			block += btodb(1 << PAGE_SHIFT);		}		uvm_pagermapout(kva, npages);		/* dispose of pages we dont use anymore */		opages = npages;		uvm_pager_dropcluster(NULL, NULL, pps, &opages, 				      PGO_PDFREECLUST);		kva = dstkva;	}#endif /* UVM_SWAP_ENCRYPT */	/*	 * now allocate a buf for the i/o.	 * [make sure we don't put the pagedaemon to sleep...]	 */	s = splbio();	pflag = (async || curproc == uvm.pagedaemon_proc) ? 0 : PR_WAITOK;	bp = pool_get(&bufpool, pflag);	splx(s);	/*	 * if we failed to get a swapbuf, return "try again"	 */	if (bp == NULL) {#ifdef UVM_SWAP_ENCRYPT		if (write && encrypt) {			int i;			/* swap encrypt needs cleanup */			for (i = 0; i < npages; i++)				SWAP_KEY_PUT(sdp, SWD_KEY(sdp, startslot + i));			uvm_pagermapout(kva, npages);			uvm_swap_freepages(tpps, npages);		}#endif		return (EAGAIN);	}	#ifdef UVM_SWAP_ENCRYPT	/* 	 * prevent ASYNC reads.	 * uvm_swap_io is only called from uvm_swap_get, uvm_swap_get	 * assumes that all gets are SYNCIO.  Just make sure here.	 * XXXARTUBC - might not be true anymore.	 */	if (!write) {		flags &= ~B_ASYNC;		async = 0;	}#endif	/*	 * fill in the bp.   we currently route our i/o through	 * /dev/drum's vnode [swapdev_vp].	 */	bp->b_flags = B_BUSY | B_NOCACHE | (flags & (B_READ|B_ASYNC));	bp->b_proc = &proc0;	/* XXX */	bp->b_vnbufs.le_next = NOLIST;	bp->b_data = (caddr_t)kva;	bp->b_blkno = startblk;	LIST_INIT(&bp->b_dep);	s = splbio();	bp->b_vp = NULL;	buf_replacevnode(bp, swapdev_vp);	splx(s);	bp->b_bufsize = bp->b_bcount = npages << PAGE_SHIFT;	/*	 * bump v_numoutput (counter of number of active outputs).	 */	if (write) {#ifdef UVM_SWAP_ENCRYPT		/* mark the pages in the drum for decryption */		if (swap_encrypt_initalized)			uvm_swap_markdecrypt(sdp, startslot, npages, encrypt);#endif		s = splbio();		swapdev_vp->v_numoutput++;		splx(s);	}	/*	 * for async ops we must set up the iodone handler.	 */	if (async) {		bp->b_flags |= B_CALL | (curproc == uvm.pagedaemon_proc ?					 B_PDAEMON : 0);		bp->b_iodone = uvm_aio_biodone;		UVMHIST_LOG(pdhist, "doing async!", 0, 0, 0, 0);	}	UVMHIST_LOG(pdhist,	    "about to start io: data = %p blkno = 0x%x, bcount = %ld",	    bp->b_data, bp->b_blkno, bp->b_bcount, 0);	/*	 * now we start the I/O, and if async, return.	 */	VOP_STRATEGY(bp);	if (async)		return 0;	/*	 * must be sync i/o.   wait for it to finish	 */	error = biowait(bp);#ifdef UVM_SWAP_ENCRYPT	/* 	 * decrypt swap	 */	if (swap_encrypt_initalized &&	    (bp->b_flags & B_READ) && !(bp->b_flags & B_ERROR)) {		int i;		caddr_t data = bp->b_data;		u_int64_t block = startblk;		struct swap_key *key = NULL;		for (i = 0; i < npages; i++) {			/* Check if we need to decrypt */			if (uvm_swap_needdecrypt(sdp, startslot + i)) {				key = SWD_KEY(sdp, startslot + i);				swap_decrypt(key, data, data, block,					     1 << PAGE_SHIFT);			}			data += 1 << PAGE_SHIFT;			block += btodb(1 << PAGE_SHIFT);		}	}#endif	/*	 * kill the pager mapping	 */	uvm_pagermapout(kva, npages);#ifdef UVM_SWAP_ENCRYPT	/*	 *  Not anymore needed, free after encryption	 */	if ((bp->b_flags & B_READ) == 0 && encrypt)		uvm_swap_freepages(tpps, npages);#endif	/*	 * now dispose of the buf	 */	s = splbio();	if (write && bp->b_vp)		vwakeup(bp->b_vp);	(void) buf_cleanout(bp);	pool_put(&bufpool, bp);	splx(s);	/*	 * finally return.	 */	UVMHIST_LOG(pdhist, "<- done (sync)  error=%d", error, 0, 0, 0);	return (error);}