📄 ialloc.c.txt
字号:
any problems,send mails to sindybear@163.com
相关文件
/fs/ext2/super.c
这个文件包含inode的分配和回收等一些列函数
*************************分配回收位图函数**********************************
(1)static struct buffer_head *load_inode_bitmap (struct super_block * sb,
unsigned int block_group)
struct ext2_sb_info *sbi = &sb->u.ext2_sb; //得到ext2_sb_info结构
struct buffer_head *bh = sbi->s_inode_bitmap[0]; //得到位图的第一个位置的数据
…… //进行合法性检测
if (sbi->s_loaded_inode_bitmaps > 0 &&
sbi->s_inode_bitmap_number[0] == block_group && bh)
goto found; //如果第一个位图位置就是要求的位图,就返回这个bh
if (sbi->s_groups_count <= EXT2_MAX_GROUP_LOADED) //如果块组数目少于可装载的数量
slot = block_group; //说明缓冲区没有用完
bh = sbi->s_inode_bitmap[slot]; //找一个地方存放这个节点的缓冲
if (!bh)
goto read_it; //如果没有读的话,从磁盘上读出来
…… //如果没有地方了,选择一个地方放置,
while (i--) {
sbi->s_inode_bitmap_number[i+1] = sbi->s_inode_bitmap_number[i];
sbi->s_inode_bitmap[i+1] = sbi->s_inode_bitmap[i];
} //选择丢弃的是最后的一个位图,然后,每一个位图往后面错一位,
read_it:
if (!bh)
bh = read_inode_bitmap (sb, block_group);
sbi->s_inode_bitmap_number[slot] = block_group; //放到第一个位置(0)
sbi->s_inode_bitmap[slot] = bh;
(2)static struct buffer_head *read_inode_bitmap (struct super_block * sb,
unsigned long block_group)
desc = ext2_get_group_desc(sb, block_group, NULL); //先从块组号的到相应的组描述符
bh = sb_bread(sb, le32_to_cpu(desc->bg_inode_bitmap)); //从组描述符中读出inode位图
//bg_inode_bitmap是位图所在的块号
***********************************************************************
************************分配一个新的inode的函数****************************
(1)struct inode * ext2_new_inode (const struct inode * dir, int mode)
sb = dir->i_sb; //得到超级块
inode = new_inode(sb); //分配一个新的inode节点
lock_super (sb); //锁定超级块
if (S_ISDIR(mode)) //分两种情况处理,一种是产生的是一个目录,或者产生别的文件
group = find_group_dir(sb, dir->u.ext2_i.i_block_group);
else
group = find_group_other(sb, dir->u.ext2_i.i_block_group);
…… //对得到的group(也就是要建立在那一个块组中)进行检测
bh = load_inode_bitmap (sb, group); //从磁盘上读取这个块组的inode位图
i = ext2_find_first_zero_bit ((unsigned long *) bh->b_data,
EXT2_INODES_PER_GROUP(sb)); //找出第一个空闲的inode节点
if (i >= EXT2_INODES_PER_GROUP(sb)) //检测是否超出范围
goto bad_count;
ext2_set_bit (i, bh->b_data); //把这一位置一,说明占用了
mark_buffer_dirty(bh); //将这inode位图标志为脏,从而系统结束时要写会磁盘
ino = group * EXT2_INODES_PER_GROUP(sb) + i + 1;//计算inode的number值,注意计算方法
//ino是按顺序排列的,也就是ino的值就是
//他在磁盘上的索引值
if (ino < EXT2_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count))
//对号码进行检测,如果出错就告警
if (sb->s_flags & MS_SYNCHRONOUS) { //写回磁盘
ll_rw_block (WRITE, 1, &bh);
wait_on_buffer (bh);
}
es->s_free_inodes_count = //空闲的inode数目减一
cpu_to_le32(le32_to_cpu(es->s_free_inodes_count) - 1);
mark_buffer_dirty(sb->u.ext2_sb.s_sbh); //把超级块标志为脏,
sb->s_dirt = 1;
…… //对产生的inode进行一系列的设置
insert_inode_hash(inode); //把这个inode插入到hash表中
mark_inode_dirty(inode); //标志这个inode脏
unlock_super (sb); //超级块解锁
return inode; //返回inode节点
//如果是建立一个目录的话,开始是无所谓在那里建立的,所以总是寻找最多空闲数据块的块组,
//不比顾及parent_group的数值
(2)static int find_group_dir(struct super_block *sb, int parent_group)
int ngroups = sb->u.ext2_sb.s_groups_count; //总共有几个块组
int avefreei = le32_to_cpu(es->s_free_inodes_count) / ngroups; //平均每块组的空闲块
for (group = 0; group < ngroups; group++) //循环查询得到空闲的数据块最多的块组
desc = ext2_get_group_desc (sb, group, &bh); //先得到相应的块组的描述符
if (le16_to_cpu(desc->bg_free_inodes_count) < avefreei)
continue; //如果连平均数量都达不到,就继续寻找
if (!best_desc ||
(le16_to_cpu(desc->bg_free_blocks_count) >
le16_to_cpu(best_desc->bg_free_blocks_count))) {
best_group = group;
best_desc = desc;
best_bh = bh;
} //找到以后把最好的块组,相应的描述符和buffer纪录到best_**中
if (!best_desc) //找不到的话,出错
return -1;
best_desc->bg_free_inodes_count = //把空闲的inode数量减一
cpu_to_le16(le16_to_cpu(best_desc->bg_free_inodes_count) - 1);
best_desc->bg_used_dirs_count = //把使用的dirs数目加一
cpu_to_le16(le16_to_cpu(best_desc->bg_used_dirs_count) + 1);
mark_buffer_dirty(best_bh); //标志块组描述符所在的buffer为脏,以便写入到磁盘上
return best_group;
//但是如果是建立一个文件的话,最好建立在它的父目录的同一个块组中,
(3)static int find_group_other(struct super_block *sb, int parent_group)
group = parent_group; //尽量在父目录的范围内进行搜索
desc = ext2_get_group_desc (sb, group, &bh);
if (desc && le16_to_cpu(desc->bg_free_inodes_count))
goto found;
for (i = 1; i < ngroups; i <<= 1) { //如果不行,就在groups中跳跃搜索
group += i;
if (group >= ngroups)
group -= ngroups;
desc = ext2_get_group_desc (sb, group, &bh);
if (desc && le16_to_cpu(desc->bg_free_inodes_count))
goto found;
}
group = parent_group + 1; //如果还不行,就只有一个个挨着搜索了。
for (i = 2; i < ngroups; i++) {
if (++group >= ngroups)
group = 0;
desc = ext2_get_group_desc (sb, group, &bh);
if (desc && le16_to_cpu(desc->bg_free_inodes_count))
goto found;
}
return -1 //所有的办法都不行的话,就只有出错
found:
desc->bg_free_inodes_count = //空闲的inode减一
cpu_to_le16(le16_to_cpu(desc->bg_free_inodes_count) - 1);
mark_buffer_dirty(bh); //inode所在的buffer置为脏
return group;
***************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -