/* * 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 ext2_bmaparray() operation may not * deadlock on memory. See ext2_bmap() for details. */ static int ext2_strategy(struct vop_strategy_args *ap) { struct buf *bp = ap->a_bp; struct vnode *vp = ap->a_vp; struct inode *ip; struct bufobj *bo; int32_t blkno; int error; ip = VTOI(vp); if (vp->v_type == VBLK || vp->v_type == VCHR) panic("ext2_strategy: spec"); if (bp->b_blkno == bp->b_lblkno) { error = ext2_bmaparray(vp, bp->b_lblkno, &blkno, NULL, NULL); bp->b_blkno = blkno; if (error) { bp->b_error = error; bp->b_ioflags |= BIO_ERROR; bufdone(bp); return (0); } if ((long)bp->b_blkno == -1) vfs_bio_clrbuf(bp); } if ((long)bp->b_blkno == -1) { bufdone(bp); return (0); } bp->b_iooffset = dbtob(bp->b_blkno); bo = VFSTOEXT2(vp->v_mount)->um_bo; BO_STRATEGY(bo, bp); return (0); }
/* * Bmap converts the logical block number of a file to its physical block * number on the disk. The conversion is done by using the logical block * number to index into the array of block pointers described by the dinode. * * BMAP must return the contiguous before and after run in bytes, inclusive * of the returned block. * * ext2_bmap(struct vnode *a_vp, off_t a_loffset, * off_t *a_doffsetp, int *a_runp, int *a_runb) */ int ext2_bmap(struct vop_bmap_args *ap) { struct ext2_sb_info *fs; ext2_daddr_t lbn; ext2_daddr_t dbn; int error; /* * Check for underlying vnode requests and ensure that logical * to physical mapping is requested. */ if (ap->a_doffsetp == NULL) return (0); fs = VTOI(ap->a_vp)->i_e2fs; KKASSERT(((int)ap->a_loffset & ((1 << fs->s_bshift) - 1)) == 0); lbn = ap->a_loffset >> fs->s_bshift; error = ext2_bmaparray(ap->a_vp, lbn, &dbn, NULL, NULL, ap->a_runp, ap->a_runb); if (error || dbn == (ext2_daddr_t)-1) { *ap->a_doffsetp = NOOFFSET; } else { *ap->a_doffsetp = dbtodoff(fs, dbn); if (ap->a_runp) *ap->a_runp = (*ap->a_runp + 1) << fs->s_bshift; if (ap->a_runb) *ap->a_runb = *ap->a_runb << fs->s_bshift; } return (error); }
/* * Bmap converts the logical block number of a file to its physical block * number on the disk. The conversion is done by using the logical block * number to index into the array of block pointers described by the dinode. */ int ext2_bmap(struct vop_bmap_args *ap) { daddr_t blkno; int error; /* * Check for underlying vnode requests and ensure that logical * to physical mapping is requested. */ if (ap->a_bop != NULL) *ap->a_bop = &VTOI(ap->a_vp)->i_devvp->v_bufobj; if (ap->a_bnp == NULL) return (0); if (VTOI(ap->a_vp)->i_flag & IN_E4EXTENTS) error = ext4_bmapext(ap->a_vp, ap->a_bn, &blkno, ap->a_runp, ap->a_runb); else error = ext2_bmaparray(ap->a_vp, ap->a_bn, &blkno, ap->a_runp, ap->a_runb); *ap->a_bnp = blkno; return (error); }