ubifs文件系统代码解析
注:源码取的是v5.10.135版本,仅供个人学习使用
在线阅读地址:https://elixir.bootlin.com/linux/v5.10.135/source/fs/ubifs
ubiattach
ubimkvol
mount
ubiattach
作用:将指定的mtd分区关联到ubi上
举例:ubiattach /dev/ubi_ctrl -m 3**
int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num,
int vid_hdr_offset, int max_beb_per1024)
{
struct ubi_device *ubi;
int i, err;
/*
* max_beb_per1024:maximum expected number of bad PEBs per 1024 PEBs
* 翻译过来就是,每1024个PEB中,允许的最大坏块数--块就是PEB,记住这个
* ubiattach 使用-b 参数可以指定max_beb_per1024
* -b, --max-beb-per1024 maximum expected bad block number per 1024 eraseblock.
* The default value is correct for most NAND devices.
* Allowed range is 0-768, 0 means the default kernel value.
* #define MAX_MTD_UBI_BEB_LIMIT 768
* 不用-b指定的预期值,则默认为max_beb_per1024 默认为 MAX_MTD_UBI_BEB_LIMIT
* MAX_MTD_UBI_BEB_LIMIT 由 CONFIG_MTD_UBI_BEB_LIMIT 指定,默认未20
* 参考链接:https://zhuanlan.zhihu.com/p/504692426
*/
if (max_beb_per1024 < 0 || max_beb_per1024 > MAX_MTD_UBI_BEB_LIMIT)
return -EINVAL;
if (!max_beb_per1024)
max_beb_per1024 = CONFIG_MTD_UBI_BEB_LIMIT;
/*
* Check if we already have the same MTD device attached.
*
* Note, this function assumes that UBI devices creations and deletions
* are serialized, so it does not take the &ubi_devices_lock.
*/
/*
* 检查这个MTD设备是否已经被attach过了
* UBI_MAX_DEVICES:UBI设备最大的支持数,32
* ubi_devices[i]:ubi设备的结构体,全局数组,每当有新mtd设备attach的时候,会加入到到全局数组中,i+1
* 遍历一下现有ubi设备中,绑定的mtd信息是否与新attach的mtd相同
* 如果是则说明该mtd已经被attach过了
* struct mtd_info *mtd 结构体中,index 是唯一的
*/
for (i = 0; i < UBI_MAX_DEVICES; i++) {
ubi = ubi_devices[i];
if (ubi && mtd->index == ubi->mtd->index) {
pr_err("ubi: mtd%d is already attached to ubi%d\n",
mtd->index, i);
return -EEXIST;
}
}
/*
* Make sure this MTD device is not emulated on top of an UBI volume
* already. Well, generally this recursion works fine, but there are
* different problems like the UBI module takes a reference to itself
* by attaching (and thus, opening) the emulated MTD device. This
* results in inability to unload the module. And in general it makes
* no sense to attach emulated MTD devices, so we prohibit this.
*/
/*
* 保证MTD设备没有被模拟卷轴,这部分知识不懂,是不是要保证没有被ubimkvol执行过,还是用其他模拟的手段?
* 重点遗留,如遇到其他地方有类似的,后续再补充
*/
if (mtd->type == MTD_UBIVOLUME) {
pr_err("ubi: refuse attaching mtd%d - it is already emulated on top of UBI\n",
mtd->index);
return -EINVAL;
}
/*
* Both UBI and UBIFS have been designed for SLC NAND and NOR flashes.
* MLC NAND is different and needs special care, otherwise UBI or UBIFS
* will die soon and you will lose all your data.
* Relax this rule if the partition we're attaching to operates in SLC
* mode.
*/
/*
* 所有的UBI和UBIFS文件系统 都是用用来设置给SLC NAND(Single-LevelCell,单层单元闪存) 和 NOR flashes
* MLC NAND(Multi-Level Cell,多层单元闪存)比较特殊,需要重点关注,否则很快设备就坏掉了
* 可以网上去搜一下,SLC NAND 和 MLC NAND的区别,重点关注擦除次数
* 转译一下,就是不支持UBIFS不支持 MLC NAND 设备
*/
if (mtd->type == MTD_MLCNANDFLASH &&
!(mtd->flags & MTD_SLC_ON_MLC_EMULATION)) {
pr_err("ubi: refuse attaching mtd%d - MLC NAND is not supported\n",
mtd->index);
return -EINVAL;
}
/*
* ubi_num:第二入参,可以通过ubiattach -d参数指定
* ubiattach 命令参考链接:https://zhuanlan.zhihu.com/p/504692426
* 如果未指定,则自动分配
* 基本步骤为遍历一下,在不超过32个ubi设备数的前提下,找到空位给它
*/
if (ubi_num == UBI_DEV_NUM_AUTO) {
/* Search for an empty slot in the @ubi_devices array */
for (ubi_num = 0; ubi_num < UBI_MAX_DEVICES; ubi_num++)
if (!ubi_devices[ubi_num])
break;
if (ubi_num == UBI_MAX_DEVICES) {
pr_err("ubi: only %d UBI devices may be created\n",
UBI_MAX_DEVICES);
return -ENFILE;
}
} else {
if (ubi_num >= UBI_MAX_DEVICES)
return -EINVAL;
/* Make sure ubi_num is not busy */
if (ubi_devices[ubi_num]) {
pr_err("ubi: ubi%i already exists\n", ubi_num);
return -EEXIST;
}
}
/* 在内核空间,申请一个ubi设备结构体空间,填充数据 */
ubi = kzalloc(sizeof(struct ubi_device), GFP_KERNEL);
if (!ubi)
return -ENOMEM;
device_initialize(&ubi->dev); /* 初始化新建的逻辑设备 */
ubi->dev.release = dev_release; /* 设备的releas