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

📄 inode.c

📁 linux0.11原码
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (!inode->i_dev) {		inode->i_count--;		return;	}
// 如果是块设备文件的i 节点,此时逻辑块字段0 中是设备号,则刷新该设备。并等待i 节点解锁。	if (S_ISBLK(inode->i_mode)) {		sync_dev(inode->i_zone[0]);		wait_on_inode(inode);	}repeat:
// 如果i 节点的引用计数大于1,则递减1。	if (inode->i_count>1) {		inode->i_count--;		return;	}
// 如果i 节点的链接数为0,则释放该i 节点的所有逻辑块,并释放该i 节点。	if (!inode->i_nlinks) {		truncate(inode);		free_inode(inode);		return;	}
// 如果该i 节点已作过修改,则更新该i 节点,并等待该i 节点解锁。	if (inode->i_dirt) {		write_inode(inode);	/* we can sleep - so do again */		wait_on_inode(inode);		goto repeat;	}
// i 节点引用计数递减1。	inode->i_count--;	return;}
//// 从i 节点表(inode_table)中获取一个空闲i 节点项。
// 寻找引用计数count 为0 的i 节点,并将其写盘后清零,返回其指针。struct m_inode * get_empty_inode(void){	struct m_inode * inode;	static struct m_inode * last_inode = inode_table;// last_inode 指向i 节点表第一项。	int i;	do {
		// 扫描i 节点表。		inode = NULL;		for (i = NR_INODE; i ; i--) {
