コード例 #1
0
ファイル: extents.c プロジェクト: Strongc/reactos
NTSTATUS
Ext2DoExtentExpand(
    IN PEXT2_IRP_CONTEXT    IrpContext,
    IN PEXT2_VCB            Vcb,
    IN PEXT2_MCB            Mcb,
    IN ULONG                Index,
    IN OUT PULONG           Block,
    IN OUT PULONG           Number
)
{
    EXT4_EXTENT_HEADER *eh;
    struct buffer_head bh_got;
    int    rc, flags;

    if (IsMcbDirectory(Mcb) || IrpContext->MajorFunction == IRP_MJ_WRITE) {
        flags = EXT4_GET_BLOCKS_IO_CONVERT_EXT;
    } else {
        flags = EXT4_GET_BLOCKS_IO_CREATE_EXT;
    }

    memset(&bh_got, 0, sizeof(struct buffer_head));
    eh = get_ext4_header(&Mcb->Inode);

    if (eh->eh_magic != EXT4_EXT_MAGIC) {
        ext4_ext_tree_init(IrpContext, NULL, &Mcb->Inode);
    }

    if ((rc = ext4_ext_get_blocks( IrpContext, NULL, &Mcb->Inode, Index,
                                  *Number, &bh_got, 1, flags)) < 0) {
        DEBUG(DL_ERR, ("Expand Block insufficient resources, Number: %u,"
                       " err: %d\n", *Number, rc));
        DbgBreak();
        return Ext2WinntError(rc);
    }

    if (Number)
        *Number = rc ? rc : 1;
    if (Block)
        *Block = (ULONG)bh_got.b_blocknr;

    Ext2SaveInode(IrpContext, Vcb, &Mcb->Inode);

    return STATUS_SUCCESS;
}
コード例 #2
0
ファイル: extents.c プロジェクト: Strongc/reactos
NTSTATUS
Ext2MapExtent(
    IN PEXT2_IRP_CONTEXT    IrpContext,
    IN PEXT2_VCB            Vcb,
    IN PEXT2_MCB            Mcb,
    IN ULONG                Index,
    IN BOOLEAN              Alloc,
    OUT PULONG              Block,
    OUT PULONG              Number
)
{
    EXT4_EXTENT_HEADER *eh;
    struct buffer_head bh_got;
    int    flags, rc;
	ULONG max_blocks = 0;

    memset(&bh_got, 0, sizeof(struct buffer_head));
    eh = get_ext4_header(&Mcb->Inode);

    if (eh->eh_magic != EXT4_EXT_MAGIC) {
        if (Alloc) {
            /* now initialize inode extent root node */
            ext4_ext_tree_init(IrpContext, NULL, &Mcb->Inode);
        } else {
            /* return empty-mapping when inode extent isn't initialized */
            if (Block)
                *Block = 0;
            if (Number) {
                LONGLONG  _len = _len = Mcb->Inode.i_size;
                if (Mcb->Fcb)
                    _len = Mcb->Fcb->Header.AllocationSize.QuadPart;
                *Number = (ULONG)((_len + BLOCK_SIZE - 1) >> BLOCK_BITS);
            }
            return STATUS_SUCCESS;
        }
    }

    /* IrpContext is NULL when called during journal initialization */
    if (IsMcbDirectory(Mcb) || IrpContext == NULL ||
        IrpContext->MajorFunction == IRP_MJ_WRITE || !Alloc){
        flags = EXT4_GET_BLOCKS_IO_CONVERT_EXT;
		max_blocks = EXT_INIT_MAX_LEN;
    } else {
        flags = EXT4_GET_BLOCKS_IO_CREATE_EXT;
		max_blocks = EXT_UNWRITTEN_MAX_LEN;
    }

    if ((rc = ext4_ext_get_blocks(
                            IrpContext,
                            NULL,
                            &Mcb->Inode,
                            Index,
                            max_blocks,
                            &bh_got,
                            Alloc,
                            flags)) < 0) {
        DEBUG(DL_ERR, ("Block insufficient resources, err: %d\n", rc));
        return Ext2WinntError(rc);
    }
    if (Alloc)
        Ext2SaveInode(IrpContext, Vcb, &Mcb->Inode);
    if (Number)
        *Number = rc ? rc : 1;
    if (Block)
        *Block = (ULONG)bh_got.b_blocknr;

    return STATUS_SUCCESS;
}
コード例 #3
0
static int
ext2_ext_balloc(struct inode *ip, uint32_t lbn, int size,
    struct ucred *cred, struct buf **bpp, int flags)
{
	struct m_ext2fs *fs;
	struct buf *bp = NULL;
	struct vnode *vp = ITOV(ip);
	daddr_t newblk;
	int osize, nsize, blks, error, allocated;

	fs = ip->i_e2fs;
	blks = howmany(size, fs->e2fs_bsize);

	error = ext4_ext_get_blocks(ip, lbn, blks, cred, NULL, &allocated, &newblk);
	if (error)
		return (error);

	if (allocated) {
		if (ip->i_size < (lbn + 1) * fs->e2fs_bsize)
			nsize = fragroundup(fs, size);
		else
			nsize = fs->e2fs_bsize;

		bp = getblk(vp, lbn, nsize, 0, 0, 0);
		if(!bp)
			return (EIO);

		bp->b_blkno = fsbtodb(fs, newblk);
		if (flags & BA_CLRBUF)
			vfs_bio_clrbuf(bp);
	} else {
		if (ip->i_size >= (lbn + 1) * fs->e2fs_bsize) {

			error = bread(vp, lbn, fs->e2fs_bsize, NOCRED, &bp);
			if (error) {
				brelse(bp);
				return (error);
			}
			bp->b_blkno = fsbtodb(fs, newblk);
			*bpp = bp;
			return (0);
		}

		/*
		 * Consider need to reallocate a fragment.
		 */
		osize = fragroundup(fs, blkoff(fs, ip->i_size));
		nsize = fragroundup(fs, size);
		if (nsize <= osize)
			error = bread(vp, lbn, osize, NOCRED, &bp);
		else
			error = bread(vp, lbn, fs->e2fs_bsize, NOCRED, &bp);
		if (error) {
			brelse(bp);
			return (error);
		}
		bp->b_blkno = fsbtodb(fs, newblk);
	}

	*bpp = bp;

	return (error);
}