linux文件系统
超级块(super block)
文件系统的全局信息
文件系统的元数据
是文件系统第一个块
所包含的重要信息:
- 文件系统大小
- 块大小
- inode表大小
- 文件系统布局
作用: - 管理文件系统:识别文件系统的类型、结构、状态;
- 提供文件系统的操作接口:文件系统操作的函数指针
- 维护状态一致:挂载状态,读写状态
c
struct super_block {
struct list_head s_list; /* 保持此字段在首位,用于超级块链表 */
dev_t s_dev; /* 设备号,用于查找索引 */
unsigned char s_blocksize_bits; /* 块大小的位数(以2的对数表示) */
unsigned long s_blocksize; /* 块大小(字节) */
loff_t s_maxbytes; /* 文件最大大小 */
struct file_system_type *s_type; /* 文件系统类型指针 */
const struct super_operations *s_op; /* 超级块操作函数集 */
const struct dquot_operations *dq_op; /* 磁盘配额操作函数集 */
const struct quotactl_ops *s_qcop; /* 配额控制操作函数集 */
const struct export_operations *s_export_op; /* 导出操作函数集(用于NFS等) */
unsigned long s_flags; /* 超级块标志位 */
unsigned long s_iflags; /* 内部标志位 SB_I_* */
unsigned long s_magic; /* 文件系统魔数,用于标识文件系统类型 */
struct dentry *s_root; /* 根目录的dentry(目录项) */
struct rw_semaphore s_umount; /* 卸载读写信号量,控制卸载操作 */
int s_count; /* 超级块引用计数 */
atomic_t s_active; /* 活跃引用计数(原子操作) */
#ifdef CONFIG_SECURITY
void *s_security; /* 安全模块私有数据 */
#endif
const struct xattr_handler **s_xattr; /* 扩展属性处理函数数组 */
#ifdef CONFIG_FS_ENCRYPTION
const struct fscrypt_operations *s_cop; /* 文件系统加密操作函数集 */
struct fscrypt_keyring *s_master_keys; /* 正在使用的加密主密钥 */
#endif
#ifdef CONFIG_FS_VERITY
const struct fsverity_operations *s_vop; /* 文系统完整性校验操作函数集 */
#endif
#if IS_ENABLED(CONFIG_UNICODE)
struct unicode_map *s_encoding; /* Unicode编码映射表(用于大小写不敏感) */
__u16 s_encoding_flags; /* Unicode编码标志 */
#endif
struct hlist_bl_head s_roots; /* 备用根dentry链表(用于NFS) */
struct list_head s_mounts; /* 挂载点链表,仅供VFS使用 */
struct block_device *s_bdev; /* 对应的块设备指针 */
struct backing_dev_info *s_bdi; /* 后备设备信息(用于回写) */
struct mtd_info *s_mtd; /* MTD设备信息(用于闪存文件系统) */
struct hlist_node s_instances; /* 文件系统实例链表节点 */
unsigned int s_quota_types; /* 支持的配额类型位掩码 */
struct quota_info s_dquot; /* 磁盘配额相关选项 */
struct sb_writers s_writers; /* 超级块写入者计数(冻结控制) */
/*
* 将 s_fs_info、s_time_gran、s_fsnotify_mask 和
* s_fsnotify_marks 放在一起以提高缓存效率。
* 它们被频繁访问但很少修改。
*/
void *s_fs_info; /* 文件系统私有信息 */
/* 创建/修改/访问时间戳的粒度(纳秒),最粗为一秒 */
u32 s_time_gran;
/* 创建/修改/访问时间戳的上下限(秒) */
time64_t s_time_min;
time64_t s_time_max;
#ifdef CONFIG_FSNOTIFY
__u32 s_fsnotify_mask; /* 文件系统通知掩码 */
struct fsnotify_mark_connector __rcu *s_fsnotify_marks; /* 文件系统通知标记 */
#endif
char s_id[32]; /* 文件系统标识名称(如"sda1") */
uuid_t s_uuid; /* 文件系统的UUID */
unsigned int s_max_links; /* 最大硬链接数 */
fmode_t s_mode; /* 文件系统挂载模式 */
/*
* 以下字段仅供VFS使用,文件系统实现不应直接访问。
*/
struct mutex s_vfs_rename_mutex; /* VFS重命名互斥锁,防止跨目录重命名冲突 */
/*
* 文件系统子类型。如果非空,则 /proc/mounts 中的
* 文件系统类型字段将显示为 "type.subtype"
*/
const char *s_subtype; /* 文件系统子类型名称 */
const struct dentry_operations *s_d_op; /* 默认的dentry操作函数集 */
struct shrinker s_shrink; /* 每个超级块的shrinker句柄(用于内存回收) */
/* 链接数为0但仍被引用的inode数量 */
atomic_long_t s_remove_count;
/*
* 正在被监视的inode/mount/sb对象数量,
* 注意inode对象目前被重复计数。
*/
atomic_long_t s_fsnotify_connectors;
/* 正在被重新挂载为只读 */
int s_readonly_remount;
/* 每个超级块的errseq_t,用于通过syncfs报告回写错误 */
errseq_t s_wb_err;
/* 从中断上下文延迟的AIO完成工作队列 */
struct workqueue_struct *s_dio_done_wq;
struct hlist_head s_pins; /* 引脚链表(用于fs核心) */
/*
* 所属的用户命名空间,以及解释文件系统
* uid、gid、配额、设备节点、扩展属性和安全标签的默认上下文。
*/
struct user_namespace *s_user_ns;
/*
* list_lru结构本质上只是一个指向每节点LRU链表的指针,
* 每个链表有自己的自旋锁,无需放入单独的缓存行。
*/
struct list_lru s_dentry_lru; /* dentry的LRU链表 */
struct list_lru s_inode_lru; /* inode的LRU链表 */
struct rcu_head rcu; /* RCU回调头(用于延迟释放) */
struct work_struct destroy_work; /* 销毁工作项 */
struct mutex s_sync_lock; /* 同步序列化锁 */
/*
* 表示此超级块在文件系统堆栈中的深度
*/
int s_stack_depth;
/* s_inode_list_lock 保护 s_inodes */
spinlock_t s_inode_list_lock ____cacheline_aligned_in_smp; /* inode列表自旋锁 */
struct list_head s_inodes; /* 所有inode的链表 */
spinlock_t s_inode_wblist_lock; /* inode回写列表自旋锁 */
struct list_head s_inodes_wb; /* 需要回写的inode链表 */
} __randomize_layout;
inode表(inode table)
存储文件/目录的inode信息
数据块(data blocks)
文件系统存取文件的最小单元,由多个连续的扇区组成
存储文件/目录的实际数据
块位图
多个比特位组成的数据结构,1表示占据,0表示空闲
inode
文件的元数据
数据结构:以数组的形式存储
作用:跟踪文件系统中所有的文件与目录;每个文件和目录在文件系统都有唯一的inode对应
文件的原文件信息
硬链接:指向文件的数据块(指针)
链接数属性记录有多少个文件名指向同一个inode
多个硬链接共享inode号和数据块,删除一个不会影响
只能指向相同的文件系统
软链接:独立文件,指向另一个文件/目录的路径(快捷方式)可以指向不同的文件系统
c
struct inode {
umode_t i_mode; /* 文件类型和访问权限(如0755) */
unsigned short i_opflags; /* inode操作标志 */
kuid_t i_uid; /* 文件所有者的用户ID */
kgid_t i_gid; /* 文件所有者的组ID */
unsigned int i_flags; /* inode标志位(如同步、不可变等) */
#ifdef CONFIG_FS_POSIX_ACL
struct posix_acl *i_acl; /* 访问控制列表(ACL) */
struct posix_acl *i_default_acl; /* 默认ACL(用于目录继承) */
#endif
const struct inode_operations *i_op; /* inode操作函数集 */
struct super_block *i_sb; /* 所属的超级块指针 */
struct address_space *i_mapping; /* 地址空间映射(用于页面缓存) */
#ifdef CONFIG_SECURITY
void *i_security; /* 安全模块私有数据 */
#endif
/* 状态数据,路径遍历时不访问 */
unsigned long i_ino; /* inode编号,文件系统中唯一标识 */
/*
* 文件系统只能直接读取 i_nlink,修改时必须使用以下函数:
*
* (set|clear|inc|drop)_nlink
* inode_(inc|dec)_link_count
*/
union {
const unsigned int i_nlink; /* 硬链接计数(只读视图) */
unsigned int __i_nlink; /* 硬链接计数(可写视图) */
};
dev_t i_rdev; /* 设备号(仅对设备文件有效) */
loff_t i_size; /* 文件大小(字节) */
struct timespec64 i_atime; /* 最后访问时间 */
struct timespec64 i_mtime; /* 最后修改时间 */
struct timespec64 i_ctime; /* 最后状态改变时间 */
spinlock_t i_lock; /* 保护 i_blocks、i_bytes,可能还有 i_size 的自旋锁 */
unsigned short i_bytes; /* 文件末尾不足一个块的字节数 */
u8 i_blkbits; /* 块大小的位数(以2的对数表示) */
u8 i_write_hint; /* 写入提示(用于优化写入路径) */
blkcnt_t i_blocks; /* 文件占用的块数 */
#ifdef __NEED_I_SIZE_ORDERED
seqcount_t i_size_seqcount; /* i_size的顺序计数器(保证读取顺序) */
#endif
/* 杂项 */
unsigned long i_state; /* inode状态标志位 */
struct rw_semaphore i_rwsem; /* inode读写信号量 */
unsigned long dirtied_when; /* 首次被标记为脏的时间(jiffies) */
unsigned long dirtied_time_when; /* 脏时间戳被修改的时间(jiffies) */
struct hlist_node i_hash; /* inode哈希表节点 */
struct list_head i_io_list; /* 后备设备IO链表 */
#ifdef CONFIG_CGROUP_WRITEBACK
struct bdi_writeback *i_wb; /* 关联的cgroup回写设备 */
/* 外部inode检测,参见 wbc_detach_inode() */
int i_wb_frn_winner; /* 当前获胜的外部回写设备ID */
u16 i_wb_frn_avg_time; /* 外部回写平均时间 */
u16 i_wb_frn_history; /* 外部回写历史记录 */
#endif
struct list_head i_lru; /* inode LRU链表(用于内存回收) */
struct list_head i_sb_list; /* 所属超级块的inode链表 */
struct list_head i_wb_list; /* 后备设备回写链表 */
union {
struct hlist_head i_dentry; /* 关联的dentry链表头 */
struct rcu_head i_rcu; /* RCU回调头(用于延迟释放) */
};
atomic64_t i_version; /* inode版本号(用于检测变更) */
atomic64_t i_sequence; /* 序列号(用于futex) */
atomic_t i_count; /* inode引用计数 */
atomic_t i_dio_count; /* 直接IO引用计数 */
atomic_t i_writecount; /* 写者计数(用于写者互斥) */
#if defined(CONFIG_IMA) || defined(CONFIG_FILE_LOCKING)
atomic_t i_readcount; /* 以只读方式打开的struct files计数 */
#endif
union {
const struct file_operations *i_fop; /* 文件操作函数集(默认文件操作) */
void (*free_inode)(struct inode *); /* 自定义inode释放函数 */
};
struct file_lock_context *i_flctx; /* 文件锁上下文 */
struct address_space i_data; /* inode的地址空间(页面缓存) */
struct list_head i_devices; /* 设备链表(用于块设备/字符设备) */
union {
struct pipe_inode_info *i_pipe; /* 管道信息(仅对管道文件有效) */
struct cdev *i_cdev; /* 字符设备信息(仅对字符设备有效) */
char *i_link; /* 符号链接目标路径 */
unsigned i_dir_seq; /* 目录序列号(用于目录并发控制) */
};
__u32 i_generation; /* inode世代号(用于NFS文件句柄) */
#ifdef CONFIG_FSNOTIFY
__u32 i_fsnotify_mask; /* 此inode关注的所有事件掩码 */
struct fsnotify_mark_connector __rcu *i_fsnotify_marks; /* 文件系统通知标记 */
#endif
#ifdef CONFIG_FS_ENCRYPTION
struct fscrypt_info *i_crypt_info; /* 加密信息 */
#endif
#ifdef CONFIG_FS_VERITY
struct fsverity_info *i_verity_info; /* 文件完整性校验信息 */
#endif
void *i_private; /* 文件系统或设备的私有指针 */
} __randomize_layout;