i_rdev i_bdev i_mapping 关系

本文深入探讨Linux中块设备和文件系统的关系,包括i_bdev和i_rdev的作用,mknod创建inode的过程,以及blkdev_open和blkdev_get_block函数的工作原理。同时,分析了不同文件系统如ext2和nfs在处理块设备上的差异,以及mount过程中的设备关联。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

i_bdev只有块设备文件系统的inode会设置该属性,对应的是块设备的数据结构

i_rdev 通过mknod创建的inode都会指定设备号

一个块设备可以通过mknod创建多个具有相同i_rdev的inode,那么在访问这些inode的时候,具体对应的块设备是i_bdev指定的,这和普通的文件系统是不一样的,普通文件系统只使用sb中记录的s_bdev。所有使用相同设备号创建的inode的i_mapping属性都是相同的,他们等于inode->i_mapping = bdev->bd_inode->i_mapping。inode的i_bdev开始可能是空的,在blkdev_open函数中会调用bd_acquire函数,这里面会根据i_rdev值调用bdget函数,该函数会调用iget5_locked在块文件系统的超级块blockdev_superblock中查找对应的inode,获取bdev_inode的bdev属性,并设置inode的bdev

blkdev_get_block 和普通文件系统,例如ext2_get_block

blkdev_get_block 把bh->b_bdev 设置为inode对应的i_bdev, 而其他文件系统则使用map_bh, 把bh的b_bdev设置为sb的s_bdev,在最后调用submit_bid的时候会根据b_bdev获取设备的request_queue

在执行echo u > /proc/sysrq-trigger时执行remount_ro将系统中已经挂载的文件系统设置为只读,但在选取要设置的文件系统时有一个判断条件s_bdev是否为空,如果为空那么不设置该文件系统为只读,而网路文件系统nfs的s_bdev是为NULL的,所以这个操作对它们是无效的。

super_block的s_bdev是在mount时指定的,mount会分为两个分支mount_noblk和mount_blk,mount_noblk每次都指定的dev指针为空,所以每次都是创建新的super_block对象,而mount_blk会根据指定的dev,这个dev也是根据path查找的,查找的过程中会根据holder属性判断,是否有其他文件系统类型已经占用该dev了,这个是在全局链表上进行的,先进行查找看是否已经创建了和该dev关联的super_block对象,如果还没有则创建super_block对象,并把它加入到file_system_type对象的成员链表中,如果查找和该dev关联的super_block对象,则引用加一,并使用该super_block对象,因此同一个设备多次mount使用的是同一个super_block

如何分配唯一的ID,并且可以服用,可以参看idr和ida模块

fuse有两种类型的文件系统fuseblk和fuse,fuseblk文件系统需要指定device,而fuse类型不需要,但是使用fuse类型时bmap接口应该是不能使用的。

块文件系统和普通文件系统共用块缓存,buffer_head, buffer_head都有指针只想pagecache中的page

声明:转载本博文章须在文章明显处注明作者及附上原文链接,便于读者找到原文的更新版。
--------------------- 
作者:oscube 
来源:优快云 
原文:https://blog.youkuaiyun.com/oscube/article/details/80567096 
版权声明:本文为博主原创文章,转载请附上博文链接!

