`
M_ittrue
  • 浏览: 77014 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

ext2文件系统结构体组成

 
阅读更多

The Second Extended File System(ext2)文件系统是Linux系统中的标准文件系统,是通过对Minix的文件系统进行扩展而得到的,其存取文件的性能极好。
在ext2文件系统中,文件由inode(包含有文件的所有信息)进行唯一标识。一个文件可能对应多个文件名,只有在所有文件名都被删除后,该文件才会被删除。此外,同一文件在磁盘中存放和被打开时所对应的inode是不同的,并由内核负责同步。
ext2文件系统采用三级间接块来存储数据块指针,并以块(block,默认为1KB)为单位分配空间。其磁盘分配策略是尽可能将逻辑相邻的文件分配到磁盘上物理相邻的块中,并尽可能将碎片分配给尽量少的文件,以从全局上提高性能。ext2文件系统将同一目录下的文件(包括目录)尽可能的放在同一个块组中,但目录则分布在各个块组中以实现负载均衡。在扩展文件时,会尽量一次性扩展8个连续块给文件(以预留空间的形式实现)。
一、磁盘组织
在ext2系统中,所有元数据结构的大小均基于“块”,而不是“扇区”。块的大小随文件系统的大小而有所不同。而一定数量的块又组成一个块组,每个块组的起始部分有多种多样的描述该块组各种属性的元数据结构。ext2系统中对各个结构的定义都包含在源代码的include/linux/ext2_fs.h文件中。
1、超级块
每个ext2文件系统都必须包含一个超级块,其中存储了该文件系统的大量基本信息,包括块的大小、每块组中包含的块数等。同时,系统会对超级块进行备份,备份被存放在块组的第一个块中。超级块的起始位置为其所在分区的第1024个字节,占用1KB的空间,其结构如下:
struct ext2_super_block {
__le32 s_inodes_count; // 文件系统中inode的总数
__le32 s_blocks_count; // 文件系统中块的总数
__le32 s_r_blocks_count; // 保留块的总数
__le32 s_free_blocks_count; // 未使用的块的总数(包括保留块)
__le32 s_free_inodes_count; // 未使用的inode的总数
__le32 s_first_data_block; // 块ID,在小于1KB的文件系统中为0,大于1KB的文件系统中为1
__le32 s_log_block_size; // 用以计算块的大小(1024算术左移该值即为块大小)
__le32 s_log_frag_size; // 用以计算段大小(为正则1024算术左移该值,否则右移)
__le32 s_blocks_per_group; // 每个块组中块的总数
__le32 s_frags_per_group; // 每个块组中段的总数
__le32 s_inodes_per_group; // 每个块组中inode的总数
__le32 s_mtime; // POSIX中定义的文件系统装载时间
__le32 s_wtime; // POSIX中定义的文件系统最近被写入的时间
__le16 s_mnt_count; // 最近一次完整校验后被装载的次数
__le16 s_max_mnt_count; // 在进行完整校验前还能被装载的次数
__le16 s_magic; // 文件系统标志,ext2中为0xEF53
__le16 s_state; // 文件系统的状态
__le16 s_errors; // 文件系统发生错误时驱动程序应该执行的操作
__le16 s_minor_rev_level; // 局部修订级别
__le32 s_lastcheck; // POSIX中定义的文件系统最近一次检查的时间
__le32 s_checkinterval; // POSIX中定义的文件系统最近检查的最大时间间隔
__le32 s_creator_os; // 生成该文件系统的操作系统
__le32 s_rev_level; // 修订级别
__le16 s_def_resuid; // 报留块的默认用户ID
__le16 s_def_resgid; // 保留块的默认组ID
// 仅用于使用动态inode大小的修订版(EXT2_DYNAMIC_REV)
__le32 s_first_ino; // 标准文件的第一个可用inode的索引(非动态为11)
__le16 s_inode_size; // inode结构的大小(非动态为128)
__le16 s_block_group_nr; // 保存此超级块的块组号
__le32 s_feature_compat; // 兼容特性掩码
__le32 s_feature_incompat; // 不兼容特性掩码
__le32 s_feature_ro_compat; // 只读特性掩码
__u8 s_uuid[16]; // 卷ID,应尽可能使每个文件系统的格式唯一
char s_volume_name[16]; // 卷名(只能为ISO-Latin-1字符集,以'\0'结束)
char s_last_mounted[64]; // 最近被安装的目录
__le32 s_algorithm_usage_bitmap; // 文件系统采用的压缩算法
// 仅在EXT2_COMPAT_PREALLOC标志被设置时有效
__u8 s_prealloc_blocks; // 预分配的块数
__u8 s_prealloc_dir_blocks; // 给目录预分配的块数
__u16 s_padding1;
// 仅在EXT3_FEATURE_COMPAT_HAS_JOURNAL标志被设置时有效,用以支持日志
__u8 s_journal_uuid[16]; // 日志超级块的卷ID
__u32 s_journal_inum; // 日志文件的inode数目
__u32 s_journal_dev; // 日志文件的设备数
__u32 s_last_orphan; // 要删除的inode列表的起始位置
__u32 s_hash_seed[4]; // HTREE散列种子
__u8 s_def_hash_version; // 默认使用的散列函数
__u8 s_reserved_char_pad;
__u16 s_reserved_word_pad;
__le32 s_default_mount_opts;
__le32 s_first_meta_bg; // 块组的第一个元块
__u32 s_reserved[190];
};
2、块组描述符
一个块组描述符用以描述一个块组的属性。块组描述符组由若干块组描述符组成,描述了文件系统中所有块组的属性,存放于超级块所在块的下一个块中。一个块组描述符的结构如下:
struct ext2_group_desc
{
__le32 bg_block_bitmap; // 块位图所在的第一个块的块ID
__le32 bg_inode_bitmap; // inode位图所在的第一个块的块ID
__le32 bg_inode_table; // inode表所在的第一个块的块ID
__le16 bg_free_blocks_count; // 块组中未使用的块数
__le16 bg_free_inodes_count; // 块组中未使用的inode数
__le16 bg_used_dirs_count; // 块组分配的目录的inode数
__le16 bg_pad;
__le32 bg_reserved[3];
};
3、块位图与inode位图
块位图和inode位图的每一位分别指出块组中对应的那个块或inode是否被使用。
4inode
inode表用于跟踪定位每个文件,包括位置、大小等(但不包括文件名),一个块组只有一个inode表。一个inode的结构如下:
struct ext2_inode {
__le16 i_mode; // 文件格式和访问权限
__le16 i_uid; // 文件所有者ID的低16位
__le32 i_size; // 文件字节数
__le32 i_atime; // 文件上次被访问的时间
__le32 i_ctime; // 文件创建时间
__le32 i_mtime; // 文件被修改的时间
__le32 i_dtime; // 文件被删除的时间(如果存在则为0)
__le16 i_gid; // 文件所有组ID的低16位
__le16 i_links_count; // 此inode被连接的次数
__le32 i_blocks; // 文件已使用和保留的总块数(以512B为单位)
__le32 i_flags; // 此inode访问数据时ext2的实现方式
union {
struct {
__le32 l_i_reserved1; // 保留
} linux1;
struct {
__le32 h_i_translator; // “翻译者”标签
} hurd1;
struct {
__le32 m_i_reserved1; // 保留
} masix1;
} osd1; // 操作系统相关数据
__le32 i_block[EXT2_N_BLOCKS]; // 定位存储文件的块的数组,前12个为块号,第13个为一级间接块号,第14个为二级间接块号,第15个为三级间接块号
__le32 i_generation; // 用于NFS的文件版本
__le32 i_file_acl; // 包含扩展属性的块号,老版本中为0
__le32 i_dir_acl; // 表示文件的“High Size”,老版本中为0
__le32 i_faddr; // 文件最后一个段的地址
union {
struct {
__u8 l_i_frag; // 段号
__u8 l_i_fsize; // 段大小
__u16 i_pad1;
__le16 l_i_uid_high; // 文件所有者ID的高16位
__le16 l_i_gid_high; // 文件所有组ID的高16位
__u32 l_i_reserved2;
} linux2;
struct {
__u8 h_i_frag; // 段号
__u8 h_i_fsize; // 段大小
__le16 h_i_mode_high;
__le16 h_i_uid_high; // 文件所有者ID的高16位
__le16 h_i_gid_high; // 文件所有组ID的高16位
__le32 h_i_author;
} hurd2;
struct {
__u8 m_i_frag; // 段号
__u8 m_i_fsize; // 段大小
__u16 m_pad1;
__u32 m_i_reserved2[2];
} masix2;
} osd2; // 操作系统相关数据
};

5、数据块
数据块中存放文件的内容,包括目录表、扩展属性、符号链接等。
二、目录结构
在ext2文件系统中,目录是作为文件存储的。根目录总是在inode表的第二项,而其子目录则在根目录文件的内容中定义。目录项在include/linux/ext2_fs.h文件中定义,其结构如下:
struct ext2_dir_entry_2 {
__le32 inode; // 文件入口的inode号,0表示该项未使用
__le16 rec_len; // 目录项长度
__u8 name_len; // 文件名包含的字符数
__u8 file_type; // 文件类型
char name[255]; // 文件名
};
三、文件扩展属性
文件的属性大多数是位于该文件的inode结构中的标准属性,也还包含其他一些扩展属性(于系统中所有的inode相关,通常用于增加额外的功能),在fs/ext2/xattr.h文件中定义。
inode的i_file_acl字段中保存扩展属性的块的块号。属性头部项位于属性块的起始位置,其后为属性入口项,而属性值可以根据属性入口项找到所在位置。
1、属性头部项
struct ext2_xattr_header {
__le32 h_magic; // 标识码,为0xEA020000
__le32 h_refcount; // 属性块被链接的数目
__le32 h_blocks; // 用于扩展属性的块数
__le32 h_hash; // 所有属性的哈希值
__u32 h_reserved[4];
};
2、属性入口项
struct ext2_xattr_entry {
__u8 e_name_len; // 属性名长度
__u8 e_name_index; // 属性名索引
__le16 e_value_offs; // 属性值在值块中的偏移量
__le32 e_value_block; // 保存值的块的块号
__le32 e_value_size; // 属性值长度
__le32 e_hash; // 属性名和值的哈希值
char e_name[0]; // 属性名
};

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/27624/showart_234187.html

/*
*  linux/include/linux/ext2_fs.h
*
* Copyright (C) 1992, 1993, 1994, 1995
* Remy Card (card@masi.ibp.fr)
* Laboratoire MASI - Institut Blaise Pascal
* Universite Pierre et Marie Curie (Paris VI)
*
*  from
*
*  linux/include/linux/minix_fs.h
*
*  Copyright (C) 1991, 1992  Linus Torvalds
*/

#ifndef _LINUX_EXT2_FS_H
#define _LINUX_EXT2_FS_H

#include <linux/types.h>
#include <linux/magic.h>
#include <linux/fs.h>

/*
* The second extended filesystem constants/structures
*/

/*
* Define EXT2FS_DEBUG to produce debug messages
*/
#undef EXT2FS_DEBUG

/*
* Define EXT2_RESERVATION to reserve data blocks for expanding files
*/
#define EXT2_DEFAULT_RESERVE_BLOCKS     8
/*max window size: 1024(direct blocks) + 3([t,d]indirect blocks) */
#define EXT2_MAX_RESERVE_BLOCKS         1027
#define EXT2_RESERVE_WINDOW_NOT_ALLOCATED 0
/*
* The second extended file system version
*/
#define EXT2FS_DATE                "95/08/09"
#define EXT2FS_VERSION                "0.5b"

/*
* Debug code
*/
#ifdef EXT2FS_DEBUG
#        define ext2_debug(f, a...)        { \
                                        printk ("EXT2-fs DEBUG (%s, %d): %s:", \
                                                __FILE__, __LINE__, __func__); \
                                          printk (f, ## a); \
                                        }
#else
#        define ext2_debug(f, a...)        /**/
#endif

/*
* Special inode numbers
*/
#define        EXT2_BAD_INO                 1        /* Bad blocks inode */
#define EXT2_ROOT_INO                 2        /* Root inode */
#define EXT2_BOOT_LOADER_INO         5        /* Boot loader inode */
#define EXT2_UNDEL_DIR_INO         6        /* Undelete directory inode */

/* First non-reserved inode for old ext2 filesystems */
#define EXT2_GOOD_OLD_FIRST_INO        11

/* Assume that user mode programs are passing in an ext2fs superblock, not
* a kernel struct super_block.  This will allow us to call the feature-test
* macros from user land. */
#define EXT2_SB(sb)        (sb)

/*
* Maximal count of links to a file
*/
#define EXT2_LINK_MAX                32000

/*
* Macro-instructions used to manage several block sizes
*/
#define EXT2_MIN_BLOCK_SIZE                1024
#define        EXT2_MAX_BLOCK_SIZE                4096
#define EXT2_MIN_BLOCK_LOG_SIZE                  10
# define EXT2_BLOCK_SIZE(s)                (EXT2_MIN_BLOCK_SIZE << (s)->s_log_block_size)
#define        EXT2_ADDR_PER_BLOCK(s)                (EXT2_BLOCK_SIZE(s) / sizeof (__u32))
# define EXT2_BLOCK_SIZE_BITS(s)        ((s)->s_log_block_size + 10)
#define EXT2_INODE_SIZE(s)        (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
                                 EXT2_GOOD_OLD_INODE_SIZE : \
                                 (s)->s_inode_size)
#define EXT2_FIRST_INO(s)        (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
                                 EXT2_GOOD_OLD_FIRST_INO : \
                                 (s)->s_first_ino)

/*
* Macro-instructions used to manage fragments
*/
#define EXT2_MIN_FRAG_SIZE                1024
#define        EXT2_MAX_FRAG_SIZE                4096
#define EXT2_MIN_FRAG_LOG_SIZE                  10
# define EXT2_FRAG_SIZE(s)                (EXT2_MIN_FRAG_SIZE << (s)->s_log_frag_size)
# define EXT2_FRAGS_PER_BLOCK(s)        (EXT2_BLOCK_SIZE(s) / EXT2_FRAG_SIZE(s))

/*
* Structure of a blocks group descriptor
*/
struct ext2_group_desc
{
        __le32        bg_block_bitmap;                /* Blocks bitmap block */
        __le32        bg_inode_bitmap;                /* Inodes bitmap block */
        __le32        bg_inode_table;                /* Inodes table block */
        __le16        bg_free_blocks_count;        /* Free blocks count */
        __le16        bg_free_inodes_count;        /* Free inodes count */
        __le16        bg_used_dirs_count;        /* Directories count */
        __le16        bg_pad;
        __le32        bg_reserved[3];
};

/*
* Macro-instructions used to manage group descriptors
*/
# define EXT2_BLOCKS_PER_GROUP(s)        ((s)->s_blocks_per_group)
# define EXT2_DESC_PER_BLOCK(s)                (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc))
# define EXT2_INODES_PER_GROUP(s)        ((s)->s_inodes_per_group)

/*
* Constants relative to the data blocks
*/
#define        EXT2_NDIR_BLOCKS                12
#define        EXT2_IND_BLOCK                        EXT2_NDIR_BLOCKS
#define        EXT2_DIND_BLOCK                        (EXT2_IND_BLOCK + 1)
#define        EXT2_TIND_BLOCK                        (EXT2_DIND_BLOCK + 1)
#define        EXT2_N_BLOCKS                        (EXT2_TIND_BLOCK + 1)

/*
* Inode flags (GETFLAGS/SETFLAGS)
*/
#define        EXT2_SECRM_FL                        FS_SECRM_FL        /* Secure deletion */
#define        EXT2_UNRM_FL                        FS_UNRM_FL        /* Undelete */
#define        EXT2_COMPR_FL                        FS_COMPR_FL        /* Compress file */
#define EXT2_SYNC_FL                        FS_SYNC_FL        /* Synchronous updates */
#define EXT2_IMMUTABLE_FL                FS_IMMUTABLE_FL        /* Immutable file */
#define EXT2_APPEND_FL                        FS_APPEND_FL        /* writes to file may only append */
#define EXT2_NODUMP_FL                        FS_NODUMP_FL        /* do not dump file */
#define EXT2_NOATIME_FL                        FS_NOATIME_FL        /* do not update atime */
/* Reserved for compression usage... */
#define EXT2_DIRTY_FL                        FS_DIRTY_FL
#define EXT2_COMPRBLK_FL                FS_COMPRBLK_FL        /* One or more compressed clusters */
#define EXT2_NOCOMP_FL                        FS_NOCOMP_FL        /* Don't compress */
#define EXT2_ECOMPR_FL                        FS_ECOMPR_FL        /* Compression error */
/* End compression flags --- maybe not all used */        
#define EXT2_BTREE_FL                        FS_BTREE_FL        /* btree format dir */
#define EXT2_INDEX_FL                        FS_INDEX_FL        /* hash-indexed directory */
#define EXT2_IMAGIC_FL                        FS_IMAGIC_FL        /* AFS directory */
#define EXT2_JOURNAL_DATA_FL                FS_JOURNAL_DATA_FL /* Reserved for ext3 */
#define EXT2_NOTAIL_FL                        FS_NOTAIL_FL        /* file tail should not be merged */
#define EXT2_DIRSYNC_FL                        FS_DIRSYNC_FL        /* dirsync behaviour (directories only) */
#define EXT2_TOPDIR_FL                        FS_TOPDIR_FL        /* Top of directory hierarchies*/
#define EXT2_RESERVED_FL                FS_RESERVED_FL        /* reserved for ext2 lib */

#define EXT2_FL_USER_VISIBLE                FS_FL_USER_VISIBLE        /* User visible flags */
#define EXT2_FL_USER_MODIFIABLE                FS_FL_USER_MODIFIABLE        /* User modifiable flags */

/* Flags that should be inherited by new inodes from their parent. */
#define EXT2_FL_INHERITED (EXT2_SECRM_FL | EXT2_UNRM_FL | EXT2_COMPR_FL |\
                           EXT2_SYNC_FL | EXT2_IMMUTABLE_FL | EXT2_APPEND_FL |\
                           EXT2_NODUMP_FL | EXT2_NOATIME_FL | EXT2_COMPRBLK_FL|\
                           EXT2_NOCOMP_FL | EXT2_JOURNAL_DATA_FL |\
                           EXT2_NOTAIL_FL | EXT2_DIRSYNC_FL)

/* Flags that are appropriate for regular files (all but dir-specific ones). */
#define EXT2_REG_FLMASK (~(EXT2_DIRSYNC_FL | EXT2_TOPDIR_FL))

/* Flags that are appropriate for non-directories/regular files. */
#define EXT2_OTHER_FLMASK (EXT2_NODUMP_FL | EXT2_NOATIME_FL)

/* Mask out flags that are inappropriate for the given type of inode. */
static __inline__ __u32 ext2_mask_flags(umode_t mode, __u32 flags)
{
        if (S_ISDIR(mode))
                return flags;
        else if (S_ISREG(mode))
                return flags & EXT2_REG_FLMASK;
        else
                return flags & EXT2_OTHER_FLMASK;
}

/*
* ioctl commands
*/
#define        EXT2_IOC_GETFLAGS                FS_IOC_GETFLAGS
#define        EXT2_IOC_SETFLAGS                FS_IOC_SETFLAGS
#define        EXT2_IOC_GETVERSION                FS_IOC_GETVERSION
#define        EXT2_IOC_SETVERSION                FS_IOC_SETVERSION
#define        EXT2_IOC_GETRSVSZ                _IOR('f', 5, long)
#define        EXT2_IOC_SETRSVSZ                _IOW('f', 6, long)

/*
* ioctl commands in 32 bit emulation
*/
#define EXT2_IOC32_GETFLAGS                FS_IOC32_GETFLAGS
#define EXT2_IOC32_SETFLAGS                FS_IOC32_SETFLAGS
#define EXT2_IOC32_GETVERSION                FS_IOC32_GETVERSION
#define EXT2_IOC32_SETVERSION                FS_IOC32_SETVERSION

/*
* Structure of an inode on the disk
*/
struct ext2_inode {
        __le16        i_mode;                /* File mode */
        __le16        i_uid;                /* Low 16 bits of Owner Uid */
        __le32        i_size;                /* Size in bytes */
        __le32        i_atime;        /* Access time */
        __le32        i_ctime;        /* Creation time */
        __le32        i_mtime;        /* Modification time */
        __le32        i_dtime;        /* Deletion Time */
        __le16        i_gid;                /* Low 16 bits of Group Id */
        __le16        i_links_count;        /* Links count */
        __le32        i_blocks;        /* Blocks count */
        __le32        i_flags;        /* File flags */
        union {
                struct {
                        __le32  l_i_reserved1;
                } linux1;
                struct {
                        __le32  h_i_translator;
                } hurd1;
                struct {
                        __le32  m_i_reserved1;
                } masix1;
        } osd1;                                /* OS dependent 1 */
        __le32        i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
        __le32        i_generation;        /* File version (for NFS) */
        __le32        i_file_acl;        /* File ACL */
        __le32        i_dir_acl;        /* Directory ACL */
        __le32        i_faddr;        /* Fragment address */
        union {
                struct {
                        __u8        l_i_frag;        /* Fragment number */
                        __u8        l_i_fsize;        /* Fragment size */
                        __u16        i_pad1;
                        __le16        l_i_uid_high;        /* these 2 fields    */
                        __le16        l_i_gid_high;        /* were reserved2[0] */
                        __u32        l_i_reserved2;
                } linux2;
                struct {
                        __u8        h_i_frag;        /* Fragment number */
                        __u8        h_i_fsize;        /* Fragment size */
                        __le16        h_i_mode_high;
                        __le16        h_i_uid_high;
                        __le16        h_i_gid_high;
                        __le32        h_i_author;
                } hurd2;
                struct {
                        __u8        m_i_frag;        /* Fragment number */
                        __u8        m_i_fsize;        /* Fragment size */
                        __u16        m_pad1;
                        __u32        m_i_reserved2[2];
                } masix2;
        } osd2;                                /* OS dependent 2 */
};

#define i_size_high        i_dir_acl

#if defined(__KERNEL__) || defined(__linux__)
#define i_reserved1        osd1.linux1.l_i_reserved1
#define i_frag                osd2.linux2.l_i_frag
#define i_fsize                osd2.linux2.l_i_fsize
#define i_uid_low        i_uid
#define i_gid_low        i_gid
#define i_uid_high        osd2.linux2.l_i_uid_high
#define i_gid_high        osd2.linux2.l_i_gid_high
#define i_reserved2        osd2.linux2.l_i_reserved2
#endif

#ifdef        __hurd__
#define i_translator        osd1.hurd1.h_i_translator
#define i_frag                osd2.hurd2.h_i_frag
#define i_fsize                osd2.hurd2.h_i_fsize
#define i_uid_high        osd2.hurd2.h_i_uid_high
#define i_gid_high        osd2.hurd2.h_i_gid_high
#define i_author        osd2.hurd2.h_i_author
#endif

#ifdef        __masix__
#define i_reserved1        osd1.masix1.m_i_reserved1
#define i_frag                osd2.masix2.m_i_frag
#define i_fsize                osd2.masix2.m_i_fsize
#define i_reserved2        osd2.masix2.m_i_reserved2
#endif

/*
* File system states
*/
#define        EXT2_VALID_FS                        0x0001        /* Unmounted cleanly */
#define        EXT2_ERROR_FS                        0x0002        /* Errors detected */

/*
* Mount flags
*/
#define EXT2_MOUNT_CHECK                0x000001  /* Do mount-time checks */
#define EXT2_MOUNT_OLDALLOC                0x000002  /* Don't use the new Orlov allocator */
#define EXT2_MOUNT_GRPID                0x000004  /* Create files with directory's group */
#define EXT2_MOUNT_DEBUG                0x000008  /* Some debugging messages */
#define EXT2_MOUNT_ERRORS_CONT                0x000010  /* Continue on errors */
#define EXT2_MOUNT_ERRORS_RO                0x000020  /* Remount fs ro on errors */
#define EXT2_MOUNT_ERRORS_PANIC                0x000040  /* Panic on errors */
#define EXT2_MOUNT_MINIX_DF                0x000080  /* Mimics the Minix statfs */
#define EXT2_MOUNT_NOBH                        0x000100  /* No buffer_heads */
#define EXT2_MOUNT_NO_UID32                0x000200  /* Disable 32-bit UIDs */
#define EXT2_MOUNT_XATTR_USER                0x004000  /* Extended user attributes */
#define EXT2_MOUNT_POSIX_ACL                0x008000  /* POSIX Access Control Lists */
#define EXT2_MOUNT_XIP                        0x010000  /* Execute in place */
#define EXT2_MOUNT_USRQUOTA                0x020000  /* user quota */
#define EXT2_MOUNT_GRPQUOTA                0x040000  /* group quota */
#define EXT2_MOUNT_RESERVATION                0x080000  /* Preallocation */


#define clear_opt(o, opt)                o &= ~EXT2_MOUNT_##opt
#define set_opt(o, opt)                        o |= EXT2_MOUNT_##opt
#define test_opt(sb, opt)                (EXT2_SB(sb)->s_mount_opt & \
                                         EXT2_MOUNT_##opt)
/*
* Maximal mount counts between two filesystem checks
*/
#define EXT2_DFL_MAX_MNT_COUNT                20        /* Allow 20 mounts */
#define EXT2_DFL_CHECKINTERVAL                0        /* Don't use interval check */

/*
* Behaviour when detecting errors
*/
#define EXT2_ERRORS_CONTINUE                1        /* Continue execution */
#define EXT2_ERRORS_RO                        2        /* Remount fs read-only */
#define EXT2_ERRORS_PANIC                3        /* Panic */
#define EXT2_ERRORS_DEFAULT                EXT2_ERRORS_CONTINUE

/*
* Structure of the super block
*/
struct ext2_super_block {
        __le32        s_inodes_count;                /* Inodes count */
        __le32        s_blocks_count;                /* Blocks count */
        __le32        s_r_blocks_count;        /* Reserved blocks count */
        __le32        s_free_blocks_count;        /* Free blocks count */
        __le32        s_free_inodes_count;        /* Free inodes count */
        __le32        s_first_data_block;        /* First Data Block */
        __le32        s_log_block_size;        /* Block size */
        __le32        s_log_frag_size;        /* Fragment size */
        __le32        s_blocks_per_group;        /* # Blocks per group */
        __le32        s_frags_per_group;        /* # Fragments per group */
        __le32        s_inodes_per_group;        /* # Inodes per group */
        __le32        s_mtime;                /* Mount time */
        __le32        s_wtime;                /* Write time */
        __le16        s_mnt_count;                /* Mount count */
        __le16        s_max_mnt_count;        /* Maximal mount count */
        __le16        s_magic;                /* Magic signature */
        __le16        s_state;                /* File system state */
        __le16        s_errors;                /* Behaviour when detecting errors */
        __le16        s_minor_rev_level;         /* minor revision level */
        __le32        s_lastcheck;                /* time of last check */
        __le32        s_checkinterval;        /* max. time between checks */
        __le32        s_creator_os;                /* OS */
        __le32        s_rev_level;                /* Revision level */
        __le16        s_def_resuid;                /* Default uid for reserved blocks */
        __le16        s_def_resgid;                /* Default gid for reserved blocks */
        /*
         * These fields are for EXT2_DYNAMIC_REV superblocks only.
         *
         * Note: the difference between the compatible feature set and
         * the incompatible feature set is that if there is a bit set
         * in the incompatible feature set that the kernel doesn't
         * know about, it should refuse to mount the filesystem.
         * 
         * e2fsck's requirements are more strict; if it doesn't know
         * about a feature in either the compatible or incompatible
         * feature set, it must abort and not try to meddle with
         * things it doesn't understand...
         */
        __le32        s_first_ino;                 /* First non-reserved inode */
        __le16   s_inode_size;                 /* size of inode structure */
        __le16        s_block_group_nr;         /* block group # of this superblock */
        __le32        s_feature_compat;         /* compatible feature set */
        __le32        s_feature_incompat;         /* incompatible feature set */
        __le32        s_feature_ro_compat;         /* readonly-compatible feature set */
        __u8        s_uuid[16];                /* 128-bit uuid for volume */
        char        s_volume_name[16];         /* volume name */
        char        s_last_mounted[64];         /* directory where last mounted */
        __le32        s_algorithm_usage_bitmap; /* For compression */
        /*
         * Performance hints.  Directory preallocation should only
         * happen if the EXT2_COMPAT_PREALLOC flag is on.
         */
        __u8        s_prealloc_blocks;        /* Nr of blocks to try to preallocate*/
        __u8        s_prealloc_dir_blocks;        /* Nr to preallocate for dirs */
        __u16        s_padding1;
        /*
         * Journaling support valid if EXT3_FEATURE_COMPAT_HAS_JOURNAL set.
         */
        __u8        s_journal_uuid[16];        /* uuid of journal superblock */
        __u32        s_journal_inum;                /* inode number of journal file */
        __u32        s_journal_dev;                /* device number of journal file */
        __u32        s_last_orphan;                /* start of list of inodes to delete */
        __u32        s_hash_seed[4];                /* HTREE hash seed */
        __u8        s_def_hash_version;        /* Default hash version to use */
        __u8        s_reserved_char_pad;
        __u16        s_reserved_word_pad;
        __le32        s_default_mount_opts;
        __le32        s_first_meta_bg;         /* First metablock block group */
        __u32        s_reserved[190];        /* Padding to the end of the block */
};

/*
* Codes for operating systems
*/
#define EXT2_OS_LINUX                0
#define EXT2_OS_HURD                1
#define EXT2_OS_MASIX                2
#define EXT2_OS_FREEBSD                3
#define EXT2_OS_LITES                4

/*
* Revision levels
*/
#define EXT2_GOOD_OLD_REV        0        /* The good old (original) format */
#define EXT2_DYNAMIC_REV        1         /* V2 format w/ dynamic inode sizes */

#define EXT2_CURRENT_REV        EXT2_GOOD_OLD_REV
#define EXT2_MAX_SUPP_REV        EXT2_DYNAMIC_REV

#define EXT2_GOOD_OLD_INODE_SIZE 128

/*
* Feature set definitions
*/

#define EXT2_HAS_COMPAT_FEATURE(sb,mask)                        \
        ( EXT2_SB(sb)->s_es->s_feature_compat & cpu_to_le32(mask) )
#define EXT2_HAS_RO_COMPAT_FEATURE(sb,mask)                        \
        ( EXT2_SB(sb)->s_es->s_feature_ro_compat & cpu_to_le32(mask) )
#define EXT2_HAS_INCOMPAT_FEATURE(sb,mask)                        \
        ( EXT2_SB(sb)->s_es->s_feature_incompat & cpu_to_le32(mask) )
#define EXT2_SET_COMPAT_FEATURE(sb,mask)                        \
        EXT2_SB(sb)->s_es->s_feature_compat |= cpu_to_le32(mask)
#define EXT2_SET_RO_COMPAT_FEATURE(sb,mask)                        \
        EXT2_SB(sb)->s_es->s_feature_ro_compat |= cpu_to_le32(mask)
#define EXT2_SET_INCOMPAT_FEATURE(sb,mask)                        \
        EXT2_SB(sb)->s_es->s_feature_incompat |= cpu_to_le32(mask)
#define EXT2_CLEAR_COMPAT_FEATURE(sb,mask)                        \
        EXT2_SB(sb)->s_es->s_feature_compat &= ~cpu_to_le32(mask)
#define EXT2_CLEAR_RO_COMPAT_FEATURE(sb,mask)                        \
        EXT2_SB(sb)->s_es->s_feature_ro_compat &= ~cpu_to_le32(mask)
#define EXT2_CLEAR_INCOMPAT_FEATURE(sb,mask)                        \
        EXT2_SB(sb)->s_es->s_feature_incompat &= ~cpu_to_le32(mask)

#define EXT2_FEATURE_COMPAT_DIR_PREALLOC        0x0001
#define EXT2_FEATURE_COMPAT_IMAGIC_INODES        0x0002
#define EXT3_FEATURE_COMPAT_HAS_JOURNAL                0x0004
#define EXT2_FEATURE_COMPAT_EXT_ATTR                0x0008
#define EXT2_FEATURE_COMPAT_RESIZE_INO                0x0010
#define EXT2_FEATURE_COMPAT_DIR_INDEX                0x0020
#define EXT2_FEATURE_COMPAT_ANY                        0xffffffff

#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER        0x0001
#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE        0x0002
#define EXT2_FEATURE_RO_COMPAT_BTREE_DIR        0x0004
#define EXT2_FEATURE_RO_COMPAT_ANY                0xffffffff

#define EXT2_FEATURE_INCOMPAT_COMPRESSION        0x0001
#define EXT2_FEATURE_INCOMPAT_FILETYPE                0x0002
#define EXT3_FEATURE_INCOMPAT_RECOVER                0x0004
#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV        0x0008
#define EXT2_FEATURE_INCOMPAT_META_BG                0x0010
#define EXT2_FEATURE_INCOMPAT_ANY                0xffffffff

#define EXT2_FEATURE_COMPAT_SUPP        EXT2_FEATURE_COMPAT_EXT_ATTR
#define EXT2_FEATURE_INCOMPAT_SUPP        (EXT2_FEATURE_INCOMPAT_FILETYPE| \
                                         EXT2_FEATURE_INCOMPAT_META_BG)
#define EXT2_FEATURE_RO_COMPAT_SUPP        (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
                                         EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
                                         EXT2_FEATURE_RO_COMPAT_BTREE_DIR)
#define EXT2_FEATURE_RO_COMPAT_UNSUPPORTED        ~EXT2_FEATURE_RO_COMPAT_SUPP
#define EXT2_FEATURE_INCOMPAT_UNSUPPORTED        ~EXT2_FEATURE_INCOMPAT_SUPP

/*
* Default values for user and/or group using reserved blocks
*/
#define        EXT2_DEF_RESUID                0
#define        EXT2_DEF_RESGID                0

/*
* Default mount options
*/
#define EXT2_DEFM_DEBUG                0x0001
#define EXT2_DEFM_BSDGROUPS        0x0002
#define EXT2_DEFM_XATTR_USER        0x0004
#define EXT2_DEFM_ACL                0x0008
#define EXT2_DEFM_UID16                0x0010
    /* Not used by ext2, but reserved for use by ext3 */
#define EXT3_DEFM_JMODE                0x0060 
#define EXT3_DEFM_JMODE_DATA        0x0020
#define EXT3_DEFM_JMODE_ORDERED        0x0040
#define EXT3_DEFM_JMODE_WBACK        0x0060

/*
* Structure of a directory entry
*/
#define EXT2_NAME_LEN 255

struct ext2_dir_entry {
        __le32        inode;                        /* Inode number */
        __le16        rec_len;                /* Directory entry length */
        __le16        name_len;                /* Name length */
        char        name[EXT2_NAME_LEN];        /* File name */
};

/*
* The new version of the directory entry.  Since EXT2 structures are
* stored in intel byte order, and the name_len field could never be
* bigger than 255 chars, it's safe to reclaim the extra byte for the
* file_type field.
*/
struct ext2_dir_entry_2 {
        __le32        inode;                        /* Inode number */
        __le16        rec_len;                /* Directory entry length */
        __u8        name_len;                /* Name length */
        __u8        file_type;
        char        name[EXT2_NAME_LEN];        /* File name */
};

/*
* Ext2 directory file types.  Only the low 3 bits are used.  The
* other bits are reserved for now.
*/
enum {
        EXT2_FT_UNKNOWN                = 0,
        EXT2_FT_REG_FILE        = 1,
        EXT2_FT_DIR                = 2,
        EXT2_FT_CHRDEV                = 3,
        EXT2_FT_BLKDEV                = 4,
        EXT2_FT_FIFO                = 5,
        EXT2_FT_SOCK                = 6,
        EXT2_FT_SYMLINK                = 7,
        EXT2_FT_MAX
};

/*
* EXT2_DIR_PAD defines the directory entries boundaries
*
* NOTE: It must be a multiple of 4
*/
#define EXT2_DIR_PAD                         4
#define EXT2_DIR_ROUND                         (EXT2_DIR_PAD - 1)
#define EXT2_DIR_REC_LEN(name_len)        (((name_len) + 8 + EXT2_DIR_ROUND) & \
                                         ~EXT2_DIR_ROUND)
#define EXT2_MAX_REC_LEN                ((1<<16)-1)

#endif        /* _LINUX_EXT2_FS_H */

分享到:
评论

相关推荐

    linux ext2 文件系统模拟 c语言实现

    1. **EXT2文件系统结构**:EXT2的核心结构由超级块(Superblock)、组描述符表(Group Descriptor Table)、inode表和数据块组成。超级块存储了文件系统的整体信息,如文件系统大小、块大小、空闲块信息等。组描述符...

    ext4文件系统源码

    2. `include/linux/ext4.h`: 定义了EXT4相关的结构体、常量和函数原型,是理解和分析EXT4源码的关键头文件。 3. `block/mmp.c`: 处理多映射点(Multi-Mount Protection,MMP)功能,防止不同挂载点同时修改同一文件...

    linux ext4文件系统分析

    Linux ext4文件系统是Linux操作系统中使用非常广泛的文件系统类型之一,相较于早期的ext3文件系统,在性能和扩展性方面有了显著的提升。ext4文件系统的诞生解决了存储容量增长带来的挑战,同时优化了文件系统结构,...

    用C实现的带缓冲池的虚拟Ext2文件系统

    Ext2文件系统的主要组成部分包括超级块(Superblock)、inode表、块组描述符、目录项等。这个项目的核心就是模拟这些组件,并通过C语言实现它们的功能。 1. **超级块**: 超级块存储了文件系统的整体信息,如文件...

    文件系统-文件系统

    - **结构体**:例如,`inode`结构体是ext2文件系统中非常关键的数据结构,它存储了关于文件的各种信息,如文件的唯一标识符(ino),文件大小(size),访问权限(mode),用户ID(uid),组ID(gid)等。...

    Linux文件系统.pdf

    Linux支持多种文件系统类型,如EXT2、EXT3、EXT4、XFS、Btrfs、FAT、NTFS等。EXT4是目前最常用的一种,它在EXT2的基础上进行了优化,提供了更大的文件系统大小、更快的性能和更好的错误恢复能力。EXT4支持大文件,且...

    linux文件系统分析与研究

    超级块是Ext2文件系统的关键组成部分之一,它记录了文件系统的布局信息,如块大小、I节点总数、每组内的I节点数量、空闲块和I节点的数量等。这些信息对于文件系统的管理和操作至关重要。 超级块的结构体`struct ext...

    从文件 IO看 Linux 的虚拟文件系统

    Linux 支持多种不同的文件系统,例如 ext2、ext3、ext4、vfat 等,并且能够在这些不同的文件系统之间无缝切换和操作文件。这一切的背后,得益于一个重要的组成部分——虚拟文件系统 (VFS)。 虚拟文件系统是 Linux ...

    L6 Linux文件系统1

    EXT2的目录项结构定义了一个名为`ext2_dir_entry_2`的结构体,其中包含了文件的inode号、名称长度、类型等信息。 在EXT2中,文件类型有多种,包括普通文件、目录文件、字符设备文件和块设备文件。普通文件可以包含...

    linux文件系统之路径查找与文件系统的挂载.pdf

    Linux 文件系统是操作系统的核心组成部分,它负责组织、存储和检索数据。在Linux中,文件系统不仅包括普通文件,还涵盖目录、符号链接等其他类型的文件对象。本文将深入探讨Linux中的路径查找机制以及文件系统的挂载...

    Linux 文件系统 介绍

    VFS的重要数据结构包括文件描述符、文件结构体、超级块、i节点等,它们共同维护了文件系统的状态和文件的元信息。 文件系统的注册与安装是Linux中添加新文件系统的过程。例如,ext2和ext3是两种经典的Linux文件系统...

    Linux系统编程--文件系统1

    在 EXT2 文件系统中,磁盘分区被划分成多个块组(Block Group),每个块组都由以下部分组成: 1. 超级块(Super Block):描述整个分区的文件系统信息,例如块大小、文件系统版本号、上次 mount 的时间等等。 2. ...

    操作系统课程设计-linux下的二级文件系统.pdf

    2. **VFS结构**:VFS提供了一套通用的文件系统接口,包括文件描述符、文件结构体、超级块、i节点等概念。文件描述符是进程对文件的抽象,而文件结构体存储了文件的各种状态信息。超级块是每个文件系统特有的,记录了...

    基于Linux的模拟文件系统管理的设计与实现

    Linux中常用的文件系统有EXT2、EXT3、EXT4、XFS、Btrfs等,它们都有各自的数据块分配策略。模拟文件系统可以简化这一过程,但基本原理是相同的:分配空间用于存储文件内容,并维护数据块与文件的映射关系。 接下来...

    从内核文件系统看文件读写过程.docx

    ### 从内核文件系统视角探究文件读写过程 #### 一、系统调用机制及其在文件操作中的应用 ...无论是哪种类型的文件系统(如EXT3/4、FAT、NTFS等),都能够通过VFS进行无缝对接,实现了文件系统的高效管理和便捷访问。

    文件管理系统

    在Linux和Unix系统中,常见的文件系统包括EXT2、EXT3、EXT4以及XFS等。 C++作为一种通用的编程语言,提供了标准库来支持文件操作。在这个项目中,开发者可能使用了`fstream`库,它包含了`ifstream`(输入文件流)和...

    vfs.rar_VFS_linux vfs_linux 文件系统_vfs.c_vfs文件系统

    Linux的虚拟文件系统(Virtual File System,简称VFS)是操作系统的核心组成部分,它为不同的文件系统提供了一个统一的接口,使得Linux可以支持多种文件系统,如EXT4、XFS、FAT32、NTFS等。VFS允许应用程序在不关心...

    3170103456-应承峻-实验41

    首先,分析ext2文件系统的源代码,了解其组成部分,例如fs/ext2目录下的多个源代码文件。然后将这些文件复制到新创建的myext2目录中。接下来,需要对源代码进行适当的修改,包括更改编译时的文件名、结构体、函数名...

    linux虚拟文件系统的研究与应用.pdf

    Linux虚拟文件系统(VFS,Virtual File System)是Linux内核中的一个重要组成部分,它为上层应用程序提供了一个统一的接口,使得不同的文件系统能够透明地交互。Linux VFS的设计目标是独立于具体的物理存储设备,...

Global site tag (gtag.js) - Google Analytics