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

📄 namei.c

📁 带中文注释的 linux 0.11 源代码0.11,很好的
💻 C
📖 第 1 页 / 共 4 页
字号:
      bh->b_dirt = 1;      brelse (bh);      iput (dir);      *res_inode = inode;      return 0;    }// 若上面在目录中取文件名对应的目录项结构操作成功(也即bh 不为NULL),取出该目录项的i 节点号// 和其所在的设备号,并释放该高速缓冲区以及目录的i 节点。  inr = de->inode;  dev = dir->i_dev;  brelse (bh);  iput (dir);// 如果独占使用标志O_EXCL 置位,则返回文件已存在出错码,退出。  if (flag & O_EXCL)    return -EEXIST;// 如果取该目录项对应i 节点的操作失败,则返回访问出错码,退出。  if (!(inode = iget (dev, inr)))    return -EACCES;// 若该i 节点是一个目录的节点并且访问模式是只读或只写,或者没有访问的许可权限,则释放该i// 节点,返回访问权限出错码,退出。  if ((S_ISDIR (inode->i_mode) && (flag & O_ACCMODE)) ||      !permission (inode, ACC_MODE (flag)))    {      iput (inode);      return -EPERM;    }// 更新该i 节点的访问时间字段为当前时间。  inode->i_atime = CURRENT_TIME;// 如果设立了截0 标志,则将该i 节点的文件长度截为0。  if (flag & O_TRUNC)    truncate (inode);// 最后返回该目录项i 节点的指针,并返回0(成功)。  *res_inode = inode;  return 0;}//// 系统调用函数 - 创建一个特殊文件或普通文件节点(node)。// 创建名称为filename,由mode 和dev 指定的文件系统节点(普通文件、设备特殊文件或命名管道)。// 参数:filename - 路径名;mode - 指定使用许可以及所创建节点的类型;dev - 设备号。// 返回:成功则返回0,否则返回出错码。intsys_mknod (const char *filename, int mode, int dev){  const char *basename;  int namelen;  struct m_inode *dir, *inode;  struct buffer_head *bh;  struct dir_entry *de;// 如果不是超级用户,则返回访问许可出错码。  if (!suser ())    return -EPERM;// 如果找不到对应路径名目录的i 节点,则返回出错码。  if (!(dir = dir_namei (filename, &namelen, &basename)))    return -ENOENT;// 如果最顶端的文件名长度为0,则说明给出的路径名最后没有指定文件名,释放该目录i 节点,返回// 出错码,退出。  if (!namelen)    {      iput (dir);      return -ENOENT;    }// 如果在该目录中没有写的权限,则释放该目录的i 节点,返回访问许可出错码,退出。  if (!permission (dir, MAY_WRITE))    {      iput (dir);      return -EPERM;    }// 如果对应路径名上最后的文件名的目录项已经存在,则释放包含该目录项的高速缓冲区,释放目录// 的i 节点,返回文件已经存在出错码,退出。  bh = find_entry (&dir, basename, namelen, &de);  if (bh)    {      brelse (bh);      iput (dir);      return -EEXIST;    }// 申请一个新的i 节点,如果不成功,则释放目录的i 节点,返回无空间出错码,退出。  inode = new_inode (dir->i_dev);  if (!inode)    {      iput (dir);      return -ENOSPC;    }// 设置该i 节点的属性模式。如果要创建的是块设备文件或者是字符设备文件,则令i 节点的直接块// 指针0 等于设备号。  inode->i_mode = mode;  if (S_ISBLK (mode) || S_ISCHR (mode))    inode->i_zone[0] = dev;// 设置该i 节点的修改时间、访问时间为当前时间。  inode->i_mtime = inode->i_atime = CURRENT_TIME;  inode->i_dirt = 1;// 在目录中新添加一个目录项,如果失败(包含该目录项的高速缓冲区指针为NULL),则释放目录的// i 节点;所申请的i 节点引用连接计数复位,并释放该i 节点。返回出错码,退出。  bh = add_entry (dir, basename, namelen, &de);  if (!bh)    {      iput (dir);      inode->i_nlinks = 0;      iput (inode);      return -ENOSPC;    }// 令该目录项的i 节点字段等于新i 节点号,置高速缓冲区已修改标志,释放目录和新的i 节点,释放// 高速缓冲区,最后返回0(成功)。  de->inode = inode->i_num;  bh->b_dirt = 1;  iput (dir);  iput (inode);  brelse (bh);  return 0;}//// 系统调用函数 - 创建目录。// 参数:pathname - 路径名;mode - 目录使用的权限属性。// 返回:成功则返回0,否则返回出错码。intsys_mkdir (const char *pathname, int mode){  const char *basename;  int namelen;  struct m_inode *dir, *inode;  struct buffer_head *bh, *dir_block;  struct dir_entry *de;// 如果不是超级用户,则返回访问许可出错码。  if (!suser ())    return -EPERM;// 如果找不到对应路径名目录的i 节点,则返回出错码。  if (!(dir = dir_namei (pathname, &namelen, &basename)))    return -ENOENT;// 如果最顶端的文件名长度为0,则说明给出的路径名最后没有指定文件名,释放该目录i 节点,返回// 出错码,退出。  if (!namelen)    {      iput (dir);      return -ENOENT;    }// 如果在该目录中没有写的权限,则释放该目录的i 节点,返回访问许可出错码,退出。  if (!permission (dir, MAY_WRITE))    {      iput (dir);      return -EPERM;    }// 如果对应路径名上最后的文件名的目录项已经存在,则释放包含该目录项的高速缓冲区,释放目录// 的i 节点,返回文件已经存在出错码,退出。  bh = find_entry (&dir, basename, namelen, &de);  if (bh)    {      brelse (bh);      iput (dir);      return -EEXIST;    }// 申请一个新的i 节点,如果不成功,则释放目录的i 节点,返回无空间出错码,退出。  inode = new_inode (dir->i_dev);  if (!inode)    {      iput (dir);      return -ENOSPC;    }// 置该新i 节点对应的文件长度为32(一个目录项的大小),置节点已修改标志,以及节点的修改时间// 和访问时间。  inode->i_size = 32;  inode->i_dirt = 1;  inode->i_mtime = inode->i_atime = CURRENT_TIME;// 为该i 节点申请一磁盘块,并令节点第一个直接块指针等于该块号。如果申请失败,则释放对应目录// 的i 节点;复位新申请的i 节点连接计数;释放该新的i 节点,返回没有空间出错码,退出。  if (!(inode->i_zone[0] = new_block (inode->i_dev)))    {      iput (dir);      inode->i_nlinks--;      iput (inode);      return -ENOSPC;    }// 置该新的i 节点已修改标志。  inode->i_dirt = 1;// 读新申请的磁盘块。若出错,则释放对应目录的i 节点;释放申请的磁盘块;复位新申请的i 节点// 连接计数;释放该新的i 节点,返回没有空间出错码,退出。  if (!(dir_block = bread (inode->i_dev, inode->i_zone[0])))    {      iput (dir);      free_block (inode->i_dev, inode->i_zone[0]);      inode->i_nlinks--;      iput (inode);      return -ERROR;    }// 令de 指向目录项数据块,置该目录项的i 节点号字段等于新申请的i 节点号,名字字段等于"."。  de = (struct dir_entry *) dir_block->b_data;  de->inode = inode->i_num;  strcpy (de->name, ".");// 然后de 指向下一个目录项结构,该结构用于存放上级目录的节点号和名字".."。  de++;  de->inode = dir->i_num;  strcpy (de->name, "..");  inode->i_nlinks = 2;// 然后设置该高速缓冲区已修改标志,并释放该缓冲区。  dir_block->b_dirt = 1;  brelse (dir_block);// 初始化设置新i 节点的模式字段,并置该i 节点已修改标志。  inode->i_mode = I_DIRECTORY | (mode & 0777 & ~current->umask);  inode->i_dirt = 1;// 在目录中新添加一个目录项,如果失败(包含该目录项的高速缓冲区指针为NULL),则释放目录的// i 节点;所申请的i 节点引用连接计数复位,并释放该i 节点。返回出错码,退出。  bh = add_entry (dir, basename, namelen, &de);  if (!bh)    {      iput (dir);      free_block (inode->i_dev, inode->i_zone[0]);      inode->i_nlinks = 0;      iput (inode);      return -ENOSPC;    }// 令该目录项的i 节点字段等于新i 节点号,置高速缓冲区已修改标志,释放目录和新的i 节点,释放// 高速缓冲区,最后返回0(成功)。  de->inode = inode->i_num;  bh->b_dirt = 1;  dir->i_nlinks++;  dir->i_dirt = 1;  iput (dir);  iput (inode);  brelse (bh);  return 0;}/** routine to check that the specified directory is empty (for rmdir)*//** 用于检查指定的目录是否为空的子程序(用于rmdir 系统调用函数)。*///// 检查指定目录是否是空的。// 参数:inode - 指定目录的i 节点指针。// 返回:0 - 是空的;1 - 不空。static intempty_dir (struct m_inode *inode){  int nr, block;  int len;  struct buffer_head *bh;  struct dir_entry *de;// 计算指定目录中现有目录项的个数(应该起码有2 个,即"."和".."两个文件目录项)。  len = inode->i_size / sizeof (struct dir_entry);// 如果目录项个数少于2 个或者该目录i 节点的第1 个直接块没有指向任何磁盘块号,或者相应磁盘// 块读不出,则显示警告信息“设备dev 上目录错”,返回0(失败)。  if (len < 2 || !inode->i_zone[0] ||      !(bh = bread (inode->i_dev, inode->i_zone[0])))    {      printk ("warning - bad directory on dev %04x\n", inode->i_dev);      return 0;    }// 让de 指向含有读出磁盘块数据的高速缓冲区中第1 项目录项。  de = (struct dir_entry *) bh->b_data;// 如果第1 个目录项的i 节点号字段值不等于该目录的i 节点号,或者第2 个目录项的i 节点号字段// 为零,或者两个目录项的名字字段不分别等于"."和"..",则显示出错警告信息“设备dev 上目录错”// 并返回0。  if (de[0].inode != inode->i_num || !de[1].inode ||      strcmp (".", de[0].name) || strcmp ("..", de[1].name))    {      printk ("warning - bad directory on dev %04x\n", inode->i_dev);      return 0;    }// 令nr 等于目录项序号;de 指向第三个目录项。  nr = 2;  de += 2;// 循环检测该目录中所有的目录项(len-2 个),看有没有目录项的i 节点号字段不为0(被使用)。  while (nr < len)    {// 如果该块磁盘块中的目录项已经检测完,则释放该磁盘块的高速缓冲区,读取下一块含有目录项的// 磁盘块。若相应块没有使用(或已经不用,如文件已经删除等),则继续读下一块,若读不出,则出// 错,返回0。否则让de 指向读出块的首个目录项。      if ((void *) de >= (void *) (bh->b_data + BLOCK_SIZE))	{	  brelse (bh);	  block = bmap (inode, nr / DIR_ENTRIES_PER_BLOCK);	  if (!block)	    {	      nr += DIR_ENTRIES_PER_BLOCK;	      continue;	    }	  if (!(bh = bread (inode->i_dev, block)))	    return 0;	  de = (struct dir_entry *) bh->b_data;	}// 如果该目录项的i 节点号字段不等于0,则表示该目录项目前正被使用,则释放该高速缓冲区,// 返回0,退出。      if (de->inode)	{	  brelse (bh);	  return 0;	}// 否则,若还没有查询完该目录中的所有目录项,则继续检测。      de++;      nr++;    }// 到这里说明该目录中没有找到已用的目录项(当然除了头两个以外),则返回缓冲区,返回1。  brelse (bh);  return 1;

⌨️ 快捷键说明

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