#include "ext2.h"
#include "bitmap.h"
#include "cache.h"
extern struct ext2_fs fs;
/*
* 修改bitmap, 保留块组(group) 里面的super block backup
* group desc blocks backup, block bitmap, inode bitmap
* inode table
* 返回除去这些块以外改块组中的剩余块(空块)数目
*/
long reserve_super_and_bgd(long group)
{
int i;
long block;
long cnt = 0;
/* 保留启动块 */
/*
if(group == 0 && fs.super_i->s_es->s_first_data_block != 0)
{
_bitmap_block_used(group, 0);
cnt++;
}
*/
/* 保留超级块 */
block = fs.super_i->s_es->s_first_data_block + group * fs.super_i->s_blocks_per_group;
_bitmap_block_used(group, block);
cnt++;
/* 保留组描述符所使用的块 */
block++;
for(i = 0; i < fs.super_i->s_gdb_count; i++)
{
_bitmap_block_used(group, block + i);
}
cnt += i;
/* 保留数据块位图所使用的(1)块 */
block += i;
_bitmap_block_used(group, block);
cnt++;
/* 保留inode位图所使用的(1)块 */
block++;
_bitmap_block_used(group, block);
cnt++;
/* 保留inode table所使用的块 */
block++;
for(i = 0; i < fs.super_i->s_itb_per_group; i++)
{
_bitmap_block_used(group, block + i);
}
cnt += i;
if(group == fs.super_i->s_groups_count - 1)
{
//padding at the end of the last group block bitmap
long tmp;
tmp = fs.super_i->s_es->s_blocks_count
- fs.super_i->s_es->s_first_data_block
- group * fs.super_i->s_blocks_per_group;
block = fs.super_i->s_es->s_first_data_block + group * fs.super_i->s_blocks_per_group;
for(i = 0; i < fs.super_i->s_blocks_per_group - tmp; i++)
{
_bitmap_block_used(group, block + i + tmp);
cnt++;
}
}
return fs.super_i->s_frags_per_group - cnt;
}
void _bitmap_block_used(long group, long block)
{
unsigned char *buf;
long block_in_group;
read_group_block_bitmap(group, &buf);
block_in_group = block - fs.super_i->s_es->s_first_data_block
- group * fs.super_i->s_blocks_per_group;
buf[block_in_group / 8] |= (1 << (block_in_group % 8));
write_group_block_bitmap(group, 0);
//fs.group_desc_cache.cache.group_desc[group].bg_free_blocks_count--;
//fs.super_i->s_es->s_free_blocks_count--;
}
void bitmap_block_used(long group, long block)
{
unsigned char *buf;
long block_in_group;
read_group_block_bitmap(group, &buf);
block_in_group = block - fs.super_i->s_es->s_first_data_block
- group * fs.super_i->s_blocks_per_group;
buf[block_in_group / 8] |= (1 << (block_in_group % 8));
write_group_block_bitmap(group, 0);
fs.group_desc_cache.cache.group_desc[group].bg_free_blocks_count--;
fs.super_i->s_es->s_free_blocks_count--;
}
void bitmap_block_unused(long group, long block)
{
unsigned char *buf;
long block_in_group;
read_group_block_bitmap(group, &buf);
block_in_group = block - fs.super_i->s_es->s_first_data_block
- group * fs.super_i->s_blocks_per_group;
buf[block_in_group / 8] &= ~(1 << (block_in_group % 8));
write_group_block_bitmap(group, 0);
fs.group_desc_cache.cache.group_desc[group].bg_free_blocks_count++;
fs.super_i->s_es->s_free_blocks_count++;
}
void bitmap_inode_used(long group, long inode)
{
unsigned char *buf;
long inode_in_group;
read_group_inode_bitmap(group, &buf);
inode_in_group = inode - group * fs.super_i->s_inodes_per_group - 1;
buf[inode_in_group / 8] |= (1 << (inode_in_group % 8));
write_group_inode_bitmap(group, 0);
fs.group_desc_cache.cache.group_desc[group].bg_free_inodes_count--;
fs.super_i->s_es->s_free_inodes_count--;
}
void bitmap_inode_unused(long group, long inode)
{
unsigned char *buf;
long inode_in_group;
read_group_inode_bitmap(group, &buf);
inode_in_group = inode - group * fs.super_i->s_inodes_per_group - 1;
buf[inode_in_group / 8] &= ~(1 << (inode_in_group % 8));
write_group_inode_bitmap(group, 0);
fs.group_desc_cache.cache.group_desc[group].bg_free_inodes_count++;
fs.super_i->s_es->s_free_inodes_count++;
}
int block_stat(long group, long block)
{
unsigned char *buf;
long block_in_group;
read_group_block_bitmap(group, &buf);
block_in_group = block - fs.super_i->s_es->s_first_data_block
- group * fs.super_i->s_blocks_per_group;
return buf[block_in_group / 8] & (1 << (block_in_group % 8));
}