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;
相关推荐
Fcy64832 分钟前
Linux下 进程间关系与守护进程
linux·运维·服务器·守护进程
码农小韩1 小时前
Linux驱动理论(二)——Linux字符设备驱动
linux·嵌入式软件开发·linux操作系统·linux应用开发·linux驱动理论
well06121 小时前
Linux粘滞位与Makefile机制深度解析
linux·运维·服务器
再写一行代码就下班1 小时前
linux sh脚本在windows修改导致无法使用解决方式
java·linux·centos
额额额对了2 小时前
SPI通信
linux·c语言·汇编·单片机·嵌入式硬件·arm
子木HAPPY阳VIP2 小时前
Ubuntu 关闭防火墙操作步骤
linux·运维·ubuntu
王振超wzc2 小时前
嵌入式开发环境搭建--WM软件安装,Ubuntu操作系统安装
linux·运维·ubuntu
GeW4 小时前
制造强国底座:Linux与数据库驱动的新型工业基础设施
linux
xiaoye-duck4 小时前
《Linux 网络编程》深入理解 IO 多路复用:select 函数详解与 Echo 服务实战
linux·网络
Tairitsu_H4 小时前
[Linux系统] 命令行参数 | 环境变量 | 程序地址空间
linux·环境变量·命令行参数·程序地址空间