修改sbull的一点体会

今天在修改sbull的 open函数时出现了一些问题,本来的想法是拿到设备文件系统的 inode 结点后,把其中的 i_data 中的 a_ops 里的prepare_write 替换成我们自己的。就是三两句代码的事,可是调了一个下午才通过了。开始是编译不过去,好不容易编译过了,insmod 和 mkfs 时都没有问题,最后在mount 时发生了几次 kernel panic. 下面把发生的原因和体会说一下:

涉及到的代码就一句:

sbull_aops.prepare_write = my_prepare_write;

 

最开始时编译不过去理由很简单:我定义的函数参数类型不对,要求的类型是 unsigned , 我写的是 unsigned long, 开始查了半天没查到什么原因,最后一点一点地看,终于发现了。改过这个之后,编译通过。

编译虽然通过了,却有一个警告:在不兼容的类型之间转换,还是出在这一句上。开始没有理他,继续载入模块,创建设备,格式化设备都没有问题,但是在 mount 时却出了 kernel panic.  很是搞不懂什么原因,根据 printk 打印的信息,这个函数的替换已经成功了,可是为什么在看似无关的 mount 时出了问题呢?

反复看代码,发现自己定义函数的返回值类型也不正确,改过之后虽然没有警告信息了,可是这次在创建文件系统时就出现了 kernel panic.

这时候意识到是不是先前因为那个警告,替换根本就没有成功,虽然打印了信息,可是并没有检验替换那一句的返回值,因此到 mkfs 时调用的还是默认的 prepare_write 方法,所以成功了,最后在 mount 阶段出了问题。 现在替换成功了,所以一到 mkfs, 就是调用到 prepare_write 方法时,问题就出现了。

再次修改代码,保存了原来的函数地址,实现在新的函数中调用原来的函数。这次又失败了,但是不是 panic, 而是死循环。仔细一看,是递归调用了同一个 prepare_write 方法,这个错误很低级。改正之后,运行成功了。一直到往里面拷贝文件都没有问题了。

 

这个过程总结的教训:

  • 一定要认真,每一个函数的名字,参数类型,返回值类型必须高度注意,而且 unsigned long 和 unsigned 不是一回事。
  • 在编译过程中,警告并不意味着“勉强执行”了,有时也有可能“没有执行”。因此对于警告,也应该敏感。毕竟内核不是一般的程序。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值