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