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

📄 inode.c

📁 带中文注释的Linux+0.11+源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    {      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;		/* sum of readers/writers *//* 读/写两者总计 */  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 voidread_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 voidwrite_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 + -