给定如下一定情况:

crash> files
PID: TASK: ffff8817facd2100 CPU: COMMAND: "slabtop"
ROOT: / CWD: /
FD FILE DENTRY INODE TYPE PATH
ffff881810117680 ffff880c115a5cc0 ffff881811fa7a78 CHR /dev/null
ffff880af6bf2200 ffff88180c64e440 ffff88180dc02438 REG /dev/shm/zxdfs/moni_sys.log
ffff88180ef619c0 ffff881811a263c0 ffff880c0eabf118 CHR /dev/console
ffff880c9ddbba80 ffff8818014b1540 ffff88100a8117f8 REG /proc/slabinfo---------------请注意,第二列就是对应的file*,第三列就是dentry,第四列就是对应的inode,用来验证

比如对于fd为3,如何快速获取对应的file* 信息?虽然这个命令输出的时候,第二列就是对应的file*,第三列就是dentry,第四列就是对应的inode,但是今天我们通过代码找到的file*是否正确。

对于fd来说,一般会根据 fget_light-->fcheck_files来获取file*,(注意,这里无关fget 还是 fget_light,因为最终都是调用fcheck_files)

结构就是当前进程task中的:

struct files_struct *files = current->files;
然后根据这个files_struct成员,找到fdt指针:
static inline struct file * fcheck_files(struct files_struct *files, unsigned int fd)
{
struct file * file = NULL;
struct fdtable *fdt = files_fdtable(files); if (fd < fdt->max_fds)
file = rcu_dereference(fdt->fd[fd]);
return file;
}

fdt中的fd数组中,就是按照fd下标存放的file*指针,如下:

crash> task
PID: TASK: ffff8817facd2100 CPU: COMMAND: "slabtop" crash> struct task_struct.files ffff8817facd2100
files = 0xffff88130c8bec00
crash> struct fdtable.fd 0xffff88126d2f4900
fd = 0xffff880c976ad000 crash> rd 0xffff880c976ad000
ffff880c976ad000: ffff881810117680 ffff880af6bf2200 .v......."......
ffff880c976ad010: ffff88180ef619c0 ffff880c9ddbba80 ................

所以对于fd为3来说,取到的file*指针就是ffff880c9ddbba80   ,(这个指针也和我们files命令打印的一致)我们来验证一下这个file*指针:

crash> struct file.f_path.dentry ffff880c9ddbba80
f_path.dentry = 0xffff8818014b1540
crash> struct dentry.d_iname 0xffff8818014b1540
d_iname = "slabinfo\000_offset\000ndler.py\000m\000\000\000\000"

d_iname就是对应的文件路径最后一段文件名,说明我们取的file*指针是对了,有了file* 指针,我们就可以将对应的vfs的其他结构全部串起来。

不过需要注意的是,操作这个fdt的时候,需要关注rcu锁,具体可以查看files.txt里面的说明,获取到的file*指针,如果

if (atomic_long_inc_not_zero(&file->f_count))
*fput_needed = 1;

这个满足的话,是需要put的,否则file*指针不能用。也就是说,当file->f_count为0时,是不直接增加计数的,这个和pagecache中的lockless用法一样。

取到的file指针,用rcu保证有效性,然后这个get之后,用file->f_count来保证计数的有效性。

其实,crash中的files命令,除了能快速查看到对应的file*,dentry,inode等,带参数的files 命令还有更多的输出:

crash> files -d ffff8818014b1540
DENTRY INODE SUPERBLK TYPE PATH
ffff8818014b1540 ffff88100a8117f8 ffff880c1188cc00 REG /.root_tmpfs/proc/slabinfo

具体可以hlep files 来验证。

