Linux内核文件系统5

本文主要探讨Linux ext4文件系统相对于ext2的改进,特别是增加了使用循环冗余校验(CRC)进行元数据校验的功能,以提高数据可靠性。
摘要由CSDN通过智能技术生成

2021SC@SDUSC

今天来分析ext4.h文件

#ifndef _EXT4_H
#define _EXT4_H

#include <linux/types.h>
#include <linux/blkdev.h>
#include <linux/magic.h>
#include <linux/jbd2.h>
#include <linux/quota.h>
#include <linux/rwsem.h>
#include <linux/rbtree.h>
#include <linux/seqlock.h>
#include <linux/mutex.h>
#include <linux/timer.h>
#include <linux/wait.h>
#include <linux/sched/signal.h>
#include <linux/blockgroup_lock.h>
#include <linux/percpu_counter.h>
#include <linux/ratelimit.h>
#include <crypto/hash.h>
#include <linux/falloc.h>
#include <linux/percpu-rwsem.h>
#include <linux/fiemap.h>
#ifdef __KERNEL__
#include <linux/compat.h>
#endif

#include <linux/fscrypt.h>
#include <linux/fsverity.h>

#include <linux/compiler.h>

/* 第四代扩展文件系统常量/结构*/
/*使用aggressive . check分配器对结构运行一致性检查。但这些检查会让系统运行慢很多*/
#define AGGRESSIVE_CHECK__

/*使用DOUBLE_CHECK定义的mballoc创建持久的内核位图,维护和使用它们检查双分配*/
#define DOUBLE_CHECK__

/*定义EXT4FS_DEBUG来生成调试消息*/
#undef EXT4FS_DEBUG

