⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ialloc.c.txt

📁 linux内核学习笔记 希望想看的人可以很快下载到
💻 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 + -