Linux的ROMFS代码分析

以下是我自己第一次接触源代码时自己加的,仅供参考,应该有很多漏洞的,希望高人指点啊

#include <linux/module.h>  //加载内核模块
#include <linux/types.h> 
#include <linux/errno.h>//定义Linux些出错码的常量符号库
#include <linux/slab.h>//动态分配和释放
#include <linux/romfs_fs.h> //只读文件库
#include <linux/fs.h>   //文件库
#include <linux/locks.h>//提供锁定和强制锁定的支持
#include <linux/init.h>//初始化
#include <linux/smp_lock.h>//同步信号锁

#include <asm/uaccess.h>//符号连接 

static __s32//不用s32是为了防止污染用户的命名空间,好像用s32还要有什么文件的引入的,还是不很明白
romfs_checksum(void *data, int size)//校验文件数据
{   //checksum是前512字节的校验和,用于确认整个文件系统结构数据的正确性
 __s32 sum, *ptr;     //定义一个指针指向数据

 sum = 0; ptr = data;
 size>>=2;
 while (size>0) {        //读文件
  sum += ntohl(*ptr++);//指针自加,向下查找
   //ntohl将一个无符号长整形从网络字节顺序转换为主机字节顺序
  size--;//剩余大小减小
 }
 return sum;   //返回校验和
}
//声明超级操作结构
static struct super_operations romfs_ops;

static struct super_block *   //超级块——记录文件的管理信息
romfs_read_super(struct super_block *s, void *data, int silent)
{
 struct buffer_head *bh;  /
 kdev_t dev = s->s_dev;  //Linux内核采用的另一种不同的资料型别,//指向超级块所在的设备号
 struct romfs_super_block *rsb;//此处定义一个指向文件超级块的全局指针
 int sz;

 

 set_blocksize(dev, ROMBSIZE); //设置超级块的大小
 s->s_blocksize = ROMBSIZE;     //块大小
 s->s_blocksize_bits = ROMBSBITS;//块大小的字节数
 s->u.generic_sbp = (void *) 0;/
 s->s_maxbytes = 0xFFFFFFFF;//最大字节数

 bh = sb_bread(s, 0);//读/dev/sdbx当前扩展区或主分区的0区块
 if (!bh) {          //缓冲头指针无效
 
                printk ("romfs: unable to read superblock\n");
  goto outnobh;//执行outnobh操作
 }

 rsb = (struct romfs_super_block *)bh->b_data;  //读取文件
 sz = ntohl(rsb->size);//获取数据项在主机中的顺序,将该值赋给sz,此处可以理解为该数据项的大小
                //该数据项为ROMFS的首部,表述的是ROMFS超级块的信息,操作系统通过其来识别文件类型
 //此处的功能就相当于,判别文件的卷名
 if (rsb->word0 != ROMSB_WORD0 || rsb->word1 != ROMSB_WORD1//word0和word1在内核中定义为-rom1fs-
    || sz < ROMFH_SIZE) { //文件类型不是只读或数据的大小小于4bits,即能被16整除,#define ROMFH_SIZE 16
  if (!silent)//则在设备中找不到该只读文件,只有silent不为0是才不显示找不到这条报错语句
   //silent在上面并没有初始化,所以随机应该为负的,!silent就是正的,就是执行以下语句,可是有什么意义?
   //表明在设备中找不到,如果不输出此语句就表示有可能已经在设备中找到,只是不能匹配所以不能读出?
   printk ("VFS: Can't find a romfs filesystem on dev "
    "%s.\n", kdevname(dev));
  goto out;//执行out操作
 }//初步匹配成功,进一步检测第sz到第512个字节文件数据,否则无需进行接下来的校验,可以节省时间和资源
 if (romfs_checksum(rsb, min_t(int, sz, 512))) {//调用romfs_checksum()检测失败,则报错
  printk ("romfs: bad initial checksum on dev "
   "%s.\n", kdevname(dev));//检测失败,则报错
  goto out;//执行out操作,表示通过检测,读取超级块成功,释放缓冲区允许其他操作
 }
 //到此为止,已经完成了文件首部的检验
    //进一步检测失败,需要调整超级块
 s->s_magic = ROMFS_MAGIC; //表明是romfs类型
    //s_magic记录了从设备中读取的标识号,以便确认从设备上的数据与涉及的文件系统相符
 s->u.romfs_sb.s_maxsize = sz;//只读文件系统超级块的最大值

 s->s_flags |= MS_RDONLY;//设置了MS_RDONLY类型的文件只以只读的形式装载,不允许写入,也不会进行间接修改
  //s_flags是一个标识列表,这些标志与各个信息节点中的标志进行逻辑或操作,一确定某种行为
 
 //找文件系统的开始处,再次运用sz变量只是此时不再表示数据项的大小,而是表示开始读取的位置
 sz = (ROMFH_SIZE +//#define ROMFH_PAD (ROMFH_SIZE-1)  #define ROMFS_MAXFN (~ROMFH_PAD)
       strnlen(rsb->name, ROMFS_MAXFN) + 1 + ROMFH_PAD)
      & ROMFH_MASK;
 //完成读取非规范文件(不可读取)后的初步“恢复”操作
 brelse(bh);//释放缓冲区,等待该缓冲区解锁,引用计数减1,唤醒等待空闲缓冲区的进程
 //尝试为超级块分配新的目录
 s->s_op = &romfs_ops;//给超级块对象的操作表赋值
 s->s_root = d_alloc_root(iget(s, sz));/

 if (!s->s_root)//找不到根目录,即分配目录项失败
  goto outnobh;//执行outnobh将指针指控,方便下次使用

 
 if (0) {//0,不就是永远不执行这些语句?难道只是为了做操作声明?
out:
  brelse(bh);//释放缓冲区
outnobh:
  s = NULL;//找不到根目录,指针指向随机,此时应将将指针置空
 }

 return s;//返回超级块指针,方便后面的操作
}

相关推荐