问题背景

一个内核模块中,需要通过d_path接口获取文件的路径,然后与目标文件白名单做匹配。

在生产环境中,获取的文件是存在的,但是与文件白名单中的文件总是匹配失败。

问题定位:

通过打印d_path返回的字符串,发现获得的路径后面多了一个" (deleted)"字符串,在做完全匹配时不通过。

看了d_path函数说明:如果entry被删除了,会添加" (deleted)"字符串。

* Convert a dentry into an ASCII path name. If the entry has been deleted
 * the string " (deleted)" is appended. Note that this is ambiguous.

为什么会这样,还要从Linux文件系统的dcache、inode和dentry说起。

 linux文件系统

Linux能够成功的其中一个关键是它能够很好地与其他系统共存。你可以透明地挂载由Windows或其他Unix系统格式化

的磁盘或者分区。Linux与其他Unix系统一样,可以通过虚拟文件系统管理支持多种文件系统类型(Virtual Filesystem)。

内核中虚拟文件系提供了能够表示许多不同类型文件系统的广泛信息;Linux有字段或者函数能够支持所有真实文件系统

的每一个操作。对于每个read、write或其他调用的函数,内核替代真正的函数来支持本地Linux文件系统,NTFS文件系统,

或者其他任何的文件系统。

有一张图,可以表示进程与VFS各种对象之间的关系,来源于《深入理解Linux内核》,如下所示:

superblock对象:

  存储被挂载的文件系统的相关信息。对于磁盘文件系统,它就是文件系统控制块(filesystem control block)。

inode对象

  存储某一特定文件的一般信息。对于磁盘文件系统,它就是文件控制块(file control block)。每个inode对象

都有一个inode数字,它唯一确定了文件系统内的文件。

file对象

  存储进程与其打开的文件之间的互操作信息。这些信息仅存在于内核内存中,在进程打开文件期间有效。

dentry对象

  存储相关文件的目录条目(directory entry,也就是特殊的文件)的链接信息。每个磁盘文件系统都有自己的

特别方式存储这些信息。

  

  从上图可以看到,在文件对象和dentry对象之间,还有一个dentry cache(简称dcache),它是文件系统性能

的一个关键角色。所有最近使用的dentry对象都包含在磁盘cache中,它叫做dentry cache。它能加快从文件路径到

最后一个路径组件的转换。

  通常来说,磁盘cache是软件机制,它允许内核在RAM中保存一些存储在磁盘上的信息。因此,它可以很好地

满足对这些数据的进一步快速访问,而不需要通过磁盘本身做慢速访问。

Page Frame回收机制

  上面也提到,dentry cache是软件机制,保存最近访问文件的dentry对象,那它就不会是无限扩大,系统总是会

根据实际情况做dentry的回收和老化。

  在Linux系统中,由PFRA(Page Frame Reclaiming Algorithm)决定dentry cache回收。当它尝试重新申请Page

Frame,它也要检查dentry cache是否需要收缩。

  Linux系统PFRA从disk cache回收page的注册函数是shrink_slab,由try_to_free_pages-->shrink_slab调用。

总结:

  由上面可以得出,当系统通过PFRA释放了dentry条目,就会把dentry从disk cache链表中删除,但是其值还在,

所以在d_path中,会得到带" (deleted)"的字符串。

教训&经验
内核代码接口很强大,学艺不精,导致问题
使用内核接口之前,要仔细研读函数说明,了解细节和应用场景
参考自己的应该场景,做适当的处理。

参考资料:

1.《深入理解Linux内核》(第三版)