linux 2.6.32文件系统 fd与file*之间的关系的更多相关文章

  1. linux 2.6.32文件系统的dentry父子关系

    我们知道,linux文件系统,inode和dentry是有对应关系的,dentry是文件名或者目录的一个管理结构,2.6内核中: struct dentry { atomic_t d_count; u ...

  2. linux 2.6.32文件系统的inode

    接上文: crash> struct -xo dentry.d_inode ffff8818118002c0 struct dentry { [ffff8818118002d0] struct ...

  3. js中的blob,图片base64URL,file之间的关系

    js的base64编码和解码 英文是这样的:// atob() 将base64解码 // btoa() 将字符串转码为base64 var str = 'javascript'; window.bto ...

  4. Linux 虚拟文件系统四大对象:超级块、inode、dentry、file之间关系

    更多嵌入式原创文章,请关注公众号:一口Linux 一:文件系统 1. 什么是文件系统? 操作系统中负责管理和存储文件信息的软件机构称为文件管理系统,简称文件系统. 通常文件系统是用于存储和组织文件的一 ...

  5. 【转】linux IO子系统和文件系统读写流程

    原文地址:linux IO子系统和文件系统读写流程 我们含有分析的,是基于2.6.32及其后的内核. 我们在linux上总是要保存数据,数据要么保存在文件系统里(如ext3),要么就保存在裸设备里.我 ...

  6. 深入理解linux系统下proc文件系统内容

    深入理解linux系统下proc文件系统内容 内容摘要:Linux系统上的/proc目录是一种文件系统,即proc文件系统. Linux系统上的/proc目录是一种文件系统,即proc文件系统.与其它 ...

  7. 详解Linux磁盘管理与文件系统

    磁盘基础 硬盘结构 物理结构 盘片:硬盘有多个盘片,每盘片 2 面. 磁头:每面一个磁头. 数据结构 扇区:磁盘上的每个磁道被等分为若干个弧段,这些弧段便是硬盘的扇区. 硬盘的第一个扇区,叫做引导扇区 ...

  8. 9.1 Linux存储结构和文件系统

    1. 存储结构 Linux系统中的一切文件都是从"根"目录(/)开始的,并按照文件系统层次标准(FHS)采用倒树状结构来存放文件,以及定义了常见目录的用途. 目录名称 应放置文件的 ...

  9. Linux中文件描述符fd和文件指针flip的理解

    转自:http://www.cnblogs.com/Jezze/archive/2011/12/23/2299861.html 简单归纳:fd只是一个整数,在open时产生.起到一个索引的作用,进程通 ...

随机推荐

  1. 获取地图文档(*.mxd)中比例尺问题

    地图比例尺的概念是建立在有投影坐标系的空间参考前提下,将地图缩放到一定大小的比例值. 在多数情况下,我们都是将一个地图文档(*.mxd)加载到地图控件中(AxMapControl)显示出来,照此去获取 ...

  2. [深度分析] Python Web 开发框架 Bottle

    [深度分析] Python Web 开发框架 Bottle(这个真的他妈的经典!!!) 作者:lhf2009913 Bottle 是一个非常精致的WSGI框架,它提供了 Python Web开发中需要 ...

  3. javascript-回归原生基础

    //添加事件监听兼容函数 function addHandler(target, eventType, handler){ if(target.addEventListener){//主流浏览器 ad ...

  4. scala语法在spark withScope上的应用

    withSpout在spark中是用来做DAG可视化的,它在代码里的用法如下(以map为例,spark 2.0.0版本) def map[U: ClassTag](f: T => U): RDD ...

  5. C#窗体嵌入SetParent的用法

    模块化的开发,将模块合并到一起的时候,遇到了Mdi不能添加到其它窗口下的问题. 分两种情况: 将mdi窗口A设成普通窗口B的子控件,需要将A的TopLevel设置成false,但是Mdi窗口的TopL ...

  6. Hadoop Api 基本操作

     hadoop环境配置好后,直接可以在window上进行调试.话不多说,直接上源码. package cn.terry; import java.io.FileInputStream; import ...

  7. Linux下Mysql自启动

    如果你都是按照默认配置安装的那么只要按照如下步骤就可以了 1.cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysql   将服 ...

  8. 「2017 山东一轮集训 Day4」棋盘(费用流)

    棋盘模型 + 动态加边 #include<cstdio> #include<algorithm> #include<iostream> #include<cs ...

  9. RocketMQ源码分析:(一)安装与案例演示

    环境: Windows 暂时理解的功能图,不定时改动: 1. 克隆rocketmq代码 git clone git@github.com:apache/rocketmq.git 2. 进入rocket ...

  10. python学习之----lxml库和HTML parser

    lxml 这个库(http://lxml.de/)可以用来解析HTML 和XML 文档,以非常底层的实现而闻名 于世,大部分源代码是用C 语言写的.虽然学习它需要花一些时间(其实学习曲线越 陡峭,表明 ...