[debug_ramdisk] c_ino = 300000 c_uid = 0 c_gid = 0 c_nlink = 1 c_mtime = 0 c_dev_maj = 0 c_dev_min = 0 c_rdev_maj = 0 c_rdev_min = 0 file_type = 16384 file_mode = "0o755" [dev] c_ino = 300001 c_uid = 0 c_gid = 0 c_nlink = 1 c_mtime = 0 c_dev_maj = 0 c_dev_min = 0 c_rdev_maj = 0 c_rdev_min = 0 file_type = 16384 file_mode = "0o755" [init] c_ino = 300002 c_uid = 0 c_gid = 0 c_nlink = 1 c_mtime = 0 c_dev_maj = 0 c_dev_min = 0 c_rdev_maj = 0 c_rdev_min = 0 file_type = 32768 file_mode = "0o750" [metadata] c_ino = 300003 c_uid = 0 c_gid = 0 c_nlink = 1 c_mtime = 0 c_dev_maj = 0 c_dev_min = 0 c_rdev_maj = 0 c_rdev_min = 0 file_type = 16384 file_mode = "0o755" [mnt] c_ino = 300004 c_uid = 0 c_gid = 0 c_nlink = 1 c_mtime = 0 c_dev_maj = 0 c_dev_min = 0 c_rdev_maj = 0 c_rdev_min = 0 file_type = 16384 file_mode = "0o755" [proc] c_ino = 300005 c_uid = 0 c_gid = 0 c_nlink = 1 c_mtime = 0 c_dev_maj = 0 c_dev_min = 0 c_rdev_maj = 0 c_rdev_min = 0 file_type = 16384 file_mode = "0o755" [second_stage_resources] c_ino = 300006 c_uid = 0 c_gid = 0 c_nlink = 1 c_mtime = 0 c_dev_maj = 0 c_dev_min = 0 c_rdev_maj = 0 c_rdev_min = 0 file_type = 16384 file_mode = "0o755" [sys] c_ino = 300007 c_uid = 0 c_gid = 0 c_nlink = 1 c_mtime = 0 c_dev_maj = 0 c_dev_min = 0 c_rdev_maj = 0 c_rdev_min = 0 file_type = 16384 file_mode = "0o755" [system] c_ino = 300008 c_uid = 0 c_gid = 0 c_nlink = 1 c_mtime = 0 c_dev_maj = 0 c_dev_min = 0 c_rdev_maj = 0 c_rdev_min = 0 file_type = 16384 file_mode = "0o755" ["system/bin"] c_ino = 300009 c_uid = 0 c_gid = 0 c_nlink = 1 c_mtime = 0 c_dev_maj = 0 c_dev_min = 0 c_rdev_maj = 0 c_rdev_min = 0 file_type = 16384 file_mode = "0o751" ["system/bin/e2fsck"] c_ino = 300010 c_uid = 0 c_gid = 0 c_nlink = 1 c_mtime = 0 c_dev_maj = 0 c_dev_min = 0 c_rdev_maj = 0 c_rdev_min = 0 file_type = 32768 file_mode = "0o755" ["system/etc"] c_ino = 300011 c_uid = 0 c_gid = 0 c_nlink = 1 c_mtime = 0 c_dev_maj = 0 c_dev_min = 0 c_rdev_maj = 0 c_rdev_min = 0 file_type = 16384 file_mode = "0o755" ["system/etc/ramdisk"] c_ino = 300012 c_uid = 0 c_gid = 0 c_nlink = 1 c_mtime = 0 c_dev_maj = 0 c_dev_min = 0 c_rdev_maj = 0 c_rdev_min = 0 file_type = 16384 file_mode = "0o755" ["system/etc/ramdisk/build.prop"] c_ino = 300013 c_uid = 0 c_gid = 0 c_nlink = 1 c_mtime = 0 c_dev_maj = 0 c_dev_min = 0 c_rdev_maj = 0 c_rdev_min = 0 file_type = 32768 file_mode = "0o644" ["TRAILER!!!"] c_ino = 300014 c_uid = 0 c_gid = 0 c_nlink = 1 c_mtime = 0 c_dev_maj = 0 c_dev_min = 0 c_rdev_maj = 0 c_rdev_min = 0 c_mode = 493 这些表是用来做什么的
最新发布
07-26
<think>我们正在分析一个RAM磁盘镜像的配置表(如用户提供的文本块)。该配置表描述了RAM磁盘中各个文件或目录的元数据属性。每个条目代表一个文件或目录,并包含一组以"c_"为前缀的字段和其他字段(如file_type和file_mode)。以下是对各字段的详细解释: 1. **c_ino**:inode编号,是文件系统中每个文件的唯一标识符。例如,`c_ino = 300000`表示该文件或目录的inode编号为300000。 2. **c_uid**:文件所有者的用户ID(User ID)。0通常表示root用户。例如,`c_uid = 0`表示该文件的所有者是root。 3. **c_gid**:文件所属组的组ID(Group ID)。0通常表示root组。例如,`c_gid = 0`表示该文件属于root组。 4. **c_nlink**:硬链接计数,表示有多少个目录项指向该inode。对于目录,该值至少为2(因为目录本身和其内部的"."都指向该inode)。例如,`c_nlink = 1`表示只有一个目录项指向该inode(即该文件或目录没有被硬链接)。 5. **c_mtime**:文件的最后修改时间(modification time),通常以时间戳表示。0表示未设置或未知时间(例如在构建RAM磁盘时未指定)。 6. **c_dev_maj** 和 **c_dev_min**:如果该文件是设备文件(如字符设备或块设备),这两个字段分别表示设备的主设备号和次设备号。对于非设备文件,通常设置为0。例如,`c_dev_maj = 0`和`c_dev_min = 0`表示这不是一个设备文件。 7. **c_rdev_maj** 和 **c_rdev_min**:与设备文件相关的设备号(当文件是设备文件时使用)。同样,非设备文件则设为0。 8. **file_type**:文件类型,用数值表示。常见的文件类型值包括: - `16384`(十六进制0x4000):表示目录(S_IFDIR) - `32768`(十六进制0x8000):表示普通文件(S_IFREG) - 其他可能的取值(如符号链接、设备文件等)在用户提供的示例中没有出现,但可以参考标准文件类型宏定义。 9. **file_mode**:文件权限模式,以字符串形式表示,通常使用八进制(例如"0o755")。该字符串可以直接转换为八进制数,用于设置文件的读、写、执行权限。例如: - `"0o755"` 表示所有者有读、写、执行权限(7),同组用户和其他用户有读和执行权限(5)。 在用户提供的配置表中,每个条目对应RAM磁盘中的一个文件或目录。例如: - `[debug_ramdisk]`:表示一个目录(因为file_type=16384),权限为755(所有者可读可写可执行,其他人可读可执行)。 - `[init]`:表示一个普通文件(file_type=32768),权限为750(所有者可读可写可执行,同组用户可读可执行,其他用户无权限)。 此外,最后一个条目`["TRAILER!!!"]`是特殊的,它可能表示RAM磁盘镜像的结束标记。注意,它的字段名与其他条目略有不同(例如使用了`c_mode`而不是`file_mode`),但含义类似。其`c_mode = 493`是十进制的权限表示,转换为八进制为755(因为493=0o755)。 ### 配置表的作用 该配置表用于在构建RAM磁盘镜像时指定其中包含的文件和目录的元数据属性。构建工具(如Linux内核的initramfs构建工具)会根据这样的配置表创建相应的文件系统结构,并设置正确的inode、权限、所有者等信息。 ### 与引用内容的关系 虽然用户提供的引用内容(如引用[1]至[4])涉及内核日志缓存、崩溃分析工具、分区表配置和寄存器设置,但这些内容与当前的RAM磁盘配置表没有直接关联。因此,我们在解释配置表字段时没有引用这些内容。 ### 总结 - **c_ino**: inode号,唯一标识文件 - **c_uid/c_gid**: 文件所有者的用户ID和组ID - **c_nlink**: 硬链接计数 - **c_mtime**: 最后修改时间 - **c_dev_maj/c_dev_min, c_rdev_maj/c_rdev_min**: 设备文件相关(非设备文件为0) - **file_type**: 文件类型(目录、普通文件等) - **file_mode**: 文件权限(八进制字符串) 该配置表是构建RAM磁盘镜像的元数据蓝图,确保镜像中的文件和目录具有正确的属性和结构。 §§相关问题§§ 1. 如何创建一个类似的RAM磁盘配置表? 2. 在Linux系统中,如何查看一个文件的inode信息? 3. RAM磁盘镜像中的文件类型还有哪些可能的值? 4. 如何修改RAM磁盘镜像中文件的权限?</think>### RAM磁盘配置表字段详解 `debug_ramdisk`配置表用于定义RAM磁盘镜像中文件/目录的元数据属性,这些字段在构建RAM磁盘时由内核直接解析。各字段作用如下: #### 1. **c_ino (Inode编号)** - **作用**:文件系统中文件的唯一标识符 - **示例**:`c_ino = 300000` - **说明**: - 每个文件/目录有全局唯一inode号 - 编号范围通常预留特定区间(如300000起始) - 用于快速定位文件数据块位置[^3] #### 2. **c_uid/c_gid (用户/组ID)** - **作用**:定义文件所有者权限 - **示例**:`c_uid = 0`(root用户),`c_gid = 0`(root组) - **说明**: - 0表示最高权限账户 - 决定文件访问控制(如`init`文件的`0o750`模式限制非root用户执行) #### 3. **c_nlink (硬链接计数)** - **作用**:记录指向该inode的目录项数量 - **示例**:`c_nlink = 1` - **说明**: - 普通文件初始值为1 - 目录至少为2(含`.`和`..`) - 为0时文件被标记为可删除 #### 4. **c_mtime (修改时间)** - **作用**:记录最后修改时间戳 - **示例**:`c_mtime = 0` - **说明**: - 0表示未初始化或构建时未指定 - RAM磁盘中通常固化在镜像内不变 #### 5. **设备号字段 (c_dev_*)** - **字段**: `c_dev_maj`(主设备号) `c_dev_min`(次设备号) `c_rdev_maj`/`c_rdev_min`(特殊设备号) - **作用**:标识设备文件类型 - **示例**:全为0 - **说明**: - 非0值表示块设备/字符设备 - 全0说明当前无设备文件 #### 6. **file_type (文件类型)** - **作用**:定义文件系统对象类型 - **示例**: - `16384`(0x4000):目录(如`debug_ramdisk`) - `32768`(0x8000):普通文件(如`init`) - **关键值**: ```markdown | 十六进制 | 类型 | 示例 | |----------|------------|---------------------| | 0x4000 | 目录 | /system/etc | | 0x8000 | 普通文件 | /system/bin/e2fsck | | 0xA000 | 符号链接 | (未出现) | | 0x2000 | 字符设备 | (未出现) | ``` #### 7. **file_mode (权限模式)** - **作用**:设置文件访问权限 - **示例**:`file_mode = "0o755"` - **权限解析**: - `755` → 用户:rwx,组:r-x,其他:r-x - `750` → 用户:rwx,组:r-x,其他:--- - **特殊设置**: - `init`文件设为`0o750`限制非特权用户执行 - 配置文件(如`build.prop`)设为`0o644`禁止执行 #### 8. **特殊条目:TRAILER!!!** - **作用**:RAM磁盘镜像结束标记 - **关键字段**:`c_mode = 493`(对应八进制755) - **说明**: - 标识镜像元数据部分结束 - 后续为实际文件数据块 - 校验镜像完整性[^1] ### 配置表示例解析 以`["system/bin/e2fsck"]`条目为例: ```ini ["system/bin/e2fsck"] c_ino = 300010 c_uid = 0 c_gid = 0 c_nlink = 1 file_type = 32768 # 普通文件 file_mode = "0o755" # rwxr-xr-x ``` 表示在`/system/bin/`路径下存在一个所有者为root、全局可执行的e2fsck工具程序。 ### 配置表的核心作用 1. **定义文件系统结构**:构建目录层级和文件位置 2. **设置访问控制**:通过UID/GID和权限位实现安全隔离 3. **固化元数据**:避免运行时动态生成的开销 4. **支持快速挂载**:内核可直接解析无需额外扫描[^3]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值