当前位置: 首页 > news >正文

Linux基础 -- UBI模块之 leb_read_sanity_check函数说明

它不是给你直接调用的公共 API,而是 UBI 内核层(drivers/mtd/ubi/kapi.c)里供 ubi_leb_read()/ubi_leb_read_sg() 使用的私有参数校验函数,在真正下发读请求前把各种越界与非法场景一网打尽,避免把“坏参数”送进 EBA/IO 路径。


它做什么(作用与位置)

  • 位置drivers/mtd/ubi/kapi.c
  • 被谁调用ubi_leb_read()ubi_leb_read_sg() 在读数据前先调用它做检查;通过后才会走 ubi_eba_read_leb() 把 LEB 映射到 PEB 并执行实际读。

具体检查了什么(核心规则)

leb_read_sanity_check(struct ubi_volume_desc *desc, int lnum, int offset, int len) 主要做这些校验:

  1. 基本越界

    • 卷号、LEB 号、偏移、长度都必须在合法范围内:

      • 0 <= lnum < vol->used_ebs
      • 0 <= offset0 <= len
      • offset + len <= vol->usable_leb_size(单个 LEB 的可读上限)([Android Git Repositories][1])
  2. 静态卷(static volume)额外限制

    • 若是最后一个 LEB,不允许读超过真实有效字节 vol->last_eb_bytes(静态卷最后一个 LEB 可能没写满)。([Android Git Repositories][1])
  3. 更新中断保护

    • 卷带有 更新标记vol->upd_marker,表示上次“更新卷”被中断)时,一律拒绝读,返回 -EBADF。([Android Git Repositories][1])

通过这些检查后,ubi_leb_read() 才会去 ubi_eba_read_leb() 执行真正的读;长度为 0 的读直接返回成功。


与“读数据完整性”的关系

  • 静态卷 CRC 检查ubi_leb_read(desc, lnum, buf, off, len, check)check 参数仅对静态卷生效。若置 1,会把整个 LEB 读出并核对 CRC;这会明显变慢。动态卷忽略该参数。

  • 错误语义

    • -EBADMSG:底层 MTD 报不可校正 ECC,或静态卷的 CRC 不匹配;UBI 还会把静态卷标记为 corrupted 以便上层感知。
    • -EINVAL:各种越界/非法参数(上面 1、2 条)。
    • -EBADF:卷处于“更新中断”状态(upd_marker)。

设计思路(为什么把检查集中在这里)

  • 把 API 契约收紧在 KAPI 层:先拦截所有“坏参数”,再把干净的请求交给 EBA/IO,避免出现锁/并发/映射层里才发现的“迟到错误”。
  • 静态卷与动态卷语义分离:静态卷有“最后一个 LEB 可能不满”和“可选 CRC 校验”的特性,因此在 sanity check / 读路径上都要额外处理。

在实际系统中的作用(与 UBIFS 的关系)

  • UBIFS/其他内核客户端不会直接调用 leb_read_sanity_check,而是调用 ubi_leb_read()ubi_leb_read_sg();一旦传参出界,会被该检查直接打回,不会发起任何闪存访问。随后才进入 ubi_eba_read_leb() 完成 LEB→PEB 映射和读操作。

“正确用法”示意(内核调用方)

你要做的是 打开卷 → 调 ubi_leb_read()leb_read_sanity_check 由 UBI 内部自动执行:

struct ubi_volume_desc *d = ubi_open_volume(ubi_num, vol_id, UBI_READONLY);/* 读 LEB lnum 的一段数据 */
int err = ubi_leb_read(d, lnum, buf, offset, len, /*check=*/0);
if (err == -EINVAL)  /* 参数越界/非法 */...
if (err == -EBADF)   /* 卷处于更新中断(不可访问) */...
if (err == -EBADMSG) /* ECC/CRC 故障 */...

ubi_leb_read_sg() 提供了 scatter-gather 版本,固定也会先做同样的 sanity check。([Android Git Repositories][1])


调试与排障要点

  • 反复 -EINVAL:检查 lnum 是否小于 vol->used_ebsoffset+len 是否穿越 vol->usable_leb_size,以及静态卷最后 LEB 的 last_eb_bytes 限制。
  • -EBADF:卷带有 upd_marker(上次更新被断电中断);需要完成/回滚更新或重建卷。
  • -EBADMSG:底层介质确实有不可校正错误或静态卷 CRC 错;在静态卷场景下 UBI 会将卷标记 corrupted 并打印告警。

小结

leb_read_sanity_check = UBI 内部的“读参数闸门”:统一检查 LEB 边界、偏移/长度、静态卷末块长度 以及 更新中断 状态;只有通过它,ubi_leb_read() 才会继续把请求交给 EBA/IO 层执行。它让 UBI 的读 API 具备可预测的错误语义,也把静态卷与动态卷的特殊性(last_eb_bytes、CRC 检查)收敛在了规范的入口。

http://www.dtcms.com/a/523660.html

相关文章:

  • 深入解析 Transformer 模型:以 ChatGPT 为例从词嵌入到输出预测的大语言模型核心工作机制
  • 破局延时任务(上):为什么选择Spring Boot + DelayQueue来自研分布式延时队列组件?
  • 云手机是一种应用软件吗?
  • 工业无线通信突破!SG-Lora-TCP 模块,7 公里无线替代 TCP 布线
  • 网站建设 服务内容 费用上海有几个区最好
  • 现代前端状态管理深度剖析:从单一数据源到分布式状态
  • UART 串口协议详解与 STM32 实战实现
  • 【CMakeLists.txt】QtSvg 头文件包含配置详解
  • 调用Zlib库接口压缩、解压缩(C++源码)
  • flume的log4j日志无输出排查
  • 一个域名可以做两个网站吗天津人事考试网
  • whisper 模型处理音频办法与启示
  • linux rt任务调度器
  • 金融智能体技术解读:十大应用场景与AI Agent架构设计思路
  • 永磁同步电机(PMSM)在MATLAB中的高级调参策略与实践
  • 李宏毅机器学习笔记31
  • 【timecode】两种不同的时间码格式:“`00:00:00`” 和 “`00:00:00:00`”
  • 个人网站 不用备案深圳建设网站和公众号
  • npm 安装 canvas 报错 node-gyp ERR! 的解决方法(Windows 系统)
  • 编辑器汇总:Neovim、Helix、Vim、LazyVim、Kakoune、nb、Lite XL
  • 如何开发一个自己的包并发布到npm
  • 商城型网站的概念企业信息平台登录
  • Docker MySQL 单主从及分表函数
  • UE5 蓝图-11:本汽车蓝图的事件图表,汽车拆分事件,染色事件(绿蓝黄青)。
  • CDC 实时数据同步与小时级统计方案(Flink 1.13.5 + MySQL 8.0)
  • Redis之String 类型入门与实战,由基础语法快速掌握再到缓存加速/验证码防刷/计数统计场景应用
  • 【Qt | .pro文件】Qt项目文件详解:pro文件与pri文件
  • SpringAI2-Spring AI-聊天模型:ChatClient,流式编程,ChatModel
  • [MySQL] 事务和视图
  • 建设网站的特色wordpress域名网站搬家