Esempio n. 1
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 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);
}
Esempio n. 2
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);
}
Esempio n. 3
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.
 */
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);
}