Linux内核d_path函数应用的经验总结的更多相关文章

  1. linux内核常用函数或宏

    1. simple_strtoul 用于将字符串转换为无符号长整数,第3个参数10意味着转换方式是10进制. ival = simple_strtoul(buffer, NULL, 10); 2. 大 ...

  2. linux内核--wait_event_interruptible_timeout()函数分析(转)

    原文:https://blog.csdn.net/wuyongpeng0912/article/details/45723657 网上有关于此函数的分析,但大都是同一篇文章转载来转载去,没有进一步的分 ...

  3. Linux 内核释放函数和 kobject 类型

    讨论中仍然缺失的一个重要事情是当一个 kobject 的引用计数到 0 时会发生什么. 创建 kobject 的代码通常不知道什么时候要发生这个情况; 如果它知道, 在第一位使用一个引 用计数就没有意 ...

  4. Linux内核调试方法总结

    Linux内核调试方法总结 一  调试前的准备 二  内核中的bug 三  内核调试配置选项 1  内核配置 2  调试原子操作 四  引发bug并打印信息 1  BUG()和BUG_ON() 2   ...

  5. 基于tiny4412的Linux内核移植 -- 设备树的展开

    作者信息 作者: 彭东林 邮箱:pengdonglin137@163.com QQ:405728433 平台简介 开发板:tiny4412ADK + S700 + 4GB Flash 要移植的内核版本 ...

  6. 基于tiny4412的Linux内核移植 -- 设备树的展开【转】

    转自:https://www.cnblogs.com/pengdonglin137/p/5248114.html#_lab2_3_1 阅读目录(Content) 作者信息 平台简介 摘要 正文 一.根 ...

  7. Linux内核调试方法【转】

    转自:http://www.cnblogs.com/shineshqw/articles/2359114.html kdb:只能在汇编代码级进行调试: 优点是不需要两台机器进行调试. gdb:在调试模 ...

  8. Linux内核分析——构造一个简单的Linux系统MenuOS

    马悦+原创作品转载请注明出处+<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.Linux内核源代码简 ...

  9. Linux 内核学习经验总结

    Linux 内核学习经验总结 学习内核,每个人都有自己的学习方法,仁者见仁智者见智.以下是我在学习过程中总结出来的东西,对自身来说,我认为比较有效率,拿出来跟大家交流一下. 内核学习,一偏之见:疏漏难 ...

随机推荐

  1. pandas第一课

    pandas第一课 首先是数据的准备 movies.dat user.dat ratings.dat 注意,这些数据都是通过::来隔开每一列的,每一列有各自的含义 现在通过pandas来读入数据 首先 ...

  2. Django的安装和启动以及第一个工程的建立

    ---恢复内容开始--- 前提:已经安装了python和Anaconda (windows系统) 在Anaconda安装好之后,其文件夹下有一个叫做Anaconda Prompt的工具,类似windo ...

  3. v4l2框架分析

    参考:https://www.cnblogs.com/fengong/p/4424823.html    http://www.cnblogs.com/fengong/p/4424895.html 一 ...

  4. Linux下MySQL编码的修改

    默认登录mysql之后可以通过SHOW VARIABLES语句查看系统变量及其值. mysql> show variables like '%character%';   说明:以下是在Cent ...

  5. Stripes视图框架与Struts2之间的比较

    https://blog.csdn.net/boonya/article/details/14227149 Stripes视图框架与Struts2的行为很相似,所以在这里做一个简要的对比,发现它们的优 ...

  6. 基于Servlet的Echarts例子(2018-12-26更新)

    引子 ECharts是百度出品的,一个使用 JavaScript 实现的开源可视化库.程序员在Web页面上引入并稍作配置就能做出漂亮的数据图表. 本篇文章简单介绍一下如何在JSP中使用Echarts, ...

  7. 工控随笔_21_西门子_WinCC的VBS脚本_10_对象_01

    最近有点小忙,各种事情,心情也不是很好,烦心事特别多,因此最近更新的比较慢. 不敢再松懈了,今天正好有点时间,就继续看了一下VBScript中关于对象的一些内容. 一.对象 OOP是编程规模发展到一定 ...

  8. CentOS下puppet安装

    简介 Puppet是开源的基于Ruby的系统配置管理工具,puppet是一个C/S结构, 当然,这里的C可以有很多,因此,也可以说是一个星型结构. 所有的puppet客户端同一个服务器端的puppet ...

  9. @RequestParam、@ReqeustBody、@ReponseBody认识

    简介: @RequestParam和@RequestBody均是处理request body部分的注解,都用于获取请求部分的参数. @ResponseBody是用于响应部分的注解 1. @Reques ...

  10. 【docker】服务随容器启动而自启动

    场景: 有一个docker, 在该docker中有服务A,希望每次启动容器时服务A都随着容器启动.这样就不用每次都进入容器手动启动服务了. 方法: 1.需要在docker中添加一个启动服务脚本auto ...