コード例 #1
0
SFUNC(uint32_t, ext2_allocate_indirect_block, 
					ext2_device_t *device, 
					ext2_inode_t *inode)
{
	int status;
	size_t block_size = 1024 << device->superblock.block_size_enc;
	aoff_t size;
	uint32_t id;

	status = ext2_alloc_block(device, 0, &id);//TODO: Prevent fragmentation, swap 0 for previous block in inode

	if (status)
		THROW(status, 0);

	inode->blocks += 2 << device->superblock.block_size_enc;

	if (!ext2_zero_buffer) {
		ext2_zero_buffer = heapmm_alloc(block_size);
		memset(ext2_zero_buffer, 0, block_size);
	}

	status = ext2_write_block(device, id, 0, ext2_zero_buffer, block_size, &size);
	if (status) {
		THROW(status, 0);
	}

	RETURN(id);
}
コード例 #2
0
SFUNC(aoff_t, ext2_write_inode, inode_t *_inode, void *_buffer, aoff_t f_offset, aoff_t length)
{
	ext2_device_t *device;
	ext2_vinode_t *inode;
	aoff_t count;
	aoff_t block_size;
	aoff_t in_blk_size;
	aoff_t rsize;
	aoff_t in_blk;
	aoff_t in_file;
	uint32_t block_addr, p_block_addr;	
	uint8_t *buffer = _buffer;
	int status;

	assert( _inode != NULL );
	assert( buffer != NULL );

	device = (ext2_device_t *) _inode->device;
	inode = (ext2_vinode_t *) _inode;

	block_size = 1024 << device->superblock.block_size_enc;
	
	p_block_addr = 0;

	for (count = 0; count < length; count += in_blk_size) {
		in_file = count + f_offset;
		in_blk = in_file % block_size;				
		in_blk_size = length - count;

		if (in_blk_size > (block_size - in_blk))
			in_blk_size = block_size - in_blk;

		status = ext2_decode_block_id (device, &(inode->inode), in_file / block_size, &block_addr);
		if (status)
			THROW(status, 0);

		if (!block_addr) {
			//debugcon_printf("ext2: growing file!\n");
			status = ext2_alloc_block(device, p_block_addr, &block_addr);
			if (status) 
				THROW(status, 0);

			status = ext2_set_block_id(device, &(inode->inode), in_file / block_size, block_addr);
			if (status)
				THROW(status, 0);

			inode->inode.blocks += 2 << device->superblock.block_size_enc;
		}

		status = ext2_write_block(device, block_addr, in_blk, &(buffer[count]), in_blk_size, &rsize);

		if (status)
			THROW(status, 0);

		p_block_addr = block_addr;
	}
	
	RETURN(count);
}
コード例 #3
0
ファイル: Inode.c プロジェクト: HBelusca/NasuTek-Odyssey
bool ext2_write_inode (PEXT2_FILESYS Ext2Sys,
            ULONG               ino,
            ULONG               offset,
            PVOID               Buffer,
            ULONG               size,
            PULONG              dwReturn )
{
    PEXT2_BDL   ext2_bdl = NULL;
    ULONG       blocks, i;
    bool        bRet = true;
    EXT2_INODE  inode;
    ULONG       dwTotal = 0;
    ULONG       dwBlk = 0;
    ULONG       TotalBlks;

    blocks =  (size + offset + Ext2Sys->blocksize - 1) / Ext2Sys->blocksize;

    if (!ext2_load_inode(Ext2Sys, ino, &inode))
    {
        return false;
    }

    TotalBlks = inode.i_blocks / (Ext2Sys->blocksize / SECTOR_SIZE);
    TotalBlks = Ext2DataBlocks(Ext2Sys, TotalBlks);

    if (blocks > TotalBlks)
    {
        for (i=0; i < (blocks - TotalBlks);  i++)
        {
            if (ext2_alloc_block(Ext2Sys, 0, &dwBlk) )
            {
                ext2_expand_inode(Ext2Sys, &inode, dwBlk);
                inode.i_blocks += (Ext2Sys->blocksize/SECTOR_SIZE);
            }
        }
    }

    blocks = ext2_build_bdl(Ext2Sys, &inode, offset, size, &ext2_bdl);

    if (blocks <= 0)
        return  false;
    
    for(i = 0; i < blocks; i++)
    {
        bRet = NT_SUCCESS(Ext2WriteDisk(
                Ext2Sys,
                ext2_bdl[i].Lba, 
                ext2_bdl[i].Length,
                (PUCHAR)Buffer + ext2_bdl[i].Offset
               ));

        if (!bRet)
        {
            goto errorout;
        }

        dwTotal += ext2_bdl[i].Length;
    }

    *dwReturn = dwTotal;

    if (size + offset > inode.i_size)
    {
        inode.i_size = size + offset;
    }

    ext2_save_inode(Ext2Sys, ino, &inode);


errorout:
   
    if (ext2_bdl)
        RtlFreeHeap(RtlGetProcessHeap(), 0, ext2_bdl);

    return bRet;
}
コード例 #4
0
ファイル: Inode.c プロジェクト: HBelusca/NasuTek-Odyssey
bool ext2_expand_inode( PEXT2_FILESYS Ext2Sys,
                        PEXT2_INODE Inode,
                        ULONG newBlk         )
{
    ULONG dwSizes[4] = {12, 1, 1, 1};
    ULONG Index = 0;
    ULONG dwTotal = 0;
    ULONG dwBlk = 0, dwNewBlk = 0, Offset = 0;
    PEXT2_SUPER_BLOCK pExt2Sb = Ext2Sys->ext2_sb;
    int   i = 0;
    bool  bRet = true;
    bool  bDirty = false;
    ULONG TotalBlocks;

    TotalBlocks = Inode->i_blocks / (Ext2Sys->blocksize / SECTOR_SIZE);
    Index = Ext2DataBlocks(Ext2Sys, TotalBlocks);

    for (i = 0; i < 4; i++)
    {
        dwSizes[i] = dwSizes[i] << ((10 + pExt2Sb->s_log_block_size - 2) * i);
        dwTotal += dwSizes[i];
    }

    if (Index >= dwTotal)
    {
        DPRINT1("Mke2fs: ext2_expand_inode: beyond the maxinum size of an inode.\n");
        return false;
    }

    for (i = 0; i < 4; i++)
    {
        if (Index < dwSizes[i])
        {
            if (i == 0)
            {
                Inode->i_block[Index] = newBlk;
                bDirty = true;
            }
            else
            {
                dwBlk = Inode->i_block[(i + 12 - 1)];

                if (dwBlk == 0)
                {
                    if (ext2_alloc_block(Ext2Sys, 0, &dwBlk))
                    {
                        Inode->i_block[(i + 12 - 1)] = dwBlk;
                        bDirty = true;

                        Inode->i_blocks += (Ext2Sys->blocksize / SECTOR_SIZE);
                    }
                    else
                    {
                        break;
                    }
                }

                dwNewBlk = 0;
                bRet = ext2_expand_block(
                             Ext2Sys,
                             Inode,
                             dwBlk,
                             Index,
                             i,
                             newBlk,
                             &dwNewBlk,
                             &Offset   );
            }
            
            break;
        }

        Index -= dwSizes[i];
    }

    return bRet;
}
コード例 #5
0
ファイル: Inode.c プロジェクト: HBelusca/NasuTek-Odyssey
bool ext2_expand_block( PEXT2_FILESYS Ext2Sys, PEXT2_INODE Inode,
                        ULONG dwContent, ULONG Index, int layer,
                        ULONG newBlk, ULONG *dwRet, ULONG *off  )
{
    ULONG       *pData = NULL;
    ULONG       i = 0, j = 0, temp = 1;
    ULONG       dwBlk;
    ULONG       dwNewBlk = newBlk;
    bool        bDirty = false;
    bool        bRet = true;
    ULONG       Offset = 0;

    PEXT2_SUPER_BLOCK pExt2Sb = Ext2Sys->ext2_sb;
 
    pData = (ULONG *)RtlAllocateHeap(RtlGetProcessHeap(), 0, Ext2Sys->blocksize);
    
    if (!pData)
    {
        bRet = false;
        goto errorout;
    }
    
    if (!ext2_read_block(Ext2Sys, dwContent, (void *)pData))
    {
        bRet = false;
        goto errorout;
    }
    
    if (layer == 1)
    {
        *dwRet = dwContent;
        *off   = Index;
        pData[Index] = newBlk;

        bDirty = TRUE;
    }
    else if (layer <= 3)
    {
        temp = 1 << ((10 + pExt2Sb->s_log_block_size - 2) * (layer - 1));

        i = Index / temp;
        j = Index % temp;

        dwBlk = pData[i];
        
        if (dwBlk == 0)
        {
            if (ext2_alloc_block(Ext2Sys, 0, &dwBlk) )
            {
                pData[i] = dwBlk;
                bDirty = true;

                Inode->i_blocks += (Ext2Sys->blocksize / SECTOR_SIZE);
            }
            
            if (!bDirty)
                goto errorout;
        }
        
        if (!ext2_expand_block(Ext2Sys, Inode, dwBlk, j, layer - 1, bDirty, &dwNewBlk, &Offset))
        {
            bRet = false;
            DPRINT1("Mke2fs: ext2_expand_block: ... error recuise...\n");
            goto errorout;
        }
    }

    if (bDirty)
    {
        bRet = ext2_write_block(Ext2Sys, dwContent, (void *)pData);
    }


errorout:

    if (pData)
        RtlFreeHeap(RtlGetProcessHeap(), 0, pData);

    if (bRet && dwRet)
        *dwRet = dwNewBlk;

    return bRet;
}