/*调试代码 */
#ifdef EXT4FS_DEBUG
#define ext4_debug(f, a...)
	/*为假时输出调试结果信息 */
	do {								
		printk(KERN_DEBUG "EXT4-fs DEBUG (%s, %d): %s:",	
			__FILE__, __LINE__, __func__);			
		printk(KERN_DEBUG f, ## a);				
	} while (0)
#else
#define ext4_debug(fmt, ...)	no_printk(fmt, ##__VA_ARGS__)
#endif

 /*打开EXT_DEBUG将在ext4_ext_show_path/leaf/move中启用ext4_ext_show_path*/
#define EXT_DEBUG__

/*用于受控区调试的动态printk。*/
#ifdef CONFIG_EXT4_DEBUG
#define ext_debug(ino, fmt, ...)					\
	pr_debug("[%s/%d] EXT4-fs (%s): ino %lu: (%s, %d): %s:" fmt,	\
		 current->comm, task_pid_nr(current),			\
		 ino->i_sb->s_id, ino->i_ino, __FILE__, __LINE__,	\
		 __func__, ##__VA_ARGS__)
#else
#define ext_debug(ino, fmt, ...)	no_printk(fmt, ##__VA_ARGS__)
#endif

#define ASSERT(assert)						\
do {		
/*判断参数是否一致*/							\
	if (unlikely(!(assert))) {					\
		printk(KERN_EMERG					\
		       "Assertion failure in %s() at %s:%d: '%s'\n",	\
		       __func__, __FILE__, __LINE__, #assert);		\
		BUG();							\
	}								\
} while (0)

/*块组的块偏移的数据类型*/
typedef int ext4_grpblk_t;

/*文件系统范围的块编号的数据类型 */
typedef unsigned long long ext4_fsblk_t;

/*文件逻辑块号的数据类型*/
typedef __u32 ext4_lblk_t;

/*块组号的数据类型*/
typedef unsigned int ext4_group_t;

/*枚举转换方向*/
enum SHIFT_DIRECTION {
	SHIFT_LEFT = 0,
	SHIFT_RIGHT,
};

/*在mballoc的allocation_context Flags字段中使用的标志。
也用于显示 通过traceport接口输出标志字段时的调试目标 */

/*prefer goal again. length*/
#define EXT4_MB_HINT_MERGE		0x0001
/*预留块*/
#define EXT4_MB_HINT_RESERVED		0x0002
/*正在分配的元数据*/
#define EXT4_MB_HINT_METADATA		0x0004
/*文件中的第一个块*/
#define EXT4_MB_HINT_FIRST		0x0008
/*搜索最好的块*/
#define EXT4_MB_HINT_BEST		0x0010
/*正在分配的数据 */
#define EXT4_MB_HINT_DATA		0x0020
/*不要预分配(对于尾部)*/
#define EXT4_MB_HINT_NOPREALLOC		0x0040
/*为区域组分配*/
#define EXT4_MB_HINT_GROUP_ALLOC	0x0080
/*分配目标块或不分配目标块*/
#define EXT4_MB_HINT_GOAL_ONLY		0x0100
/*目标是有意义的*/
#define EXT4_MB_HINT_TRY_GOAL		0x0200
/*已被延迟分配提前预留的块 */
#define EXT4_MB_DELALLOC_RESERVED	0x0400
/*流分配*/
#define EXT4_MB_STREAM_ALLOC		0x0800
/*如果需要,使用保留的根块*/
#define EXT4_MB_USE_ROOT_BLOCKS		0x1000
/*使用保留池中的块*/
#define EXT4_MB_USE_RESERVED		0x2000
/*在重试块分配时是否严格检查空闲块 */
#define EXT4_MB_STRICT_CHECK		0x4000
/*对于cr = 0的大片段列表查找至少成功一次*/
#define EXT4_MB_CR0_OPTIMIZED		0x8000
/*对于cr = 1,平均片段大小的rb树查找至少成功一次*/
#define EXT4_MB_CR1_OPTIMIZED		0x00010000
/*对一个组执行线性遍历*/
#define EXT4_MB_SEARCH_NEXT_LINEAR	0x00020000
struct ext4_allocation_request {
	/*我们要分配的块的目标索引节点*/
	struct inode *inode;
	/*我们要分配多少块*/
	unsigned int len;
	/*目标节点中的逻辑块 */
	ext4_lblk_t logical;
	/*最接近左边的逻辑分配块*/
	ext4_lblk_t lleft;
	/*最接近右边的逻辑分配块*/
	ext4_lblk_t lright;
	/*物理目标块(提示)*/
	ext4_fsblk_t goal;
	/*用于左边最近的逻辑分配块的物理块*/
	ext4_fsblk_t pleft;
	/*用于右边最近的逻辑分配块的物理块*/
	ext4_fsblk_t pright;
	/*以上描述EXT4_MB_HINT_ *标志*/
	unsigned int flags;
};

/ *
逻辑到物理块的映射,由ext4_map_blocks()使用。
该结构用于将请求传递给ext4_map_blocks(),以及存储ext4_map_blocks()返回的信息。它在堆栈上所占的空间小于结构体buffer_head。
 */
#define EXT4_MAP_NEW		BIT(BH_New)
#define EXT4_MAP_MAPPED		BIT(BH_Mapped)
#define EXT4_MAP_UNWRITTEN	BIT(BH_Unwritten)
#define EXT4_MAP_BOUNDARY	BIT(BH_Boundary)
#define EXT4_MAP_FLAGS		(EXT4_MAP_NEW | EXT4_MAP_MAPPED |\
				 EXT4_MAP_UNWRITTEN | EXT4_MAP_BOUNDARY)

struct ext4_map_blocks {
	ext4_fsblk_t m_pblk;
	ext4_lblk_t m_lblk;
	unsigned int m_len;
	unsigned int m_flags;
};

/*系统区域rbtree范围内块的有效性检查。 */
struct ext4_system_blocks {
	struct rb_root root;
	struct rcu_head rcu;
};

/*ext4文件系统的IO结尾的标志*/
#define	EXT4_IO_END_UNWRITTEN	0x0001

struct ext4_io_end_vec {
	struct list_head list;		/*io_end_vec列表*/
	loff_t offset;			/*文件中的偏移量*/
	ssize_t size;			/*范围大小*/
};

/*用于转换工作队列上的未写区。'handle'用于缓冲回写。*/
typedef struct ext4_io_end {
	struct list_head	list;		    /*每个文件完成的IO列表*/
	handle_t		*handle;	    /*为区段转换保留句柄*/
	struct inode	*inode;		/*正在写入的文件*/
	struct bio		*bio;		    /*覆盖范围内的完整的bios链表*/
	unsigned int	 flag;		/* unwritten or not */
	atomic_t		count;		/*引用计数器*/
	struct list_head	list_vec;	    /* ext4_io_end_vec 列表*/
} ext4_io_end_t;

struct ext4_io_submit {
	struct writeback_control *io_wbc;
	struct bio		*io_bio;
	ext4_io_end_t		*io_end;
	sector_t		io_next_block;
};

/*特殊的inode编号*/
#define	EXT4_BAD_INO		     1	/*坏块索引节点*/
#define EXT4_ROOT_INO		     2	/*根索引节点 */
#define EXT4_USR_QUOTA_INO	 3	/*用户配额索引节点 */
#define EXT4_GRP_QUOTA_INO	 4	/* 组配额索引节点*/
#define EXT4_BOOT_LOADER_INO	 5	/*引导加载程序索引节点*/
#define EXT4_UNDEL_DIR_INO	     6	/*恢复删除的目录索引节点*/
#define EXT4_RESIZE_INO		 7	/*保留组描述符索引节点*/
#define EXT4_JOURNAL_INO	     8	/*日志索引节点*/

/*第一个用于旧ext4文件系统的非保留inode*/
#define EXT4_GOOD_OLD_FIRST_INO	11

/*文件的最大链接数*/
#define EXT4_LINK_MAX		65000

/*用于管理多个块大小的宏指令*/
#define EXT4_MIN_BLOCK_SIZE		1024
#define	EXT4_MAX_BLOCK_SIZE		65536
#define EXT4_MIN_BLOCK_LOG_SIZE		10
#define EXT4_MAX_BLOCK_LOG_SIZE		16
#define EXT4_MAX_CLUSTER_LOG_SIZE	30
#ifdef __KERNEL__
# define EXT4_BLOCK_SIZE(s)		((s)->s_blocksize)
#else
# define EXT4_BLOCK_SIZE(s)		(EXT4_MIN_BLOCK_SIZE << (s)->s_log_block_size)
#endif
#define	EXT4_ADDR_PER_BLOCK(s)		(EXT4_BLOCK_SIZE(s) / sizeof(__u32))
#define EXT4_CLUSTER_SIZE(s)		(EXT4_BLOCK_SIZE(s) << \
					 EXT4_SB(s)->s_cluster_bits)
#ifdef __KERNEL__
# define EXT4_BLOCK_SIZE_BITS(s)	((s)->s_blocksize_bits)
# define EXT4_CLUSTER_BITS(s)		(EXT4_SB(s)->s_cluster_bits)
#else
# define EXT4_BLOCK_SIZE_BITS(s)	((s)->s_log_block_size + 10)
#endif
#ifdef __KERNEL__
#define	EXT4_ADDR_PER_BLOCK_BITS(s)	(EXT4_SB(s)->s_addr_per_block_bits)
#define EXT4_INODE_SIZE(s)		(EXT4_SB(s)->s_inode_size)
#define EXT4_FIRST_INO(s)		(EXT4_SB(s)->s_first_ino)
#else
#define EXT4_INODE_SIZE(s)	(((s)->s_rev_level == EXT4_GOOD_OLD_REV) ? \
				 EXT4_GOOD_OLD_INODE_SIZE : \
				 (s)->s_inode_size)
