Linux-overlay启动挂载代码分析
背景
Linux-4.1内核使用overlay挂载文件系统后,在写文件遇突然掉电后重启出现修改文件报错问题;问题原因是写文件过程种会在wrok目录下创建Whiteout文件,文件写成功后会删除Whiteout文件,但在异常掉电时Whiteout文件没有被删除,导致系统重启overlay挂载检查work不为空出现异常;下面来分析overlay启动挂载代码流程。
代码位置
fs/overlayfs/
├── copy_up.c
├── dir.c
├── inode.c
├── Kconfig
├── Makefile
├── overlayfs.h
├── readdir.c
└── super.c
super.c
ovl_init 初始化函数
register_filesystem(&ovl_fs_type); 注册文件系统到系统static struct file_system_type ovl_fs_type = {.owner = THIS_MODULE,.name = "overlay",.mount = ovl_mount,.kill_sb = kill_anon_super,
};
MODULE_ALIAS_FS("overlay");
ovl_mount 挂载函数
mount_nodev(fs_type, flags, raw_data, ovl_fill_super); 文件系统挂载类型回调函数ovl_fill_super
ovl_fill_super 回调函数
解析挂载参数
ovl_parse_opt((char *) data, &ufs->config);static const match_table_t ovl_tokens = {{OPT_LOWERDIR, "lowerdir=%s"},{OPT_UPPERDIR, "upperdir=%s"},{OPT_WORKDIR, "workdir=%s"},{OPT_ERR, NULL}};ovl_mount_dir(ufs->config.upperdir, &upperpath); 挂载upper
ovl_mount_dir(ufs->config.workdir, &workpath); 挂载workerkstrdup(ufs->config.lowerdir, GFP_KERNEL); 分配内存
ovl_split_lowerdirs(lowertmp); 判断lower层级不大于500
ovl_lower_dir(lower, &stack[numlower], &ufs->lower_namelen, &sb->s_stack_depth); 挂载各lower层级clone_private_mount(&upperpath);
ovl_workdir_create(ufs->upper_mnt, workpath.dentry); 创建work目录
if (IS_ERR(ufs->workdir)) {创建失败本该挂载为只读文件系统并打印提示,这里被注释了//pr_warn("overlayfs: failed to create directory %s/%s (errno: %i); mounting read-only\n", // ufs->config.workdir, OVL_WORKDIR_NAME, -err);//sb->s_flags |= MS_RDONLY;ufs->workdir = NULL; 这里为NULL会导致后面copy-up报空指针错误clone_private_mount(&stack[i]); 克隆lower私有挂载路径,并设置挂载属性为只读
mnt->mnt_flags |= MNT_READONLY; d_make_root(ovl_new_inode(sb, S_IFDIR, oe)); 判断是否是根目录挂载
ovl_workdir_create 创建work目录函数
检查work目录是否存在
#define OVL_WORKDIR_NAME "work"
lookup_one_len(OVL_WORKDIR_NAME, dentry, strlen(OVL_WORKDIR_NAME)); 目录存在就去清除
ovl_cleanup(dir, work); ovl_do_rmdir vfs_rmdirerror = dir->i_op->rmdir(dir, dentry);fs/ubifs/dir.c +1174const struct inode_operations ubifs_dir_inode_operations = {.rmdir = ubifs_rmdir, err = check_dir_empty(c, d_inode(dentry)); 目录不为空会返回-39,删除失败walk directory or extended attribute entries. 遍历目录或扩展属性条目。ubifs_tnc_next_ent(c, &key, &nm); err = -ENOTEMPTY;#define ENOTEMPTY 39 /* Directory not empty */
readdir.c
ovl_workdir_cleanup 补丁文件函数:递归清除文件目录
if (!d_is_dir(dentry) || level > 1) {ovl_cleanup(dir, dentry); 删除文件return;
}err = ovl_do_rmdir(dir, dentry); 删除不为空目录失败就删除目录里面的文件
if (err) {ovl_workdir_cleanup_recurse(&path, level + 1);ovl_dir_read(path, &rdd); 读出目录信息list_for_each_entry(p, &list, l_node) {lookup_one_len(p->name, path->dentry, p->len); ovl_workdir_cleanup(dir, path->mnt, dentry, level); 目录存在就递归删除}
}
递归删除work目录下的文件,目录删空后就能删除目录了
扩展
workdir目录下work下创建文件代码:
snprintf(name, sizeof(name), "#%lx", (unsigned long) dentry);
~ # ls /ubifs/work/work/ -l
c--------- 1 root root 0, 0 Mar 7 15:31 #ffffffc03e44b9d8
Linux-overlay启动挂载代码分析相关推荐
- 【鸿蒙OS开发入门】06 - 启动流程代码分析之KernelOS:之启动Linux-4.19 Kernel内核 启动init进程
[鸿蒙OS开发入门]06 - 启动流程代码分析之KernelOS:之启动Linux-4.19 Kernel内核 一.head.S 启动start_kernel() 1.1 start_kernel() ...
- 【鸿蒙OS开发入门】13 - 启动流程代码分析之第一个用户态进程:init 进程 之 init 任务详解
[鸿蒙OS开发入门]13 - 启动流程代码分析之第一个用户态进程:init 进程 之 init 任务详解 一. /etc/init.cfg 系统默认cfg:启动lo回环网卡 1.1 init.Hi35 ...
- linux内核中链表代码分析---list.h头文件分析(二)【转】
转自:http://blog.chinaunix.net/uid-30254565-id-5637598.html linux内核中链表代码分析---list.h头文件分析(二) 16年2月28日16 ...
- Linux配置启动挂载:fstab文件详解
Linux配置启动挂载:fstab文件详解 [日期:2014-12-23] 来源:Linux社区 作者:aceking10 [字体:大 中 小] fstab文件介绍 fstab文件包含了你的电脑上的存 ...
- linux内核中链表代码分析---list.h头文件分析(一)
linux内核中链表代码分析---list.h头文件分析(一) 16年2月27日17:13:14 在学习数据结构时,有一个重要的知识点就是链表.对于链表的一些基本操作,它的最好学习资料就是内核中的li ...
- 【内核】linux内核启动流程详细分析【转】
转自:http://www.cnblogs.com/lcw/p/3337937.html Linux内核启动流程 arch/arm/kernel/head-armv.S 该文件是内核最先执行的一个文件 ...
- 【内核】linux内核启动流程详细分析
Linux内核启动流程 arch/arm/kernel/head-armv.S 该文件是内核最先执行的一个文件,包括内核入口ENTRY(stext)到start_kernel间的初始化代码, 主要作用 ...
- Linux开机启动过程详细分析
from: http://www.linuxidc.com/Linux/2007-11/8701.htm 由于操作系统正在变得越来越复杂,所以开机引导和关机下电的过程也越来越智能化.从简单的DOS系统 ...
- Linux SCSI设备容量打印代码分析
探寻SCSI设备容量如何获取代码. 分析 8G USB转SD卡启动打印信息: sd 3:0:0:0: [sdb] 15523840 512-byte logical blocks: (7.94 GB/ ...
最新文章
- 新建一个spyder窗口
- WPS for MacOS如何设置自动拼写检查
- 【HDU - 5649】DZY Loves Sorting(线段树,区间更新区间查询,思维,01缩数变换,线段树分割)
- 【每日算法Day 84】面试必考题:Trie(字典树/前缀树)的实现
- 十大常用算法之马踏棋盘算法
- abb机器人伺服电机报闸是什么_什么是抱闸电机
- 基于cat12和SPM12进行大脑VBM数据分析笔记2——统计分析
- 实验二线性表的链式存储结构
- Typora安装教程
- JS设置浏览器缩放比例
- 亮度键消失、亮度键失灵且电脑亮度为最大 | 小米 | win11 | 解决办法最最最全合集
- 什么是甘特图?怎么做甘特图?
- 目标检测网络---评价指标
- git revert 之后 找回原来的代码
- 视频监控开发(1)——萤石云硬盘录像机SDK使用
- C语言的for循环转verilog,Verilog for 循环语句
- 我只是在猜想 	——站在云端看操作系统以及计算机的未来
- neo4j图数据库入门
- JavaWeb项目 学生后台管理系统 有源码!!(基于MVC设计模式)
- 如何建立有效的绩效管理体系?
热门文章
- Macbook Air如何将m4a格式转化为mp3格式?
- 世界上第一代电子计算机取名为,计算机应用基础知识计算机应用基础试题及答案...
- Niagara_Advanced内容示例 1.3 Communicate with External Render Targets
- ESP8266+Blinker+小爱同学舵机控制开关
- 解决在高分辨率下运行Photoshop CS6,程序界面字体过小的问题
- ubuntu下使用github安装R Packages[已解决]
- 霍华德:二呆青年勤修苦练终成一代大侠记
- EXCEL清除全表格式
- NDK学习笔记:JNI调用Java层方法创建Native的AudioTrack播放PCM(方法签名,CallXXXMethod)
- 手机里的照片导入计算机的方法,如何把iphone照片导入电脑 四种方法分享【图文】...