[关闭]
@harpsword 2015-11-14T15:18:23.000000Z 字数 1748 阅读 1940

文件系统底层操作函数部分之二(truncate.c)

文件系统


简介

这篇文章承接之一,主要介绍 truncate.c文件。

功能描述
本程序用于删除文件,通过释放该文件对应的i节点在设备上占有的所有逻辑块,包括直接块、间接块。通过i节点寻找逻辑块的方式在 linux0.11内核之文件系统中有介绍,如下是示意图。
示意图

代码注释

  1. /*
  2. * linux/fs/truncate.c
  3. *
  4. * (C) 1991 Linus Torvalds
  5. */
  6. #include <linux/sched.h>
  7. #include <sys/stat.h>
  8. //// 释放所有一次间接块
  9. // 参数dev是文件系统所在设备的设备号;block是逻辑块号
  10. static void free_ind(int dev,int block)
  11. {
  12. struct buffer_head * bh;
  13. unsigned short * p;
  14. int i;
  15. // 首先判断参数的有效性
  16. if (!block)
  17. return;
  18. // 然后读取一次间接块,并释放其上表明使用的所有逻辑块,然后释放该一次间接块
  19. // 的缓冲块,函数free_block用于释放设备上指定逻辑块号的磁盘块。
  20. if ((bh=bread(dev,block))) {
  21. p = (unsigned short *) bh->b_data; // 指向缓冲块数据区
  22. for (i=0;i<512;i++,p++) // 每个逻辑块上可有512个块号
  23. if (*p)
  24. free_block(dev,*p); // 释放指定的设备逻辑块
  25. brelse(bh); // 然后释放间接块占用的缓冲块
  26. }
  27. // 最后释放设备上的一次间接块
  28. free_block(dev,block);
  29. }
  30. //// 释放所有第二次间接块
  31. // 参数同free_ind函数
  32. static void free_dind(int dev,int block)
  33. {
  34. struct buffer_head * bh;
  35. unsigned short * p;
  36. int i;
  37. if (!block)
  38. return;
  39. // 读取二次间接块的一级块,并释放其上表明使用的所有的逻辑块,然后释放该一级块的缓冲区
  40. if ((bh=bread(dev,block))) {
  41. p = (unsigned short *) bh->b_data;
  42. for (i=0;i<512;i++,p++)
  43. // 假如使用 if (p) ,会成功
  44. // 但是 p == (unsigned short *) 0 可能有效
  45. if (*p)
  46. free_ind(dev,*p); // 释放所有一次间接块
  47. // 释放二次间接块占用的缓冲块
  48. brelse(bh);
  49. }
  50. // 最后释放设备上的二次间接块
  51. free_block(dev,block);
  52. }
  53. //// 截断文件数据函数
  54. // 将节点对应的文件长度截为0,并释放所占用的设备空间
  55. void truncate(struct m_inode * inode)
  56. {
  57. int i;
  58. // 首先判断指定i节点的有效性,如果不是常规文件或者是目录文件,则返回
  59. if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)))
  60. return;
  61. // 然后释放i节点的7个直接逻辑块,并将这7个逻辑块项全置零。
  62. for (i=0;i<7;i++)
  63. if (inode->i_zone[i]) { // 如果块号不为0,则释放
  64. free_block(inode->i_dev,inode->i_zone[i]);
  65. inode->i_zone[i]=0;
  66. }
  67. free_ind(inode->i_dev,inode->i_zone[7]); // 释放所有一次间接块
  68. free_dind(inode->i_dev,inode->i_zone[8]); // 释放所有二次间接块
  69. inode->i_zone[7] = inode->i_zone[8] = 0; // 逻辑块项7、8置零
  70. inode->i_size = 0; // 文件大小置零
  71. inode->i_dirt = 1; // 置节点已修改标志
  72. // 最后重置文件修改时间和i节点改变时间为当前时间。宏CURRENT_TIME定义在
  73. // include/linux/sched.h中,用于取得从1970:0:0:0开始到现在为止经过的秒数。
  74. inode->i_mtime = inode->i_ctime = CURRENT_TIME;
  75. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注