⑴ [讨论]关于使用EXT2,EXT4文件系统,为什么没有用yaffs2
9# hanhan624624 帮顶。也有这个困惑,为什么有的nand设备还能直接用ext4. 期待大牛的回答。
⑵ ext2和 fat32哪种文件系统性能好
。。。。。FAT32是Windows系统硬盘一种分区格式,Ext2是linux系统硬盘一种分区格式!都不是同一个系统的,如何比较?
⑶ 分区格式 Fat32,NTFS,EXT2,EXT3 有什么区别
从目前流行的操作系统来看,常用的分区格式有:FAT16、FAT32、NTFS和Ext2。 FAT16:是MS-DOS和最早期的WINDOWS 95操作系统中使用的硬盘分区格式,采用16位的文 件分配表,是目前获得操作系统支持最多的一种磁盘分区格式,几乎所有的操作系统都支持这种分区格式。但它只支持2GB的磁盘容量而且磁盘利用效率低。 FAT32:采用32位的文件分配表,突破了2GB的限制。与FAT16相比,极大地减少了磁盘的 浪费,提高了磁盘利用率。缺点是运行速度比采用FAT16格式分区的磁盘要慢,而且DOS和的WINDOWS 95不支持这种分区格式。 NTFS:优点是安全性、稳定性非常出色,使用中不易产生文件碎片。并且能对用户的操作进 行记录,通过对用户权限进行严格限制,使每个用户只能按照系统赋予的权限进行操作,充分保护了系统与数据的安全。WINDOWS 2000、WINDOWS NT以及WINDOWS XP都支持这种分区格式。 Ext2/Ext3:是Linux中使用最多的一种文件系统,专门为Linux设计,拥有最快的速度和最 小的cpu 占有用率。Ext2既可以用于标准块设备(如硬盘),也被应用在软盘等移动存储设备上。Linux的磁盘分区格式与其它操作系统完全不同,其C、D、E、F等分区的意义也和WINDOWS操作系统下不一样,使用Linux操作系统后,死机的机会大大减少,但是目前支持这一分区格式的操作系统只有Linux。 这是我在网上帮你找的希望对你有用 要详细的你可以在网络搜一下
⑷ linux的ext3文件系统与ext2文件系统有何不同
Linux下的Ext2文件系统,是 GNU/Linux 系统中标准的文件系统,其特点为存取文件的性能极好,对于中小型的文件更显示出优势,这主要得利于其簇快取层的优良设计。其单一文件大小与文件系统本身的容量上限与文件系统本身的簇大小有关,在一般常见的 x86 电脑系统中,簇最大为 4KB, 则单一文件大小上限为 2048GB, 而文件系统的容量上限为 16384GB。但由于目前核心 2.4 所能使用的单一分割区最大只有 2048GB,实际上能使用的文件系统容量最多也只有 2048GB。至于Ext3文件系统,它属于一种日志文件系统,是对ext2系统的扩展。它兼容ext2,并且从ext2转换成ext3并不复杂。用来支持ext3的包都被包含在LFS基本系统里面了,所以你不用再安装其他的程序。当编译内核的时候,确认你编译了ext3的支持。如果你想在根分区使用ext3系统,你就需要把 ext3支持编译到内核的内嵌支持。如果不是在根分区使用,编译成模块就可以了。编辑/etc/fstab。把每一个你想转换成ext3的分区的条目改成类似的内容:/dev/hdXX /mnt_point ext3 defaults 1 0在上面的一行中,将 /dev/hdXX 替换成分区,例如 /dev/hda2,把 /mnt_point 替换成你想挂载的位置,例如:/home。最后的 0 保证在启动的时候这个分区不会被chechfs脚本进行一致性检查。若想这个分区肯定可以被挂载然后又不太肯定内核支持ext3的话,可以把ext3换成auto。启动每一个你在 /etc/fstab中改为ext3的分区的日志,运行:tune2fs -j /dev/hdXX 重新挂载分区或者重起系统(如果你重新编译了内核)。而且Ext3文件系统也是在保有目前 ext2 的格式之下再加上日志功能。目前它离实用阶段还有一段距离,ext3是一种日志式文件系统。日志式文件系统的优越性在于:由于文件系统都有快取层参与运作,如不使用时必须将文件系统卸下,以便将快取层的资料写回磁盘中。因此每当系统要关机时,必须将其所有的文件系统全部shutdown后才能进行关机。如果在文件系统尚未shutdown前就关机 (如停电) 时,下次重开机后会造成文件系统的资料不一致,故这时必须做文件系统的重整工作,将不一致与错误的地方修复。然而,此一重整的工作是相当耗时的,特别是容量大的文件系统,而且也不能百分之百保证所有的资料都不会流失。为了克服此问题,使用所谓‘日志式文件系统 (Journal File System) ’。此类文件系统最大的特色是,它会将整个磁盘的写入动作完整记录在磁盘的某个区域上,以便有需要时可以回朔追踪。由于资料的写入动作包含许多的细节,像是改变文件标头资料、搜寻磁盘可写入空间、一个个写入资料区段等等,每一个细节进行到一半若被中断,就会造成文件系统的不一致,因而需要重整。然而,在日志式文件系统中,由于详细纪录了每个细节,故当在某个过程中被中断时,系统可以根据这些记录直接回朔并重整被中断的部分,而不必花时间去检查其他的部分,故重整的工作速度相当快,几乎不需要花时间。另外Linux中还有一种专门用于交换分区的swap文件系统,Linux使用整个分区来作为交换空间,而不象Windows使用交换文件。一般这个SWAP格式的交换分区是主内存的2倍。
⑸ linux中fat ext2文件系统的区别
FAT有FAT16和FAT32就磁盘利用率来讲,我觉得ext2更加好。安全性方面来讲,因为都不是日志型的系统格式,所以都有所欠缺,可以考虑利用他们的后续版本,FAT32后是NTFS,EXT2是EXT3,ReiserFS等现在大部分的操作系统都可以认出FAT32,除了一些比较老的系统援引自:http://www.xbnet.cn/xbnet_bbs/dispbbs.asp?boardID=23&ID=231&page=2ext2文件系统支持标准Unix文件类型,例如普通文件、目录文件、特别文件和符号链接等。除了标准的Unix功能外,ext2文件系统还支持在一般Unix文件系统中没有的高级功能,如设置文件属性、支持数据更新时同步写入磁盘的功能、允许系统管理员在创建文件系统时选择逻辑数据块的大小、实现快速符号链接,以及提供两种定期强迫进行文件系统检查的工具等。与其它文件系统一样,ext2文件系统中的文件信息都保存在数据块中。对同一个ext2文件系统而言,所有数据块的大小都是一样的,例如1024字节。但是,不同的ext2文件系统中数据块的大小可以不同。援引自:http://www.xici.net/b670440/d40907086.htm FAT32是FAT16文件系统的派生,比 FAT16 支持更小的簇和更大的分区,这就使得 FAT32 分区的空间分配更有效率。FAT32主要应用于Windows 98及后续Windows系统(实际从未正式发布的Windows 97,即OSR2就开始支持了),它可以增强磁盘性能并增加可用磁盘空间,同时也支持长文件名。
⑹ win10下ext2文件系统怎么查看
可以使用df -Th [[email protected] ~]# df -Th 参数用处如下: -T 显示文件系统类型。 -h:以容易理解的格式输出文件系统大小,例如124KB、345MB、46GB。
⑺ 什么是ext2文件系统
ext2是LINUX系统中的一种文件系统。XP中使用的是NTFS和FAT32文件系统。
⑻ Ext2的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字符集,以’’结束)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是否被使用。4、inode表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]; // 属性名};
⑼ 文件系统有多种类型,如:ext2 早期linux中常用的文件系统;ext3 ext2的升级版
linux文件系统分类:ext2:早期linux中常用的文件系统ext3:ext2的升级版,带日志功能ext4:ext3的升级版,大版幅度改动RAMFS:内存文权件系统,速度很快NFS:网络文件系统,由SUN发明,主要用于远程文件共享MS-DOS:MS-DOS文件系统VFAT:Windows95/98操作系统采用的文件系统FAT:WindowsXP操作系统采用的文件系统NTFS:WindowsNT/XP操作系统采用的文件系统HPFS:OS/2操作系统采用的文件系统PROC:虚拟的进程文件系统ISO9660:大部分光盘所采用的文件系统ufsSun:OS所采用的文件系统NCPFS:Novell服务器所采用的文件系统SMBFS:Samba的共享文件系统XFS:由SGI开发的先进的日志文件系统,支持超大容量文件JFS:IBM的AIX使用的日志文件系统ReiserFS:基于平衡树结构的文件系统udf:可擦写的数据光盘文件系统
⑽ ext2文件系统的本科毕业论文
本文主要讲述 Linux 上比较流行的 ext2 文件系统在硬盘分区上的详细布局情况。Ext2 文件系统加上日志支持的下一个版本是 ext3 文件系统,它和 ext2 文件系统在硬盘布局上是一样的,其差别仅仅是 ext3 文件系统在硬盘上多出了一个特殊的 inode(可以理解为一个特殊文件),用来记录文件系统的日志,也即所谓的 journal。由于本文并不讨论日志文件,所以本文的内容对于 ext2 和 ext3 都是适用的。前言本文的资料来源是 Linux 内核中 ext3 文件系统的源代码。为了便于读者查阅源代码,本文中一些关键的技术词汇都使用了内核源代码中所使用的英语单词,而没有使用相应的中文翻译。(这种方法是否恰当,还请读者朋友们指教。)粗略的描述对于 ext2 文件系统来说,硬盘分区首先被划分为一个个的 block,一个 ext2 文件系统上的每个 block 都是一样大小的,但是对于不同的 ext2 文件系统,block 的大小可以有区别。典型的 block 大小是 1024 bytes 或者 4096 bytes。这个大小在创建 ext2 文件系统的时候被决定,它可以由系统管理员指定,也可以由文件系统的创建程序根据硬盘分区的大小,自动选择一个较合理的值。这些 blocks 被聚在一起分成几个大的 block group。每个 block group 中有多少个 block 是固定的。每个 block group 都相对应一个 group descriptor,这些 group descriptor 被聚在一起放在硬盘分区的开头部分,跟在 super block 的后面。所谓 super block,我们下面还要讲到。在这个 descriptor 当中有几个重要的 block 指针。我们这里所说的 block 指针,就是指硬盘分区上的 block 号数,比如,指针的值为 0,我们就说它是指向硬盘分区上的 block 0;指针的值为 1023,我们就说它是指向硬盘分区上的 block 1023。我们注意到,一个硬盘分区上的 block 计数是从 0 开始的,并且这个计数对于这个硬盘分区来说是全局性质的。在 block group 的 group descriptor 中,其中有一个 block 指针指向这个 block group 的 block bitmap,block bitmap 中的每个 bit 表示一个 block,如果该 bit 为 0,表示该 block 中有数据,如果 bit 为 1,则表示该 block 是空闲的。注意,这个 block bitmap 本身也正好只有一个 block 那么大小。假设 block 大小为 S bytes,那么 block bitmap 当中只能记载 8*S 个 block 的情况(因为一个 byte 等于 8 个 bits,而一个 bit 对应一个 block)。这也就是说,一个 block group 最多只能有 8*S*S bytes 这么大。在 block group 的 group descriptor 中另有一个 block 指针指向 inode bitmap,这个 bitmap 同样也是正好有一个 block 那么大,里面的每一个 bit 相对应一个 inode。硬盘上的一个 inode 大体上相对应于文件系统上的一个文件或者目录。关于 inode,我们下面还要进一步讲到。在 block group 的 descriptor 中另一个重要的 block 指针,是指向所谓的 inode table。这个 inode table 就不止一个 block 那么大了。这个 inode table 就是这个 block group 中所聚集到的全部 inode 放在一起形成的。一个 inode 当中记载的最关键的信息,是这个 inode 中的用户数据存放在什么地方。我们在前面提到,一个 inode 大体上相对应于文件系统中的一个文件,那么用户文件的内容存放在什么地方,这就是一个 inode 要回答的问题。一个 inode 通过提供一系列的 block 指针,来回答这个问题。这些 block 指针指向的 block,里面就存放了用户文件的内容。2.1 回顾现在我们回顾一下。硬盘分区首先被分为好多个 block。这些 block 聚在一起,被分成几组,也就是 block group。每个 block group 都有一个 group descriptor。所有这些 descriptor 被聚在一起,放在硬盘分区的开头部分,跟在 super block 的后面。从 group descriptor 我们可以通过 block 指针,找到这个 block group 的 inode table 和 block bitmap 等等。从 inode table 里面,我们就可以看到一个个的 inode 了。从一个 inode,我们通过它里面的 block 指针,就可以进而找到存放用户数据的那些 block。我们还要提一下,block 指针不是可以到处乱指的。一个 block group 的 block bitmap 和 inode bitmap 以及 inode table,都依次存放在这个 block group 的开头部分,而那些存放用户数据的 block 就紧跟在它们的后面。一个 block group 结束后,另一个 block group 又跟着开始。3.1 Super Block所谓 ext2 文件系统的 super block,就是硬盘分区开头(开头的第一个 byte 是 byte 0)从 byte 1024 开始往后的一部分数据。由于 block size 最小是 1024 bytes,所以 super block 可能是在 block 1 中(此时 block 的大小正好是 1024 bytes),也可能是在 block 0 中。硬盘分区上 ext3 文件系统的 super block 的详细情况如下。其中 __u32 是表示 unsigned 不带符号的 32 bits 的数据类型,其余类推。这是 Linux 内核中所用到的数据类型,如果是开发用户空间(user-space)的程序,可以根据具体计算机平台的情况,用 unsigned long 等等来代替。下面列表中关于 fragments 的部分可以忽略,Linux 上的 ext3 文件系统并没有实现 fragments 这个特性。另外要注意,ext3 文件系统在硬盘分区上的数据是按照 Intel 的 Little-endian 格式存放的,如果是在 PC 以外的平台上开发 ext3 相关的程序,要特别注意这一点。如果只是在 PC 上做开发,倒不用特别注意。struct ext3_super_block {/*00*/ __u32 s_inodes_count; /* inodes 计数 */__u32 s_blocks_count; /* blocks 计数 */__u32 s_r_blocks_count; /* 保留的 blocks 计数 */__u32 s_free_blocks_count; /* 空闲的 blocks 计数 *//*10*/ __u32 s_free_inodes_count; /* 空闲的 inodes 计数 */__u32 s_first_data_block; /* 第一个数据 block */__u32 s_log_block_size; /* block 的大小 */__s32 s_log_frag_size; /* 可以忽略 *//*20*/ __u32 s_blocks_per_group; /* 每 block group 的 block 数量 */__u32 s_frags_per_group; /* 可以忽略 */__u32 s_inodes_per_group; /* 每 block group 的 inode 数量 */__u32 s_mtime; /* Mount time *//*30*/ __u32 s_wtime; /* Write time */__u16 s_mnt_count; /* Mount count */__s16 s_max_mnt_count; /* Maximal mount count */__u16 s_magic; /* Magic 签名 */__u16 s_state; /* File system state */__u16 s_errors; /* Behaviour when detecting errors */__u16 s_minor_rev_level; /* minor revision level *//*40*/ __u32 s_lastcheck; /* time of last check */__u32 s_checkinterval; /* max. time between checks */__u32 s_creator_os; /* 可以忽略 */__u32 s_rev_level; /* Revision level *//*50*/ __u16 s_def_resuid; /* Default uid for reserved blocks */__u16 s_def_resgid; /* Default gid for reserved blocks */__u32 s_first_ino; /* First non-reserved inode */__u16 s_inode_size; /* size of inode structure */__u16 s_block_group_nr; /* block group # of this superblock */__u32 s_feature_compat; /* compatible feature set *//*60*/ __u32 s_feature_incompat; /* incompatible feature set */__u32 s_feature_ro_compat; /* readonly-compatible feature set *//*68*/ __u8 s_uuid[16]; /* 128-bit uuid for volume *//*78*/ char s_volume_name[16]; /* volume name *//*88*/ char s_last_mounted[64]; /* directory where last mounted *//*C8*/ __u32 s_algorithm_usage_bitmap; /* 可以忽略 */__u8 s_prealloc_blocks; /* 可以忽略 */__u8 s_prealloc_dir_blocks; /* 可以忽略 */__u16 s_padding1; /* 可以忽略 *//*D0*/ __u8 s_journal_uuid[16]; /* uuid of journal superblock *//*E0*/ __u32 s_journal_inum; /* 日志文件的 inode 号数 */__u32 s_journal_dev; /* 日志文件的设备号 */__u32 s_last_orphan; /* start of list of inodes to delete *//*EC*/ __u32 s_reserved[197]; /* 可以忽略 */};我们可以看到,super block 一共有 1024 bytes 那么大。在 super block 中,我们第一个要关心的字段是 magic 签名,对于 ext2 和 ext3 文件系统来说,这个字段的值应该正好等于 0xEF53。如果不等的话,那么这个硬盘分区上肯定不是一个正常的 ext2 或 ext3 文件系统。从这里,我们也可以估计到,ext2 和 ext3 的兼容性一定是很强的,不然的话,Linux 内核的开发者应该会为 ext3 文件系统另选一个 magic 签名才对。在 super block 中另一个重要的字段是 s_log_block_size。从这个字段,我们可以得出真正的 block 的大小。我们把真正 block 的大小记作 B,B = 1 << (s_log_block_size + 10),单位是 bytes。举例来说,如果这个字段是 0,那么 block 的大小就是 1024 bytes,这正好就是最小的 block 大小;如果这个字段是 2,那么 block 大小就是 4096 bytes。从这里我们就得到了 block 的大小这一非常重要的数据。3.2 Group Descriptors我们继续往下,看跟在 super block 后面的一堆 group descriptors。首先注意到 super block 是从 byte 1024 开始,一共有 1024 bytes 那么大。而 group descriptors 是从 super block 后面的第一个 block 开始。也就是说,如果 super block 是在 block 0,那么 group descriptors 就是从 block 1 开始;如果 super block 是在 block 1,那么 group descriptors 就是从 block 2 开始。因为 super block 一共只有 1024 bytes 那么大,所以不会超出一个 block 的边界。如果一个 block 正好是 1024 bytes 那么大的话,我们看到 group descriptors 就是紧跟在 super block 后面的了,没有留一点空隙。而如果一个 block 是 4096 bytes 那么大的话,那么在 group descriptors(从 byte 4096 开始)和 super block 的结尾之间,就有一定的空隙(4096 – 2048 bytes)。那么硬盘分区上一共有多少个 block group,或者说一共有多少个 group descriptors,这我们要在 super block 中找答案。super block 中的 s_blocks_count 记录了硬盘分区上的 block 的总数,而 s_blocks_per_group 记录了每个 group 中有多少个 block。显然,文件系统上的 block groups 数量,我们把它记作 G,G = (s_blocks_count – s_first_data_block – 1) / s_blocks_per_group + 1。为什么要减去 s_first_data_block,因为 s_blocks_count 是硬盘分区上全部的 block 的数量,而在 s_first_data_block 之前的 block 是不归 block group 管的,所以当然要减去。最后为什么又要加一,这是因为尾巴上可能多出来一些 block,这些 block 我们要把它划在一个相对较小的 group 里面。注意,硬盘分区上的所有这些 group descriptors 要能塞在一个 block 里面。也就是说 groups_count * descriptor_size 必须小于等于 block_size。知道了硬盘分区上一共有多少个 block group,我们就可以把这么多个 group descriptors 读出来了。先来看看 group descriptor 是什么样子的。struct ext3_group_desc{__u32 bg_block_bitmap; /* block 指针指向 block bitmap */__u32 bg_inode_bitmap; /* block 指针指向 inode bitmap */__u32 bg_inode_table; /* block 指针指向 inodes table */__u16 bg_free_blocks_count; /* 空闲的 blocks 计数 */__u16 bg_free_inodes_count; /* 空闲的 inodes 计数 */__u16 bg_used_dirs_count; /* 目录计数 */__u16 bg_pad; /* 可以忽略 */__u32 bg_reserved[3]; /* 可以忽略 */};每个 group descriptor 是 32 bytes 那么大。从上面,我们看到了三个关键的 block 指针,这三个关键的 block 指针,我们已经在前面都提到过了。3.3 Inode前面都准备好了以后,我们现在终于可以开始读取文件了。首先要读的,当然是文件系统的根目录。注意,这里所谓的根目录,是相对于这一个文件系统或者说硬盘分区而言的,它并不一定是整个 Linux 操作系统上的根目录。这里的这个 root 目录存放在一个固定的 inode 中,这就是文件系统上的 inode 2。需要提到 inode 计数同 block 计数一样,也是全局性质的。这里需要特别注意的是,inode 计数是从 1 开始的,而前面我们提到过 block 计数是从 0 开始,这个不同在开发程序的时候要特别留心。(这一奇怪的 inode 计数方法,曾经让本文作者大伤脑筋。)那么,我们先来看一下得到一个 inode 号数以后,怎样读取这个 inode 中的用户数据。在 super block 中有一个字段 s_inodes_per_group 记载了每个 block group 中有多少个 inode。用我们得到的 inode 号数除以 s_inodes_per_group,我们就知道了我们要的这个 inode 是在哪一个 block group 里面,这个除法的余数也告诉我们,我们要的这个 inode 是这个 block group 里面的第几个 inode;然后,我们可以先找到这个 block group 的 group descriptor,从这个 descriptor,我们找到这个 group 的 inode table,再从 inode table 找到我们要的第几个 inode,再以后,我们就可以开始读取 inode 中的用户数据了。这个公式是这样的:block_group = (ino – 1) / s_inodes_per_group。这里 ino 就是我们的 inode 号数。而 offset = (ino – 1) % s_inodes_per_group,这个 offset 就指出了我们要的 inode 是这个 block group 里面的第几个 inode。找到这个 inode 之后,我们来具体的看看 inode 是什么样的。struct ext3_inode {__u16 i_mode; /* File mode */__u16 i_uid; /* Low 16 bits of Owner Uid */__u32 i_size; /* 文件大小,单位是 byte */__u32 i_atime; /* Access time */__u32 i_ctime; /* Creation time */__u32 i_mtime; /* Modification time */__u32 i_dtime; /* Deletion Time */__u16 i_gid; /* Low 16 bits of Group Id */__u16 i_links_count; /* Links count */__u32 i_blocks; /* blocks 计数 */__u32 i_flags; /* File flags */__u32 l_i_reserved1; /* 可以忽略 */__u32 i_block[EXT3_N_BLOCKS]; /* 一组 block 指针 */__u32 i_generation; /* 可以忽略 */__u32 i_file_acl; /* 可以忽略 */__u32 i_dir_acl; /* 可以忽略 */__u32 i_faddr; /* 可以忽略 */__u8 l_i_frag; /* 可以忽略 */__u8 l_i_fsize; /* 可以忽略 */__u16 i_pad1; /* 可以忽略 */__u16 l_i_uid_high; /* 可以忽略 */__u16 l_i_gid_high; /* 可以忽略 */__u32 l_i_reserved2; /* 可以忽略 */};我们看到在 inode 里面可以存放 EXT3_N_BLOCKS(= 15)这么多个 block 指针。用户数据就从这些 block 里面获得。15 个 blocks 不一定放得下全部的用户数据,在这里 ext3 文件系统采取了一种分层的结构。这组 15 个 block 指针的前 12 个是所谓的 direct blocks,里面直接存放的就是用户数据。第 13 个 block,也就是所谓的 indirect block,里面存放的全部是 block 指针,这些 block 指针指向的 block 才被用来存放用户数据。第 14 个 block 是所谓的 double indirect block,里面存放的全是 block 指针,这些 block 指针指向的 block 也被全部用来存放 block 指针,而这些 block 指针指向的 block,才被用来存放用户数据。第 15 个 block 是所谓的 triple indirect block,比上面说的 double indirect block 有多了一层 block 指针。作为练习,读者可以计算一下,这样的分层结构可以使一个 inode 中最多存放多少字节的用户数据。(计算所需的信息是否已经足够?还缺少哪一个关键数据?)一个 inode 里面实际有多少个 block,这是由 inode 字段 i_size 再通过计算得到的。i_size 记录的是文件或者目录的实际大小,用它的值除以 block 的大小,就可以得出这个 inode 一共占有几个 block。注意上面的 i_blocks 字段,粗心的读者可能会以为是这一字段记录了一个 inode 中实际用到多少个 block,其实不是的。3.4 文件系统的目录结构现在我们已经可以读取 inode 的内容了,再往后,我们将要读取文件系统上文件和目录的内容。读取文件的内容,只要把相应的 inode 的内容全部读出来就行了;而目录只是一种固定格式的文件,这个文件按照固定的格式记录了目录中有哪些文件,以及它们的文件名,和 inode 号数等等。struct ext3_dir_entry_2 {__u32 inode; /* Inode 号数 */__u16 rec_len; /* Directory entry length */__u8 name_len; /* Name length */__u8 file_type;char name[EXT3_NAME_LEN]; /* File name */};上面用到的 EXT3_NAME_LEN 是 255。注意,在硬盘分区上的 dir entry 不是固定长度的,每个 dir entry 的长度由上面的 rec_len 字段记录。
未经允许不得转载:山九号 » ext2文件系统|什么是ext2文件系统