找回密码
 立即注册
Qt开源社区 门户 查看内容

一次向linux开源社区提交补丁的经历

2019-6-27 17:49| 发布者: admin| 查看: 464| 评论: 0

摘要: 在开发过程中,偶然发现了spinand驱动的一个bug,满怀欣喜地往社区提补丁。这是怎么样的一个bug呢?Copystaticintspinand_mtd_read(struct mtd_info *mtd, loff_t from,struct mtd_oob_ops *ops){ ...... ...


在开发过程中,偶然发现了spinand驱动的一个bug,满怀欣喜地往社区提补丁。这是怎么样的一个bug呢?

Copy
staticintspinand_mtd_read(struct mtd_info *mtd, loff_t from,
struct mtd_oob_ops *ops)
{
......
nanddev_io_for_each_page(nand, from, ops, &iter) {
......
ret = spinand_read_page(spinand, &iter.req, enable_ecc);
if (ret < 0 && ret != -EBADMSG) /* 读取数据出错 */
break;

if (ret == -EBADMSG) {
/* -EBADMSG 返回表示坏块 */
ecc_failed = true;
mtd->ecc_stats.failed++;
ret = 0;
} else {
/* 出现位翻转或者读取正常,则记录历史位翻转最大值 */
mtd->ecc_stats.corrected += ret;
max_bitflips = max_t(unsigned int, max_bitflips, ret);
}

ops->retlen += iter.req.datalen;
ops->oobretlen += iter.req.ooblen;
}

if (ecc_failed && !ret)
ret = -EBADMSG;

return ret ? ret : max_bitflips;
}





代码逻辑如下:

  1. 遍历读取每一个page

  2. 如果读出错则直接返回

  3. 如果出现坏块,则置位ecc_failed,在函数最后会检查此标志

  4. 如果出现位翻转,则暂存最大位翻转的bit位数量

  5. 全部读取完后,如果有置位ecc_failed,则返回坏块错误码;如果出现位翻转,则返回最大位翻转;否则返回0,表示正常



问题出在于,如果刚好最后一次读取出现位翻转,此时ret != 0就直接退出循环,此时会导致坏块标识无效,且返回最后的位翻转量而非历史位翻转最大值。这是代码不严谨的地方。

第一次提交#



修改补丁如下,补丁逻辑不再解释。

Copy
----------------------------------------------------------------------------------------------------------------------
我们尊重原创,也注重分享,文章来源于微信公众号:中圣智彩HR,建议关注公众号查看原文。如若侵权请联系qter@qter.org。
----------------------------------------------------------------------------------------------------------------------

鲜花

握手

雷人

路过

鸡蛋

公告
可以关注我们的微信公众号yafeilinux_friends获取最新动态,或者加入QQ会员群进行交流:190741849、186601429(已满) 我知道了