文件元数据 文件本身内容之外的所有属性信息Linux 内核通过inode作为核心载体管理配套 dentry、super_block、file 等结构协同工作。inode索引节点文件元数据核心容器磁盘持久化 内核内存缓存dentry目录项文件名 inode 映射负责路径解析、目录缓存super_block文件系统全局元数据分区、块大小、挂载信息struct file进程打开文件后的内存态句柄元数据仅运行时存在inode最核心的文件元数据inode 存储位置磁盘 inode文件系统分区内永久存储ext4/xfs/btrfs 格式不同内存 inode (struct inode)内核加载到内存所有文件操作都依赖它内核struct inode关键元数据Linux 通用字段struct inode { // 1. 身份标识 umode_t i_mode; // 文件类型 权限(rwx) unsigned short i_nlink; // 硬链接计数 uid_t i_uid; // 所有者UID gid_t i_gid; // 所属组GID ino_t i_ino; // inode 编号(分区内唯一) // 2. 时间戳标准三大时间 struct timespec64 i_atime; // 访问时间 (read) struct timespec64 i_mtime; // 修改时间 (内容写入) struct timespec64 i_ctime; // 状态修改时间 (权限/属主/链接变) // 3. 大小与存储 loff_t i_size; // 文件大小(字节) blkcnt_t i_blocks; // 占用磁盘块数 unsigned int i_blkbits; // 块大小位数 // 4. 类型与操作接口 const struct file_operations *i_fop; // 文件读写回调 const struct inode_operations *i_op; // inode操作(创建/删除/链接) // 5. 设备相关设备文件专用 dev_t i_rdev; // 设备号(字符/块设备) // 6. 内核状态标记 unsigned long i_state; // inode状态(脏、锁定、缓存等) struct super_block *i_sb; // 所属文件系统超级块 };三大时间戳区别字段含义触发场景atime访问时间cat/less/cp读取文件内容mtime内容修改时间echo/vi/write改动文件数据ctime元数据修改时间chmod/chown/ln/rename/truncate现代 Linux 默认noatime关闭 atime 更新提升性能。i_mode 解析文件类型 权限i_mode高 4 位表示文件类型低 9 位是权限位文件类型常见S_IFREG普通文件S_IFDIR目录S_IFLNK软链接S_IFCHR字符设备S_IFBLK块设备S_IFIFO管道dentry 目录项文件名 - inode 映射inode不存文件名文件名由dentry管理。核心作用保存文件名、父目录、对应 inode内核dcache目录项缓存加速路径查找/a/b/c逐层解析关键结构字段struct dentry { const char *d_name; // 文件名 struct inode *d_inode; // 指向对应 inode struct dentry *d_parent; // 父目录dentry unsigned int d_flags; // 状态标记(挂载点、缓存等) };关系路径字符串→ dentry → inode → 文件数据块super_block 超级块文件系统全局元数据每个挂载的文件系统分区对应一个super_block描述整个分区属性。核心元数据文件系统类型ext4/xfs/tmpfs总块数、空闲块、总 inode、空闲 inode块大小、扇区大小挂载点路径、挂载参数ro/rw、relatime 等根目录 inode / 根 dentrystruct file进程打开文件的运行时元数据仅存在于内存进程打开文件后创建关闭即销毁不属于磁盘元数据。关键字段struct file { struct path f_path; // 对应 dentry super_block struct inode *f_inode; // 指向真实 inode loff_t f_pos; // 文件读写偏移量(指针位置) unsigned int f_flags; // 打开标志 O_RDONLY/O_WRONLY/O_APPEND const struct file_operations *f_op; // 读写接口 };特点多个进程 / 多次open同一个文件 →多个 struct file但共享同一个 inode每个struct file拥有独立的读写偏移 f_pos用户态查看文件元数据1.stat命令最常用stat test.txt输出逐项对应内核元数据File文件名 → dentrySizei_sizeBlocksi_blocksIO Block文件系统块大小 → super_blockDevice分区设备号Inodei_inoLinksi_nlink 硬链接数Uid/Gidi_uid / i_gidAccess/Modify/Changeatime / mtime / ctimePermissionsi_mode 权限位2. 查看 inode 号ls -i3. 只看三大时间stat -c %x %y %z test.txt硬链接 / 软链接 与元数据关系硬链接多个 dentry 指向同一个 inodei_nlink链接计数 1不创建新 inode共享所有元数据软链接符号链接独立 inode 独立 dentryinode 类型为S_IFLNK文件内容 目标路径字符串内核关键数据流访问文件全过程用户open(/tmp/a.txt)内核解析路径 → 查 dcache (dentry 缓存)拿到 dentry → 关联 inode无则从磁盘加载 inode 到内存创建struct file记录偏移、权限、标志返回文件描述符 fdread/write 通过struct file→inode→ 磁盘数据块不同文件系统元数据差异ext4经典固定 inode 表元数据分区独立存放支持扩展属性xfs动态分配 inode无固定 inode 区域大分区友好tmpfs纯内存文件系统无磁盘元数据重启丢失btrfsCopy-on-Write元数据也走快照 / 重定向xattrExtended Attributes文件系统的扩展属性是与文件 / 目录绑定的键值对keyvalue用来存放标准 inode 之外的自定义元数据。标准 inode权限、uid、gid、大小、atime/mtime/ctime、硬链接数xattr额外附加如作者、MIME 类型、ACL、SELinux 标签、能力cap、校验和等四大命名空间Namespacekey 必须带前缀决定权限与用途前缀名称权限典型用途user.用户属性普通用户可读写需挂载user_xattr自定义标签、作者、版本、注释system.系统属性内核 / 特权进程POSIX ACL、文件能力capsecurity.安全属性内核 / 安全模块SELinux 上下文、Smack 标签trusted.可信属性root -only加密标记、私有元数据示例 keyuser.commentsecurity.selinuxsystem.posix_acl_accesstrusted.md5sum内核实现原理ext4 为例1. 存储位置xattr不属于文件内容也不属于目录项它是inode 的附属数据。xattr 是 inode 的附属元数据优先存在 inode 内部放不下则存在独立的 xattr 数据块。VFS 提供统一接口文件系统把 xattr 存在 inode 或单独块中与文件内容完全分离。磁盘上只有两个地方能存 xattr1inode 内嵌入式in-inodeinode 尾部预留小空间通常几十到 100 字节存小尺寸 xattr访问最快i_extra_isize控制可用大小优点不需要额外读磁盘块速度最快缺点空间很小通常几十100 字节放不下太多 xattr2外部数据块block大 / 多 xattr 时分配独立块inode 的i_file_acl指向该块支持链式但现代文件系统一般单级2. 内核数据结构VFS 层// fs/xattr.c 核心接口 struct xattr_handler { const char *prefix; // 命名空间前缀 int (*get)(struct inode *, const char *, void *, size_t); int (*set)(struct inode *, const char *, const void *, size_t, int); }; // inode 中关联字段 struct inode { ... struct super_block *i_sb; unsigned int i_extra_isize; // in-inode xattr 可用大小 blk64_t i_file_acl; // 外部 xattr 块指针 ... };VFS 提供统一getxattr/setxattr接口各文件系统ext4/xfs/btrfs各自实现xattr_operationsxattr 的磁盘结构布局ext4 真实结构inode 内部结构┌─────────────────────────────────────┐ │ 标准 inode 元数据 │ │ 权限、大小、时间、指针... │ ├─────────────────────────────────────┤ │ i_extra_isize已用额外空间 │ ├─────────────────────────────────────┤ │ 【xattr 存储区】← 小 xattr 放这里 │ └─────────────────────────────────────┘如果 inode 放不下┌───────────────┐ │ inode │ │ i_file_acl ────────→ xattr block │ └───────────────┘ 存所有扩展属性xattr内核原理VFS 文件系统两层内核读写 xattr 分两层第一层VFS 虚拟文件系统统一接口用户调用setxattr()getxattr()listxattr()VFS 只做检查权限user/security/system 命名空间找到文件对应的 inode调用具体文件系统的 xattr 方法第二层ext4/xfs 真正实现存磁盘以 ext4 为例先看 inode 内部空间够不够够 → 直接写 inode 尾部不够 → 分配 xattr block写进去更新 inode 的 xattr 指针典型应用场景文件 ACL访问控制列表system.posix_acl_access实现细粒度权限如 userA:r--、groupB:rw-SELinux 安全标签security.selinux强制访问控制MAC限制进程对文件的访问文件能力Capabilitiessecurity.capability替代 root给程序特定权限如CAP_NET_BIND_SERVICE自定义元数据文档管理作者、版本、分类、过期时间网盘 / 备份校验和、存储位置、加密标记
linux内核 文件元数据
文件元数据 文件本身内容之外的所有属性信息Linux 内核通过inode作为核心载体管理配套 dentry、super_block、file 等结构协同工作。inode索引节点文件元数据核心容器磁盘持久化 内核内存缓存dentry目录项文件名 inode 映射负责路径解析、目录缓存super_block文件系统全局元数据分区、块大小、挂载信息struct file进程打开文件后的内存态句柄元数据仅运行时存在inode最核心的文件元数据inode 存储位置磁盘 inode文件系统分区内永久存储ext4/xfs/btrfs 格式不同内存 inode (struct inode)内核加载到内存所有文件操作都依赖它内核struct inode关键元数据Linux 通用字段struct inode { // 1. 身份标识 umode_t i_mode; // 文件类型 权限(rwx) unsigned short i_nlink; // 硬链接计数 uid_t i_uid; // 所有者UID gid_t i_gid; // 所属组GID ino_t i_ino; // inode 编号(分区内唯一) // 2. 时间戳标准三大时间 struct timespec64 i_atime; // 访问时间 (read) struct timespec64 i_mtime; // 修改时间 (内容写入) struct timespec64 i_ctime; // 状态修改时间 (权限/属主/链接变) // 3. 大小与存储 loff_t i_size; // 文件大小(字节) blkcnt_t i_blocks; // 占用磁盘块数 unsigned int i_blkbits; // 块大小位数 // 4. 类型与操作接口 const struct file_operations *i_fop; // 文件读写回调 const struct inode_operations *i_op; // inode操作(创建/删除/链接) // 5. 设备相关设备文件专用 dev_t i_rdev; // 设备号(字符/块设备) // 6. 内核状态标记 unsigned long i_state; // inode状态(脏、锁定、缓存等) struct super_block *i_sb; // 所属文件系统超级块 };三大时间戳区别字段含义触发场景atime访问时间cat/less/cp读取文件内容mtime内容修改时间echo/vi/write改动文件数据ctime元数据修改时间chmod/chown/ln/rename/truncate现代 Linux 默认noatime关闭 atime 更新提升性能。i_mode 解析文件类型 权限i_mode高 4 位表示文件类型低 9 位是权限位文件类型常见S_IFREG普通文件S_IFDIR目录S_IFLNK软链接S_IFCHR字符设备S_IFBLK块设备S_IFIFO管道dentry 目录项文件名 - inode 映射inode不存文件名文件名由dentry管理。核心作用保存文件名、父目录、对应 inode内核dcache目录项缓存加速路径查找/a/b/c逐层解析关键结构字段struct dentry { const char *d_name; // 文件名 struct inode *d_inode; // 指向对应 inode struct dentry *d_parent; // 父目录dentry unsigned int d_flags; // 状态标记(挂载点、缓存等) };关系路径字符串→ dentry → inode → 文件数据块super_block 超级块文件系统全局元数据每个挂载的文件系统分区对应一个super_block描述整个分区属性。核心元数据文件系统类型ext4/xfs/tmpfs总块数、空闲块、总 inode、空闲 inode块大小、扇区大小挂载点路径、挂载参数ro/rw、relatime 等根目录 inode / 根 dentrystruct file进程打开文件的运行时元数据仅存在于内存进程打开文件后创建关闭即销毁不属于磁盘元数据。关键字段struct file { struct path f_path; // 对应 dentry super_block struct inode *f_inode; // 指向真实 inode loff_t f_pos; // 文件读写偏移量(指针位置) unsigned int f_flags; // 打开标志 O_RDONLY/O_WRONLY/O_APPEND const struct file_operations *f_op; // 读写接口 };特点多个进程 / 多次open同一个文件 →多个 struct file但共享同一个 inode每个struct file拥有独立的读写偏移 f_pos用户态查看文件元数据1.stat命令最常用stat test.txt输出逐项对应内核元数据File文件名 → dentrySizei_sizeBlocksi_blocksIO Block文件系统块大小 → super_blockDevice分区设备号Inodei_inoLinksi_nlink 硬链接数Uid/Gidi_uid / i_gidAccess/Modify/Changeatime / mtime / ctimePermissionsi_mode 权限位2. 查看 inode 号ls -i3. 只看三大时间stat -c %x %y %z test.txt硬链接 / 软链接 与元数据关系硬链接多个 dentry 指向同一个 inodei_nlink链接计数 1不创建新 inode共享所有元数据软链接符号链接独立 inode 独立 dentryinode 类型为S_IFLNK文件内容 目标路径字符串内核关键数据流访问文件全过程用户open(/tmp/a.txt)内核解析路径 → 查 dcache (dentry 缓存)拿到 dentry → 关联 inode无则从磁盘加载 inode 到内存创建struct file记录偏移、权限、标志返回文件描述符 fdread/write 通过struct file→inode→ 磁盘数据块不同文件系统元数据差异ext4经典固定 inode 表元数据分区独立存放支持扩展属性xfs动态分配 inode无固定 inode 区域大分区友好tmpfs纯内存文件系统无磁盘元数据重启丢失btrfsCopy-on-Write元数据也走快照 / 重定向xattrExtended Attributes文件系统的扩展属性是与文件 / 目录绑定的键值对keyvalue用来存放标准 inode 之外的自定义元数据。标准 inode权限、uid、gid、大小、atime/mtime/ctime、硬链接数xattr额外附加如作者、MIME 类型、ACL、SELinux 标签、能力cap、校验和等四大命名空间Namespacekey 必须带前缀决定权限与用途前缀名称权限典型用途user.用户属性普通用户可读写需挂载user_xattr自定义标签、作者、版本、注释system.系统属性内核 / 特权进程POSIX ACL、文件能力capsecurity.安全属性内核 / 安全模块SELinux 上下文、Smack 标签trusted.可信属性root -only加密标记、私有元数据示例 keyuser.commentsecurity.selinuxsystem.posix_acl_accesstrusted.md5sum内核实现原理ext4 为例1. 存储位置xattr不属于文件内容也不属于目录项它是inode 的附属数据。xattr 是 inode 的附属元数据优先存在 inode 内部放不下则存在独立的 xattr 数据块。VFS 提供统一接口文件系统把 xattr 存在 inode 或单独块中与文件内容完全分离。磁盘上只有两个地方能存 xattr1inode 内嵌入式in-inodeinode 尾部预留小空间通常几十到 100 字节存小尺寸 xattr访问最快i_extra_isize控制可用大小优点不需要额外读磁盘块速度最快缺点空间很小通常几十100 字节放不下太多 xattr2外部数据块block大 / 多 xattr 时分配独立块inode 的i_file_acl指向该块支持链式但现代文件系统一般单级2. 内核数据结构VFS 层// fs/xattr.c 核心接口 struct xattr_handler { const char *prefix; // 命名空间前缀 int (*get)(struct inode *, const char *, void *, size_t); int (*set)(struct inode *, const char *, const void *, size_t, int); }; // inode 中关联字段 struct inode { ... struct super_block *i_sb; unsigned int i_extra_isize; // in-inode xattr 可用大小 blk64_t i_file_acl; // 外部 xattr 块指针 ... };VFS 提供统一getxattr/setxattr接口各文件系统ext4/xfs/btrfs各自实现xattr_operationsxattr 的磁盘结构布局ext4 真实结构inode 内部结构┌─────────────────────────────────────┐ │ 标准 inode 元数据 │ │ 权限、大小、时间、指针... │ ├─────────────────────────────────────┤ │ i_extra_isize已用额外空间 │ ├─────────────────────────────────────┤ │ 【xattr 存储区】← 小 xattr 放这里 │ └─────────────────────────────────────┘如果 inode 放不下┌───────────────┐ │ inode │ │ i_file_acl ────────→ xattr block │ └───────────────┘ 存所有扩展属性xattr内核原理VFS 文件系统两层内核读写 xattr 分两层第一层VFS 虚拟文件系统统一接口用户调用setxattr()getxattr()listxattr()VFS 只做检查权限user/security/system 命名空间找到文件对应的 inode调用具体文件系统的 xattr 方法第二层ext4/xfs 真正实现存磁盘以 ext4 为例先看 inode 内部空间够不够够 → 直接写 inode 尾部不够 → 分配 xattr block写进去更新 inode 的 xattr 指针典型应用场景文件 ACL访问控制列表system.posix_acl_access实现细粒度权限如 userA:r--、groupB:rw-SELinux 安全标签security.selinux强制访问控制MAC限制进程对文件的访问文件能力Capabilitiessecurity.capability替代 root给程序特定权限如CAP_NET_BIND_SERVICE自定义元数据文档管理作者、版本、分类、过期时间网盘 / 备份校验和、存储位置、加密标记