linux中的文件系统与inode

linux文件系统

超级块(super block)

文件系统的全局信息

文件系统的元数据

是文件系统第一个块

所包含的重要信息:

  1. 文件系统大小
  2. 块大小
  3. inode表大小
  4. 文件系统布局
    作用:
  5. 管理文件系统:识别文件系统的类型、结构、状态;
  6. 提供文件系统的操作接口:文件系统操作的函数指针
  7. 维护状态一致:挂载状态,读写状态
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;
相关推荐
bksczm21 小时前
Linux之网络层协议(IP协议)
linux·网络·tcp/ip
深念Y21 小时前
无头电视盒子改服务器调优记录
linux·运维·服务器·串口·嵌入式·电视盒子·海思
我是小灰灰吖21 小时前
Qt 6.9.3 Ubuntu 22.04 虚拟键盘显示问题全记录与解决方案
linux·qt·ubuntu
Mortalbreeze21 小时前
深入理解TCP协议(一):TCP报文格式详解
linux·服务器·网络·tcp/ip
三言老师1 天前
K8s 集群 LocalPV 静态 PV 资源手动创建实操
linux·运维·服务器·kubernetes
一直在努力学习的菜鸟1 天前
Rocky Linux 8.10 编译安装 PostgreSQL 17.11
linux·运维
Doraemomo1 天前
Linux编程-进程的执行和退出
linux·运维·服务器
lengjingzju1 天前
编译与调试完全指南—第5章 GDB调试详解
linux
艾伦_耶格宇1 天前
【ELK】-5 kibana和filebeat
linux·运维·ubuntu·elk
DevHub1 天前
电视盒子刷 Armbian 教程:30 元旧盒子变 NAS 跑 Docker,200+ 机型可刷
linux·嵌入式硬件·docker·容器·开源·电视盒子