第五周学习笔记

第11章 EXT2文件系统

摘要

  • EXT2文件系统在Linux中的历史地位以及EXT3/EXT4文件系统的当前状况;
  • 用编程示例展示了各种EXT2数据结构以及如何遍历EXT2文件系统树;
  • 实现支持Linux内核中所有文件操作的EXT2文件系统;展示了如何通过虚拟磁盘的 mountroot来构建基本文件系统;
  • 将文件系统的实现划分为3个级别,级别1扩展了基本文件系统,以实现文件系统树,级别2实现了文件内容的读/写操作,级别3实现了文件系统的挂载/装载和文件保护;
  • 描述了各个级别文件系统函数的算法,并通过编程示例演示了它们的实现过程;

EXT2文件系统

EXT2即第二代扩展文件系统(英语:second extended filesystem,缩写为 EXT2)

EXT2文件系统数据结构

通过mkfs创建虚拟磁盘

dd if=/dev/zero of=vdisk bs=1024 count=1440
mke2fs vdisk 1440

虚拟磁盘布局

Block#0 是引导块,文件系统不会使用它,它用于容纳从磁盘引导操作系统的引导程序

超级块
Block#1 是超级块,用于容纳关于整个文件系统的信息

块组描述符

Block#2 是块组描述符,EXT2将磁盘块分成几个组,每组有8192个块,每组用一个块组描述符结构体描述

块和索引节点位图

Block#8 是块位图,用于表示某种项的位序列,例如磁盘块或索引节点,位图用于分配和回收项。

Block#9 是索引节点位图,索引节点用于代表一个文件的数据结构

索引节点

Block#10 是索引(开始)节点块,索引节点大小用于平均分割块大小,所以每个索引节点块都包含整数个索引节点。

i_mode为U16或2字符无符号整数

i_block[15]数组包含指向文件磁盘的指针,这些磁盘块有:

  • 直接块:iblock[0]至i_block[11],指向直接磁盘块。
  • 间接块:iblock[12]指向一个包含256个块编号(对于1KBBLKSIZE)的磁盘块,每个块编号指向一个磁盘块。
  • 双重间接块:iblock[13]指向一个指向256个块的块,每个块指向256个磁盘块。
  • 三重间接块:iblock[14]是三重间接块。对于“小型”EXT2文件系统,可以忽略它。

数据块

是紧跟在索引节点块后面的文件存储块

目录条目

包含dir_entry结构()一种可扩充结构,即

struct ext2_dir_entry_2{
  u32 inode;
  u16 rec_len;
  u8  name_len;
  u8  file_type;
  char name[EXT2_NAME_LEN];
};
/*********** superblock.c program ************/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/io.h>
#include <ext2fs/ext2_fs.h>
// typedef u8, ul6, u32 SUPER for convenience typedef typedef typedef
typedef unsigned char u8;
typedef unsigned short ul6;
typedef unsigned int u32;
typedef struct ext2_super_block SUPER;
SUPER *sp;
char buf[1024];
int fd, blksize, inodesize;
int print(char *s, u32 x)
{
    printf("%-30s = %8d\n", s, x);
}
int super(char *device)
{
    fd = open(device, O_RDONLY);
    if (fd < 0) 
    {
        printf("open %s failed\n", device); 
        exit(1);
    }
    lseek(fd, (long)1024*1, 0);	// block 1 or offset 1024
    read(fd, buf, 1024);
    sp = (SUPER *)buf;	// as a super block structure
    // check for EXT2 FS magic number
    printf("%-30s = %8x ", "s_magic", sp->s_magic);
    if (sp->s_magic != 0xEF53)
    {
        printf("NOT an EXT2 FS\n"); exit(2);
    }
    printf("EXT2 FS OK\n"); 
    print("s_inodes_count",  sp->s_inodes_count);
    print("s_blocks _count", sp->s_blocks_count); 
    print("s_r_blocks_count", sp->s_r_blocks_count);
    print("s_free_inodes_count", sp->s_free_inodes_count);
    print("s_free_blocks_count", sp->s_free_blocks_count);
    print("s_first_data_blcok", sp->s_first_data_block); 
    print("s_log_block_s i z e", sp->s_log_block_size);
    print("s_blocks_per_group", sp->s_blocks_per_group); 
    print("s_inodes_per_group", sp-> s_inodes_per_group); 
    print("s_mnt_count", sp->s_mnt_count);
    print("s_max_mnt_count", sp-> s_max_mnt_count);
 
    printf("%-30s = %8x\n", "s_magic", sp->s_magic); 
    
    printf ("s_mtime = %s\n", ctime ((const time_t *)&sp->s_mtime)); 
    printf ("s_wtime = %s", ctime ((const time_t *)&sp->s_wtime)); 
    blksize = 1024 * (1 << sp->s_log_block_size);
    printf("block size = %d\n", blksize);
    printf("inode size = %d\n", sp->s_inode_size);
}

char *device = "vdisk";	// default device name
int main(int argc, char *argv[])
{
    if (argc>1)
        device = argv[1];
    super(device);
}

运行

邮差算法

邮差算法是指将一个二元(多元)应表转换为一个一元的线性表的转换算法

遍历EXT2文件系统书

遍历算法

读取超级块。
检査幻数s_magic ( OxEF53 ),验证它确实是EXT2 FS,

  • 读取块组描述符块(1 + s_first_data_block)
    以访问组0描述符。从块组描述符的bg_inode_table条目中找到索引节点的起始块编号,并将其称为InodesBeginBlock,

  • 读取InodeBeginBlock,获取/的索引节点,即INODE #2。
    将路径名标记为组件字符串
    假设组件数量为n,例如,如果路径名=/a/b/c,则组 件字符串是“a”“b”“c”,其中n = 3。用name[0], namefl],…,name[n-l]来表示组件。

  • 从(3)中的根索引节点开始,在其数据块中搜索name[0]。
    使用索引节点号ino来定位相应的索引节点。
    ino从1开始计数,使用邮差算法计算包含索引节点的磁盘块及其在该块中的偏移量。

问题:ext2头文件的缺失以及下载,按照书上提供方法sudo apt-get install ext2fs-dev无法解决,包不存在,且使用apt-get sudo 之后任然无法解决问题

解决:使用sudo apt-get isntall libext2fs-dev成功解决问题

posted @ 2022-10-03 21:58  20201327刘谨铭  阅读(32)  评论(0编辑  收藏  举报