#define EXT4_FIRST_INO(s)	(((s)->s_rev_level == EXT4_GOOD_OLD_REV) ? \
				 EXT4_GOOD_OLD_FIRST_INO : \
				 (s)->s_first_ino)
#endif
#define EXT4_BLOCK_ALIGN(size, blkbits)		ALIGN((size), (1 << (blkbits)))
#define EXT4_MAX_BLOCKS(size, offset, blkbits) \
	((EXT4_BLOCK_ALIGN(size + offset, blkbits) >> blkbits) - (offset >> \
								  blkbits))

/*block to cluster将块号转换为集群号*/
#define EXT4_B2C(sbi, blk)	((blk) >> (sbi)->s_cluster_bits)
/* C2B的逆转将集群号转换为块号 */
#define EXT4_C2B(sbi, cluster)	((cluster) << (sbi)->s_cluster_bits)
/*将blks的#转换为集群的# */
#define EXT4_NUM_B2C(sbi, blks)	(((blks) + (sbi)->s_cluster_ratio - 1) >> \
				 (sbi)->s_cluster_bits)
/*屏蔽低位以获得集群的起始块 */
#define EXT4_PBLK_CMASK(s, pblk) ((pblk) &				\
				  ~((ext4_fsblk_t) (s)->s_cluster_ratio - 1))
#define EXT4_LBLK_CMASK(s, lblk) ((lblk) &				\
				  ~((ext4_lblk_t) (s)->s_cluster_ratio - 1))
/*填充低位以获得集群的最后一个块*/
#define EXT4_LBLK_CFILL(sbi, lblk) ((lb
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值
>