/* * The strategy function is typically only called when memory pressure * forces the system to attempt to pageout pages. It can also be called * by [n]vtruncbuf() when a truncation cuts a page in half. Normal write * operations */ static int tmpfs_strategy(struct vop_strategy_args *ap) { struct bio *bio = ap->a_bio; struct bio *nbio; struct buf *bp = bio->bio_buf; struct vnode *vp = ap->a_vp; struct tmpfs_node *node; vm_object_t uobj; vm_page_t m; int i; if (vp->v_type != VREG) { bp->b_resid = bp->b_bcount; bp->b_flags |= B_ERROR | B_INVAL; bp->b_error = EINVAL; biodone(bio); return(0); } lwkt_gettoken(&vp->v_mount->mnt_token); node = VP_TO_TMPFS_NODE(vp); uobj = node->tn_reg.tn_aobj; /* * Don't bother flushing to swap if there is no swap, just * ensure that the pages are marked as needing a commit (still). */ if (bp->b_cmd == BUF_CMD_WRITE && vm_swap_size == 0) { for (i = 0; i < bp->b_xio.xio_npages; ++i) { m = bp->b_xio.xio_pages[i]; vm_page_need_commit(m); } bp->b_resid = 0; bp->b_error = 0; biodone(bio); } else { nbio = push_bio(bio); nbio->bio_done = tmpfs_strategy_done; nbio->bio_offset = bio->bio_offset; swap_pager_strategy(uobj, nbio); } lwkt_reltoken(&vp->v_mount->mnt_token); return 0; }
/* * Calculate the logical to physical mapping if not done already, * then call the device strategy routine. * * In order to be able to swap to a file, the VOP_BMAP operation may not * deadlock on memory. See hpfs_bmap() for details. XXXXXXX (not impl) * * hpfs_strategy(struct vnode *a_vp, struct bio *a_bio) */ int hpfs_strategy(struct vop_strategy_args *ap) { struct bio *bio = ap->a_bio; struct bio *nbio; struct buf *bp = bio->bio_buf; struct vnode *vp = ap->a_vp; struct hpfsnode *hp; int error; dprintf(("hpfs_strategy(): \n")); if (vp->v_type == VBLK || vp->v_type == VCHR) panic("hpfs_strategy: spec"); nbio = push_bio(bio); if (nbio->bio_offset == NOOFFSET) { error = VOP_BMAP(vp, bio->bio_offset, &nbio->bio_offset, NULL, NULL, bp->b_cmd); if (error) { kprintf("hpfs_strategy: VOP_BMAP FAILED %d\n", error); bp->b_error = error; bp->b_flags |= B_ERROR; /* I/O was never started on nbio, must biodone(bio) */ biodone(bio); return (error); } if (nbio->bio_offset == NOOFFSET) vfs_bio_clrbuf(bp); } if (nbio->bio_offset == NOOFFSET) { /* I/O was never started on nbio, must biodone(bio) */ biodone(bio); return (0); } hp = VTOHP(ap->a_vp); vn_strategy(hp->h_devvp, nbio); return (0); }