// 如果last_inode 已经指向i 节点表的最后1 项之后,则让其重新指向i 节点表开始处。			if (++last_inode >= inode_table + NR_INODE)				last_inode = inode_table;
// 如果last_inode 所指向的i 节点的计数值为0,则说明可能找到空闲i 节点项。让inode 指向
// 该i 节点。如果该i 节点的已修改标志和锁定标志均为0,则我们可以使用该i 节点,于是退出循环。			if (!last_inode->i_count) {				inode = last_inode;				if (!inode->i_dirt && !inode->i_lock)					break;			}		}
// 如果没有找到空闲i 节点(inode=NULL),则将整个i 节点表打印出来供调试使用,并死机。		if (!inode) {			for (i=0 ; i<NR_INODE ; i++)				printk("%04x: %6d\t",inode_table[i].i_dev,					inode_table[i].i_num);			panic("No free inodes in mem");		}
// 等待该i 节点解锁(如果又被上锁的话)。		wait_on_inode(inode);
// 如果该i 节点已修改标志被置位的话,则将该i 节点刷新,并等待该i 节点解锁。		while (inode->i_dirt) {			write_inode(inode);			wait_on_inode(inode);		}	} while (inode->i_count);// 如果i 节点又被其它占用的话,则重新寻找空闲i 节点。
// 已找到空闲i 节点项。则将该i 节点项内容清零,并置引用标志为1,返回该i 节点指针。	memset(inode,0,sizeof(*inode));	inode->i_count = 1;	return inode;}
//// 获取管道节点。返回为i 节点指针(如果是NULL 则失败)。
// 首先扫描i 节点表,寻找一个空闲i 节点项,然后取得一页空闲内存供管道使用。
// 然后将得到的i 节点的引用计数置为2(读者和写者),初始化管道头和尾,置i 节点的管道类型表示。struct m_inode * get_pipe_inode(void){	struct m_inode * inode;	if (!(inode = get_empty_inode()))	// 如果找不到空闲i 节点则返回NULL。		return NULL;	if (!(inode->i_size=get_free_page())) {// 节点的i_size 字段指向缓冲区。		inode->i_count = 0;					// 如果已没有空闲内存,则		return NULL;						// 释放该i 节点,并返回NULL。	}	inode->i_count = 2;	/* 读/写两者总计 */	PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;// 复位管道头尾指针。	inode->i_pipe = 1;			// 置节点为管道使用的标志。	return inode;		// 返回i 节点指针。}
//// 从设备上读取指定节点号的i 节点。
// nr - i 节点号。struct m_inode * iget(int dev,int nr){	struct m_inode * inode, * empty;	if (!dev)		panic("iget with dev==0");
// 从i 节点表中取一个空闲i 节点。	empty = get_empty_inode();
// 扫描i 节点表。寻找指定节点号的i 节点。并递增该节点的引用次数。	inode = inode_table;	while (inode < NR_INODE+inode_table) {
// 如果当前扫描的i 节点的设备号不等于指定的设备号或者节点号不等于指定的节点号,则继续扫描。		if (inode->i_dev != dev || inode->i_num != nr) {			inode++;			continue;		}
// 找到指定设备号和节点号的i 节点,等待该节点解锁(如果已上锁的话)。		wait_on_inode(inode);
// 在等待该节点解锁的阶段,节点表可能会发生变化,所以再次判断,如果发生了变化,则再次重新
// 扫描整个i 节点表。		if (inode->i_dev != dev || inode->i_num != nr) {			inode = inode_table;			continue;		}
// 将该i 节点引用计数增1。		inode->i_count++;		if (inode->i_mount) {			int i;
// 如果该i 节点是其它文件系统的安装点,则在超级块表中搜寻安装在此i 节点的超级块。如果没有
// 找到,则显示出错信息,并释放函数开始获取的空闲节点,返回该i 节点指针。			for (i = 0 ; i<NR_SUPER ; i++)				if (super_block[i].s_imount==inode)					break;			if (i >= NR_SUPER) {				printk("Mounted inode hasn't got sb\n");				if (empty)					iput(empty);				return inode;			}
// 将该i 节点写盘。从安装在此i 节点文件系统的超级块上取设备号,并令i 节点号为1。然后重新
// 扫描整个i 节点表,取该被安装文件系统的根节点。			iput(inode);			dev = super_block[i].s_dev;			nr = ROOT_INO;			inode = inode_table;			continue;		}
// 已经找到相应的i 节点,因此放弃临时申请的空闲节点,返回该找到的i 节点。		if (empty)			iput(empty);		return inode;	}
// 如果在i 节点表中没有找到指定的i 节点,则利用前面申请的空闲i 节点在i 节点表中建立该节点。
// 并从相应设备上读取该i 节点信息。返回该i 节点。	if (!empty)		return (NULL);	inode=empty;	inode->i_dev = dev;	inode->i_num = nr;	read_inode(inode);	return inode;}
//// 从设备上读取指定i 节点的信息到内存中(缓冲区中)。static void read_inode(struct m_inode * inode){	struct super_block * sb;	struct buffer_head * bh;	int block;
// 首先锁定该i 节点,取该节点所在设备的超级块。	lock_inode(inode);	if (!(sb=get_super(inode->i_dev)))		panic("trying to read inode without dev");
// 该i 节点所在的逻辑块号= (启动块+超级块) + i 节点位图占用的块数+ 逻辑块位图占用的块数+
// (i 节点号-1)/每块含有的i 节点数。	block = 2 + sb->s_imap_blocks + sb->s_zmap_blocks +		(inode->i_num-1)/INODES_PER_BLOCK;
// 从设备上读取该i 节点所在的逻辑块,并将该inode 指针指向对应i 节点信息。	if (!(bh=bread(inode->i_dev,block)))		panic("unable to read i-node block");	*(struct d_inode *)inode =		((struct d_inode *)bh->b_data)			[(inode->i_num-1)%INODES_PER_BLOCK];
// 最后释放读入的缓冲区,并解锁该i 节点。	brelse(bh);	unlock_inode(inode);}
//// 将指定i 节点信息写入设备(写入缓冲区相应的缓冲块中,待缓冲区刷新时会写入盘中)。static void write_inode(struct m_inode * inode){	struct super_block * sb;	struct buffer_head * bh;	int block;
// 首先锁定该i 节点,如果该i 节点没有被修改过或者该i 节点的设备号等于零,则解锁该i 节点,
// 并退出。	lock_inode(inode);	if (!inode->i_dirt || !inode->i_dev) {		unlock_inode(inode);		return;	}
// 获取该i 节点的超级块。	if (!(sb=get_super(inode->i_dev)))		panic("trying to write inode without device");
// 该i 节点所在的逻辑块号= (启动块+超级块) + i 节点位图占用的块数+ 逻辑块位图占用的块数+
// (i 节点号-1)/每块含有的i 节点数。	block = 2 + sb->s_imap_blocks + sb->s_zmap_blocks +		(inode->i_num-1)/INODES_PER_BLOCK;
// 从设备上读取该i 节点所在的逻辑块。	if (!(bh=bread(inode->i_dev,block)))		panic("unable to read i-node block");
// 将该i 节点信息复制到逻辑块对应该i 节点的项中。	((struct d_inode *)bh->b_data)		[(inode->i_num-1)%INODES_PER_BLOCK] =			*(struct d_inode *)inode;
// 置缓冲区已修改标志,而i 节点修改标志置零。然后释放该含有i 节点的缓冲区,并解锁该i 节点。	bh->b_dirt=1;	inode->i_dirt=0;	brelse(bh);	unlock_inode(inode);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -