/* alloc a new block */ int ext2_alloc_block ( unsigned int goal) { unsigned int block; unsigned int block_group; unsigned int bit; struct ext2_group_desc *desc; struct ext2_sb_info * sbi = EXT2_SBI(); void *bitmap; block_group = ext2_get_group_num (goal, BLOCK); bit = ext2_get_group_offset (goal, BLOCK); bitmap = ext2_read_block_bitmap (block_group); block = ext2_grab_block (bitmap, bit); if ( !block) ext2_error ("no free blocks any more"); desc = ext2_get_group_desc (block_group); desc->bg_free_blocks_count --; sbi->s_free_blocks_count --; ext2_set_bit (bitmap, block); return block; }
/* * This function zeros out the allocated block, and updates all of the * appropriate filesystem records. */ bool ext2_alloc_block(PEXT2_FILESYS fs, ULONG goal, ULONG *ret) { bool retval; ULONG block; char *buf = NULL; buf = (char *)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, fs->blocksize); if (!buf) return false; if (!fs->block_map) { retval = ext2_read_block_bitmap(fs); if (!retval) goto fail; } retval = ext2_new_block(fs, goal, 0, &block); if (!retval) goto fail; retval = NT_SUCCESS(Ext2WriteDisk( fs, ((LONGLONG)block * fs->blocksize), fs->blocksize, (unsigned char *)buf)); if (!retval) { goto fail; } ext2_block_alloc_stats(fs, block, +1); *ret = block; if (buf) { RtlFreeHeap(RtlGetProcessHeap(), 0, buf); } return true; fail: if (buf) { RtlFreeHeap(RtlGetProcessHeap(), 0, buf); } return false; }
/* free the goal block, clean it */ void ext2_free_block(unsigned int block) { unsigned int block_group; unsigned int bit; struct ext2_group_desc *desc; struct ext2_sb_info * sbi = EXT2_SBI(); void * bitmap; block_group = ext2_get_group_num (block, BLOCK); bit = ext2_get_group_offset (block, BLOCK); desc = ext2_get_group_desc (block_group); bitmap = ext2_read_block_bitmap (block_group); if ( !ext2_clear_bit(bitmap, bit) ) ext2_error("bit %d (%d) alread cleard", bit, block_group); desc->bg_free_blocks_count ++; sbi->s_free_blocks_count ++; }